diff --git a/html/304screen.subx.html b/html/304screen.subx.html index 90335a0d..665f3a91 100644 --- a/html/304screen.subx.html +++ b/html/304screen.subx.html @@ -69,7 +69,7 @@ if ('onhashchange' in window) { 11 (flush Stdout) 12 (flush Stderr) 13 # switch to second screen buffer - 14 (write 1 Esc) + 14 (write 1 Esc) 15 (write 1 "[?1049h") 16 # 17 (clear-real-screen) @@ -84,7 +84,7 @@ if ('onhashchange' in window) { 26 55/push-ebp 27 89/<- %ebp 4/r32/esp 28 # switch to first screen buffer - 29 (write 1 Esc) + 29 (write 1 Esc) 30 (write 1 "[?1049l") 31 $enable-screen-type-mode:end: 32 # . epilogue @@ -102,7 +102,7 @@ if ('onhashchange' in window) { 44 56/push-esi 45 57/push-edi 46 # - 47 (_maybe-open-terminal) + 47 (_maybe-open-terminal) 48 # var window-size-info/esi: (addr winsize) 49 # winsize is a type from the Linux kernel. We don't care how large it is. 50 81 5/subop/subtract %esp 0x40/imm32 @@ -110,7 +110,7 @@ if ('onhashchange' in window) { 52 # ioctl(*Terminal-file-descriptor, TIOCGWINSZ, window-size-info) 53 89/<- %edx 6/r32/esi 54 b9/copy-to-ecx 0x5413/imm32/TIOCGWINSZ - 55 8b/-> *Terminal-file-descriptor 3/r32/ebx + 55 8b/-> *Terminal-file-descriptor 3/r32/ebx 56 e8/call syscall_ioctl/disp32 57 # some bitworking to extract 2 16-bit shorts 58 8b/-> *esi 0/r32/eax @@ -135,9 +135,9 @@ if ('onhashchange' in window) { 77 55/push-ebp 78 89/<- %ebp 4/r32/esp 79 # - 80 (write 1 Esc) + 80 (write 1 Esc) 81 (write 1 "[H") - 82 (write 1 Esc) + 82 (write 1 Esc) 83 (write 1 "[2J") 84 $clear-real-screen:end: 85 # . epilogue @@ -159,7 +159,7 @@ if ('onhashchange' in window) { 101 68/push 0/imm32/write 102 89/<- %ecx 4/r32/esp 103 # construct directive in buf -104 (write %ecx Esc) +104 (write %ecx Esc) 105 (write %ecx "[") 106 (write-int32-decimal %ecx *(ebp+8)) 107 (write %ecx ";") @@ -189,254 +189,267 @@ if ('onhashchange' in window) { 131 5d/pop-to-ebp 132 c3/return 133 -134 # print a grapheme in utf-8 (only up to 4 bytes so far) -135 print-grapheme-to-real-screen: # c: grapheme -136 # . prologue -137 55/push-ebp -138 89/<- %ebp 4/r32/esp -139 # . save registers -140 50/push-eax -141 # var curr/eax: byte = 0 -142 b8/copy-to-eax 0/imm32 -143 # curr = *(ebp+8) -144 8a/byte-> *(ebp+8) 0/r32/al -145 # if (curr == 0) return -146 3d/compare-eax-and 0/imm32 -147 74/jump-if-= $print-grapheme-to-real-screen:end/disp8 -148 # -149 (print-byte-to-real-screen %eax) -150 # curr = *(ebp+9) -151 8a/byte-> *(ebp+9) 0/r32/al -152 # if (curr == 0) return -153 3d/compare-eax-and 0/imm32 -154 74/jump-if-= $print-grapheme-to-real-screen:end/disp8 -155 # -156 (print-byte-to-real-screen %eax) -157 # curr = *(ebp+10) -158 8a/byte-> *(ebp+0xa) 0/r32/al -159 # if (curr == 0) return -160 3d/compare-eax-and 0/imm32 -161 74/jump-if-= $print-grapheme-to-real-screen:end/disp8 -162 # -163 (print-byte-to-real-screen %eax) -164 # curr = *(ebp+11) -165 8a/byte-> *(ebp+0xb) 0/r32/al -166 # if (curr == 0) return -167 3d/compare-eax-and 0/imm32 -168 74/jump-if-= $print-grapheme-to-real-screen:end/disp8 -169 # -170 (print-byte-to-real-screen %eax) -171 $print-grapheme-to-real-screen:end: -172 # . restore registers -173 58/pop-to-eax -174 # . epilogue -175 89/<- %esp 5/r32/ebp -176 5d/pop-to-ebp -177 c3/return -178 -179 print-byte-to-real-screen: # c: byte -180 # . prologue -181 55/push-ebp -182 89/<- %ebp 4/r32/esp -183 # . save registers -184 51/push-ecx -185 # var s/ecx: (addr array byte) -186 ff 6/subop/push *(ebp+8) -187 68/push 1/imm32/size -188 89/<- %ecx 4/r32/esp -189 (write 1 %ecx) -190 $print-byte-to-real-screen:end: -191 # . reclaim locals -192 81 0/subop/add %esp 8/imm32 -193 # . restore registers -194 59/pop-to-ecx -195 # . epilogue -196 89/<- %esp 5/r32/ebp -197 5d/pop-to-ebp -198 c3/return -199 -200 print-int32-hex-to-real-screen: # n: int -201 # . prologue -202 55/push-ebp -203 89/<- %ebp 4/r32/esp -204 # -205 (write-int32-hex-buffered Stdout *(ebp+8)) -206 (flush Stdout) -207 $print-int32-hex-to-real-screen:end: +134 print-stream-to-real-screen: # s: (addr stream byte) +135 # . prologue +136 55/push-ebp +137 89/<- %ebp 4/r32/esp +138 # +139 (write-stream-data Stdout *(ebp+8)) +140 (flush Stdout) +141 $print-stream-to-real-screen:end: +142 # . epilogue +143 89/<- %esp 5/r32/ebp +144 5d/pop-to-ebp +145 c3/return +146 +147 # print a grapheme in utf-8 (only up to 4 bytes so far) +148 print-grapheme-to-real-screen: # c: grapheme +149 # . prologue +150 55/push-ebp +151 89/<- %ebp 4/r32/esp +152 # . save registers +153 50/push-eax +154 # var curr/eax: byte = 0 +155 b8/copy-to-eax 0/imm32 +156 # curr = *(ebp+8) +157 8a/byte-> *(ebp+8) 0/r32/al +158 # if (curr == 0) return +159 3d/compare-eax-and 0/imm32 +160 74/jump-if-= $print-grapheme-to-real-screen:end/disp8 +161 # +162 (print-byte-to-real-screen %eax) +163 # curr = *(ebp+9) +164 8a/byte-> *(ebp+9) 0/r32/al +165 # if (curr == 0) return +166 3d/compare-eax-and 0/imm32 +167 74/jump-if-= $print-grapheme-to-real-screen:end/disp8 +168 # +169 (print-byte-to-real-screen %eax) +170 # curr = *(ebp+10) +171 8a/byte-> *(ebp+0xa) 0/r32/al +172 # if (curr == 0) return +173 3d/compare-eax-and 0/imm32 +174 74/jump-if-= $print-grapheme-to-real-screen:end/disp8 +175 # +176 (print-byte-to-real-screen %eax) +177 # curr = *(ebp+11) +178 8a/byte-> *(ebp+0xb) 0/r32/al +179 # if (curr == 0) return +180 3d/compare-eax-and 0/imm32 +181 74/jump-if-= $print-grapheme-to-real-screen:end/disp8 +182 # +183 (print-byte-to-real-screen %eax) +184 $print-grapheme-to-real-screen:end: +185 # . restore registers +186 58/pop-to-eax +187 # . epilogue +188 89/<- %esp 5/r32/ebp +189 5d/pop-to-ebp +190 c3/return +191 +192 print-byte-to-real-screen: # c: byte +193 # . prologue +194 55/push-ebp +195 89/<- %ebp 4/r32/esp +196 # . save registers +197 51/push-ecx +198 # var s/ecx: (addr array byte) +199 ff 6/subop/push *(ebp+8) +200 68/push 1/imm32/size +201 89/<- %ecx 4/r32/esp +202 (write 1 %ecx) +203 $print-byte-to-real-screen:end: +204 # . reclaim locals +205 81 0/subop/add %esp 8/imm32 +206 # . restore registers +207 59/pop-to-ecx 208 # . epilogue 209 89/<- %esp 5/r32/ebp 210 5d/pop-to-ebp 211 c3/return 212 -213 reset-formatting-on-real-screen: +213 print-int32-hex-to-real-screen: # n: int 214 # . prologue 215 55/push-ebp 216 89/<- %ebp 4/r32/esp 217 # -218 (write 1 Esc) -219 (write 1 "(B") -220 (write 1 Esc) -221 (write 1 "[m") -222 $reset-formatting-on-real-screen:end: -223 # . epilogue -224 89/<- %esp 5/r32/ebp -225 5d/pop-to-ebp -226 c3/return -227 -228 start-color-on-real-screen: # fg: int, bg: int -229 # . prologue -230 55/push-ebp -231 89/<- %ebp 4/r32/esp -232 # . save registers -233 51/push-ecx -234 # var buf/ecx: (stream byte 32) -235 81 5/subop/subtract %esp 0x20/imm32 -236 68/push 0x20/imm32/size -237 68/push 0/imm32/read -238 68/push 0/imm32/write -239 89/<- %ecx 4/r32/esp -240 # construct directive in buf -241 # . set fg -242 (write %ecx Esc) -243 (write %ecx "[38;5;") -244 (write-int32-decimal %ecx *(ebp+8)) -245 (write %ecx "m") -246 # . set bg -247 (write %ecx Esc) -248 (write %ecx "[48;5;") -249 (write-int32-decimal %ecx *(ebp+0xc)) -250 (write %ecx "m") -251 # flush -252 (write-stream 2 %ecx) -253 $start-color-on-real-screen:end: -254 # . reclaim locals -255 81 0/subop/add %esp 0x2c/imm32 -256 # . restore registers -257 59/pop-to-ecx -258 # . epilogue -259 89/<- %esp 5/r32/ebp -260 5d/pop-to-ebp -261 c3/return -262 -263 start-bold-on-real-screen: -264 # . prologue -265 55/push-ebp -266 89/<- %ebp 4/r32/esp -267 # -268 (write 1 Esc) -269 (write 1 "[1m") -270 $start-bold-on-real-screen:end: +218 (write-int32-hex-buffered Stdout *(ebp+8)) +219 (flush Stdout) +220 $print-int32-hex-to-real-screen:end: +221 # . epilogue +222 89/<- %esp 5/r32/ebp +223 5d/pop-to-ebp +224 c3/return +225 +226 reset-formatting-on-real-screen: +227 # . prologue +228 55/push-ebp +229 89/<- %ebp 4/r32/esp +230 # +231 (write 1 Esc) +232 (write 1 "(B") +233 (write 1 Esc) +234 (write 1 "[m") +235 $reset-formatting-on-real-screen:end: +236 # . epilogue +237 89/<- %esp 5/r32/ebp +238 5d/pop-to-ebp +239 c3/return +240 +241 start-color-on-real-screen: # fg: int, bg: int +242 # . prologue +243 55/push-ebp +244 89/<- %ebp 4/r32/esp +245 # . save registers +246 51/push-ecx +247 # var buf/ecx: (stream byte 32) +248 81 5/subop/subtract %esp 0x20/imm32 +249 68/push 0x20/imm32/size +250 68/push 0/imm32/read +251 68/push 0/imm32/write +252 89/<- %ecx 4/r32/esp +253 # construct directive in buf +254 # . set fg +255 (write %ecx Esc) +256 (write %ecx "[38;5;") +257 (write-int32-decimal %ecx *(ebp+8)) +258 (write %ecx "m") +259 # . set bg +260 (write %ecx Esc) +261 (write %ecx "[48;5;") +262 (write-int32-decimal %ecx *(ebp+0xc)) +263 (write %ecx "m") +264 # flush +265 (write-stream 2 %ecx) +266 $start-color-on-real-screen:end: +267 # . reclaim locals +268 81 0/subop/add %esp 0x2c/imm32 +269 # . restore registers +270 59/pop-to-ecx 271 # . epilogue 272 89/<- %esp 5/r32/ebp 273 5d/pop-to-ebp 274 c3/return 275 -276 start-underline-on-real-screen: +276 start-bold-on-real-screen: 277 # . prologue 278 55/push-ebp 279 89/<- %ebp 4/r32/esp 280 # -281 (write 1 Esc) -282 (write 1 "[4m") -283 $start-underline-on-real-screen:end: +281 (write 1 Esc) +282 (write 1 "[1m") +283 $start-bold-on-real-screen:end: 284 # . epilogue 285 89/<- %esp 5/r32/ebp 286 5d/pop-to-ebp 287 c3/return 288 -289 start-reverse-video-on-real-screen: +289 start-underline-on-real-screen: 290 # . prologue 291 55/push-ebp 292 89/<- %ebp 4/r32/esp 293 # -294 (write 1 Esc) -295 (write 1 "[7m") -296 $start-reverse-video-on-real-screen:end: +294 (write 1 Esc) +295 (write 1 "[4m") +296 $start-underline-on-real-screen:end: 297 # . epilogue 298 89/<- %esp 5/r32/ebp 299 5d/pop-to-ebp 300 c3/return 301 -302 # might require enabling blinking in your terminal program -303 start-blinking-on-real-screen: -304 # . prologue -305 55/push-ebp -306 89/<- %ebp 4/r32/esp -307 # -308 (write 1 Esc) -309 (write 1 "[5m") -310 $start-blinking-on-real-screen:end: -311 # . epilogue -312 89/<- %esp 5/r32/ebp -313 5d/pop-to-ebp -314 c3/return -315 -316 hide-cursor-on-real-screen: +302 start-reverse-video-on-real-screen: +303 # . prologue +304 55/push-ebp +305 89/<- %ebp 4/r32/esp +306 # +307 (write 1 Esc) +308 (write 1 "[7m") +309 $start-reverse-video-on-real-screen:end: +310 # . epilogue +311 89/<- %esp 5/r32/ebp +312 5d/pop-to-ebp +313 c3/return +314 +315 # might require enabling blinking in your terminal program +316 start-blinking-on-real-screen: 317 # . prologue 318 55/push-ebp 319 89/<- %ebp 4/r32/esp 320 # -321 (write 1 Esc) -322 (write 1 "[?25l") -323 $hide-cursor-on-real-screen:end: +321 (write 1 Esc) +322 (write 1 "[5m") +323 $start-blinking-on-real-screen:end: 324 # . epilogue 325 89/<- %esp 5/r32/ebp 326 5d/pop-to-ebp 327 c3/return 328 -329 show-cursor-on-real-screen: +329 hide-cursor-on-real-screen: 330 # . prologue 331 55/push-ebp 332 89/<- %ebp 4/r32/esp 333 # -334 (write 1 Esc) -335 (write 1 "[?12l") -336 (write 1 Esc) -337 (write 1 "[?25h") -338 $show-cursor-on-real-screen:end: -339 # . epilogue -340 89/<- %esp 5/r32/ebp -341 5d/pop-to-ebp -342 c3/return -343 -344 # This is a low-level detail; I don't think everything should be a file. -345 # -346 # Open "/dev/tty" if necessary and cache its file descriptor in Terminal-file-descriptor -347 # where later primitives can use it. -348 _maybe-open-terminal: -349 81 7/subop/compare *Terminal-file-descriptor -1/imm32 -350 75/jump-if-!= $_maybe-open-terminal:epilogue/disp8 -351 # . save registers -352 50/push-eax -353 51/push-ecx -354 53/push-ebx -355 # open("/dev/tty", O_RDWR) -356 bb/copy-to-ebx Terminal-filename/imm32 -357 b9/copy-to-ecx 2/imm32/O_RDWR -358 e8/call syscall_open/disp32 -359 89/<- *Terminal-file-descriptor 0/r32/eax -360 $_maybe-open-terminal:end: -361 # . restore registers -362 5b/pop-to-ebx -363 59/pop-to-ecx -364 58/pop-to-eax -365 $_maybe-open-terminal:epilogue: -366 c3/return -367 -368 == data -369 -370 Terminal-file-descriptor: # (addr int) -371 -1/imm32 -372 -373 Esc: # (addr array byte) -374 # size -375 1/imm32 -376 # data -377 0x1b -378 -379 Terminal-filename: # (addr kernel-string) -380 # "/dev/null" -381 2f/slash 64/d 65/e 76/v 2f/slash 74/t 74/t 79/y 0/nul +334 (write 1 Esc) +335 (write 1 "[?25l") +336 $hide-cursor-on-real-screen:end: +337 # . epilogue +338 89/<- %esp 5/r32/ebp +339 5d/pop-to-ebp +340 c3/return +341 +342 show-cursor-on-real-screen: +343 # . prologue +344 55/push-ebp +345 89/<- %ebp 4/r32/esp +346 # +347 (write 1 Esc) +348 (write 1 "[?12l") +349 (write 1 Esc) +350 (write 1 "[?25h") +351 $show-cursor-on-real-screen:end: +352 # . epilogue +353 89/<- %esp 5/r32/ebp +354 5d/pop-to-ebp +355 c3/return +356 +357 # This is a low-level detail; I don't think everything should be a file. +358 # +359 # Open "/dev/tty" if necessary and cache its file descriptor in Terminal-file-descriptor +360 # where later primitives can use it. +361 _maybe-open-terminal: +362 81 7/subop/compare *Terminal-file-descriptor -1/imm32 +363 75/jump-if-!= $_maybe-open-terminal:epilogue/disp8 +364 # . save registers +365 50/push-eax +366 51/push-ecx +367 53/push-ebx +368 # open("/dev/tty", O_RDWR) +369 bb/copy-to-ebx Terminal-filename/imm32 +370 b9/copy-to-ecx 2/imm32/O_RDWR +371 e8/call syscall_open/disp32 +372 89/<- *Terminal-file-descriptor 0/r32/eax +373 $_maybe-open-terminal:end: +374 # . restore registers +375 5b/pop-to-ebx +376 59/pop-to-ecx +377 58/pop-to-eax +378 $_maybe-open-terminal:epilogue: +379 c3/return +380 +381 == data +382 +383 Terminal-file-descriptor: # (addr int) +384 -1/imm32 +385 +386 Esc: # (addr array byte) +387 # size +388 1/imm32 +389 # data +390 0x1b +391 +392 Terminal-filename: # (addr kernel-string) +393 # "/dev/null" +394 2f/slash 64/d 65/e 76/v 2f/slash 74/t 74/t 79/y 0/nul diff --git a/html/305keyboard.subx.html b/html/305keyboard.subx.html index ee4e48a7..007ff14e 100644 --- a/html/305keyboard.subx.html +++ b/html/305keyboard.subx.html @@ -73,7 +73,7 @@ if ('onhashchange' in window) { 15 56/push-esi 16 57/push-edi 17 # - 18 (_maybe-open-terminal) + 18 (_maybe-open-terminal) 19 # var terminal-info/esi: (addr termios) 20 # termios is a type from the Linux kernel. We don't care how large it is. 21 81 5/subop/subtract %esp 0x100/imm32 @@ -81,7 +81,7 @@ if ('onhashchange' in window) { 23 # ioctl(*Terminal-file-descriptor, TCGETS, terminal-info) 24 89/<- %edx 6/r32/esi 25 b9/copy-to-ecx 0x5401/imm32/TCGETS - 26 8b/-> *Terminal-file-descriptor 3/r32/ebx + 26 8b/-> *Terminal-file-descriptor 3/r32/ebx 27 e8/call syscall_ioctl/disp32 28 # terminal-info->c_iflags &= Keyboard-immediate-mode-iflags 29 #? (write-buffered Stderr "iflags before: ") @@ -110,7 +110,7 @@ if ('onhashchange' in window) { 52 # ioctl(*Terminal-file-descriptor, TCSETS, terminal-info) 53 89/<- %edx 6/r32/esi 54 b9/copy-to-ecx 0x5402/imm32/TCSETS - 55 8b/-> *Terminal-file-descriptor 3/r32/ebx + 55 8b/-> *Terminal-file-descriptor 3/r32/ebx 56 e8/call syscall_ioctl/disp32 57 $enable-keyboard-immediate-mode:end: 58 # . reclaim locals @@ -139,7 +139,7 @@ if ('onhashchange' in window) { 81 56/push-esi 82 57/push-edi 83 # - 84 (_maybe-open-terminal) + 84 (_maybe-open-terminal) 85 # var terminal-info/esi: (addr termios) 86 # termios is a type from the Linux kernel. We don't care how large it is. 87 81 5/subop/subtract %esp 0x100/imm32 @@ -147,7 +147,7 @@ if ('onhashchange' in window) { 89 # ioctl(*Terminal-file-descriptor, TCGETS, terminal-info) 90 89/<- %edx 6/r32/esi 91 b9/copy-to-ecx 0x5401/imm32/TCGETS - 92 8b/-> *Terminal-file-descriptor 3/r32/ebx + 92 8b/-> *Terminal-file-descriptor 3/r32/ebx 93 e8/call syscall_ioctl/disp32 94 # terminal-info->c_iflags |= Keyboard-type-mode-iflags 95 8b/-> *esi 0/r32/eax # Termios-c_iflag @@ -160,7 +160,7 @@ if ('onhashchange' in window) { 102 # ioctl(*Terminal-file-descriptor, TCSETS, terminal-info) 103 89/<- %edx 6/r32/esi 104 b9/copy-to-ecx 0x5402/imm32/TCSETS -105 8b/-> *Terminal-file-descriptor 3/r32/ebx +105 8b/-> *Terminal-file-descriptor 3/r32/ebx 106 e8/call syscall_ioctl/disp32 107 $enable-keyboard-type-mode:end: 108 # . reclaim locals diff --git a/html/400.mu.html b/html/400.mu.html index 702c2817..5464f1e1 100644 --- a/html/400.mu.html +++ b/html/400.mu.html @@ -197,24 +197,25 @@ if ('onhashchange' in window) { 142 sig clear-real-screen 143 sig move-cursor-on-real-screen row: int, column: int 144 sig print-string-to-real-screen s: (addr array byte) -145 sig print-grapheme-to-real-screen c: grapheme -146 sig print-int32-hex-to-real-screen n: int -147 sig reset-formatting-on-real-screen -148 sig start-color-on-real-screen fg: int, bg: int -149 sig start-bold-on-real-screen -150 sig start-underline-on-real-screen -151 sig start-reverse-video-on-real-screen -152 sig start-blinking-on-real-screen -153 sig hide-cursor-on-real-screen -154 sig show-cursor-on-real-screen -155 sig enable-keyboard-immediate-mode -156 sig enable-keyboard-type-mode -157 sig read-key -> result/eax: byte -158 sig open filename: (addr array byte), write?: boolean, out: (addr handle buffered-file) -159 #sig size in: (addr array _) -> result/eax: int -160 -161 sig stream-empty? s: (addr stream _) -> result/eax: boolean -162 sig stream-full? s: (addr stream _) -> result/eax: boolean +145 sig print-stream-to-real-screen s: (addr stream byte) +146 sig print-grapheme-to-real-screen c: grapheme +147 sig print-int32-hex-to-real-screen n: int +148 sig reset-formatting-on-real-screen +149 sig start-color-on-real-screen fg: int, bg: int +150 sig start-bold-on-real-screen +151 sig start-underline-on-real-screen +152 sig start-reverse-video-on-real-screen +153 sig start-blinking-on-real-screen +154 sig hide-cursor-on-real-screen +155 sig show-cursor-on-real-screen +156 sig enable-keyboard-immediate-mode +157 sig enable-keyboard-type-mode +158 sig read-key -> result/eax: byte +159 sig open filename: (addr array byte), write?: boolean, out: (addr handle buffered-file) +160 #sig size in: (addr array _) -> result/eax: int +161 +162 sig stream-empty? s: (addr stream _) -> result/eax: boolean +163 sig stream-full? s: (addr stream _) -> result/eax: boolean diff --git a/html/403code-point.mu.html b/html/403code-point.mu.html index 88f29561..6543e41e 100644 --- a/html/403code-point.mu.html +++ b/html/403code-point.mu.html @@ -119,7 +119,7 @@ if ('onhashchange' in window) { 59 { 60 break-if-> 61 print-string-to-real-screen "unsupported code point " - 62 print-int32-hex-to-real-screen c + 62 print-int32-hex-to-real-screen c 63 print-string-to-real-screen "\n" 64 var exit-status/ebx: int <- copy 1 65 syscall_exit diff --git a/html/405screen.mu.html b/html/405screen.mu.html index dc658b1b..8bea2ff4 100644 --- a/html/405screen.mu.html +++ b/html/405screen.mu.html @@ -209,7 +209,7 @@ if ('onhashchange' in window) { 151 compare screen, 0 152 { 153 break-if-!= -154 print-grapheme-to-real-screen c +154 print-grapheme-to-real-screen c 155 break $print-grapheme:body 156 } 157 { @@ -229,7 +229,7 @@ if ('onhashchange' in window) { 171 compare screen, 0 172 { 173 break-if-!= -174 print-int32-hex-to-real-screen n +174 print-int32-hex-to-real-screen n 175 break $print-int32-hex:body 176 } 177 { @@ -244,7 +244,7 @@ if ('onhashchange' in window) { 186 compare screen, 0 187 { 188 break-if-!= -189 reset-formatting-on-real-screen +189 reset-formatting-on-real-screen 190 break $reset-formatting:body 191 } 192 { @@ -259,7 +259,7 @@ if ('onhashchange' in window) { 201 compare screen, 0 202 { 203 break-if-!= -204 start-color-on-real-screen fg, bg +204 start-color-on-real-screen fg, bg 205 break $start-color:body 206 } 207 { @@ -274,7 +274,7 @@ if ('onhashchange' in window) { 216 compare screen, 0 217 { 218 break-if-!= -219 start-bold-on-real-screen +219 start-bold-on-real-screen 220 break $start-bold:body 221 } 222 { @@ -289,7 +289,7 @@ if ('onhashchange' in window) { 231 compare screen, 0 232 { 233 break-if-!= -234 start-underline-on-real-screen +234 start-underline-on-real-screen 235 break $start-underline:body 236 } 237 { @@ -304,7 +304,7 @@ if ('onhashchange' in window) { 246 compare screen, 0 247 { 248 break-if-!= -249 start-reverse-video-on-real-screen +249 start-reverse-video-on-real-screen 250 break $start-reverse-video:body 251 } 252 { @@ -319,7 +319,7 @@ if ('onhashchange' in window) { 261 compare screen, 0 262 { 263 break-if-!= -264 start-blinking-on-real-screen +264 start-blinking-on-real-screen 265 break $start-blinking:body 266 } 267 { @@ -334,7 +334,7 @@ if ('onhashchange' in window) { 276 compare screen, 0 277 { 278 break-if-!= -279 hide-cursor-on-real-screen +279 hide-cursor-on-real-screen 280 break $hide-cursor:body 281 } 282 { @@ -349,7 +349,7 @@ if ('onhashchange' in window) { 291 compare screen, 0 292 { 293 break-if-!= -294 show-cursor-on-real-screen +294 show-cursor-on-real-screen 295 break $show-cursor:body 296 } 297 { diff --git a/html/apps/browse.mu.html b/html/apps/browse.mu.html index 81b3c3ab..eebd104a 100644 --- a/html/apps/browse.mu.html +++ b/html/apps/browse.mu.html @@ -65,7 +65,7 @@ if ('onhashchange' in window) { 6 # 7 # Press 'q' to quit. All other keys scroll down. 8 - 9 fn main args-on-stack: (addr array (addr array byte)) -> exit-status/ebx: int { + 9 fn main args-on-stack: (addr array addr array byte) -> exit-status/ebx: int { 10 +-- 20 lines: # var file/esi: (addr buffered-file) = open args-on-stack[1] for reading -------------------------------------------------------------------------------------------------- 30 enable-screen-grid-mode 31 var nrows/eax: int <- copy 0 diff --git a/html/apps/factorial.mu.html b/html/apps/factorial.mu.html index bce88f11..4880270d 100644 --- a/html/apps/factorial.mu.html +++ b/html/apps/factorial.mu.html @@ -90,8 +90,8 @@ if ('onhashchange' in window) { 31 check-ints-equal result 0x78 "F - test-factorial" 32 } 33 -34 fn main args-on-stack: (addr array (addr array byte)) -> exit-status/ebx: int { -35 var args/eax: (addr array (addr array byte)) <- copy args-on-stack +34 fn main args-on-stack: (addr array addr array byte) -> exit-status/ebx: int { +35 var args/eax: (addr array addr array byte) <- copy args-on-stack 36 var tmp/ecx: int <- length args 37 $main-body: { 38 # if (len(args) <= 1) factorial(5) diff --git a/html/apps/mu.subx.html b/html/apps/mu.subx.html index 9ed160bf..47819a6c 100644 --- a/html/apps/mu.subx.html +++ b/html/apps/mu.subx.html @@ -566,7 +566,7 @@ if ('onhashchange' in window) { 504 # . save registers 505 50/push-eax 506 # initialize global data structures - 507 c7 0/subop/copy *Next-block-index 1/imm32 + 507 c7 0/subop/copy *Next-block-index 1/imm32 508 8b/-> *Primitive-type-ids 0/r32/eax 509 89/<- *Type-id 0/r32/eax # stream-write 510 c7 0/subop/copy *_Program-functions 0/imm32 @@ -576,11 +576,11 @@ if ('onhashchange' in window) { 514 c7 0/subop/copy *_Program-signatures 0/imm32 515 c7 0/subop/copy *_Program-signatures->payload 0/imm32 516 # - 517 (parse-mu *(ebp+8) *(ebp+0x10) *(ebp+0x14)) - 518 (populate-mu-type-sizes *(ebp+0x10) *(ebp+0x14)) + 517 (parse-mu *(ebp+8) *(ebp+0x10) *(ebp+0x14)) + 518 (populate-mu-type-sizes *(ebp+0x10) *(ebp+0x14)) 519 #? (dump-typeinfos "=== typeinfos\n") - 520 (check-mu-types *(ebp+0x10) *(ebp+0x14)) - 521 (emit-subx *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) + 520 (check-mu-types *(ebp+0x10) *(ebp+0x14)) + 521 (emit-subx *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) 522 $convert-mu:end: 523 # . restore registers 524 58/pop-to-eax @@ -3988,17881 +3988,19094 @@ if ('onhashchange' in window) { 4306 (flush _test-output-buffered-file) 4307 (flush _test-error-buffered-file) 4308 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 4314 (check-stream-equal _test-error-stream "" "F - test-reg-var-def-with-read-of-same-register: error stream should be empty") - 4315 # check output - 4316 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-reg-var-def-with-read-of-same-register/0") - 4317 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-reg-var-def-with-read-of-same-register/1") - 4318 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-reg-var-def-with-read-of-same-register/2") - 4319 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-reg-var-def-with-read-of-same-register/3") - 4320 (check-next-stream-line-equal _test-output-stream " {" "F - test-reg-var-def-with-read-of-same-register/4") - 4321 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-reg-var-def-with-read-of-same-register/5") - 4322 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-reg-var-def-with-read-of-same-register/6") - 4323 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-reg-var-def-with-read-of-same-register/7") - 4324 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-reg-var-def-with-read-of-same-register/8") - 4325 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-reg-var-def-with-read-of-same-register/9") - 4326 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + ecx<<0x00000002 + 4) 0x00000000/r32" "F - test-reg-var-def-with-read-of-same-register/11") - 4327 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-reg-var-def-with-read-of-same-register/13") - 4328 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-reg-var-def-with-read-of-same-register/14") - 4329 (check-next-stream-line-equal _test-output-stream " }" "F - test-reg-var-def-with-read-of-same-register/15") - 4330 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-reg-var-def-with-read-of-same-register/16") - 4331 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-reg-var-def-with-read-of-same-register/17") - 4332 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-reg-var-def-with-read-of-same-register/18") - 4333 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-reg-var-def-with-read-of-same-register/19") - 4334 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-reg-var-def-with-read-of-same-register/20") - 4335 # don't restore from ebp - 4336 81 0/subop/add %esp 8/imm32 - 4337 # . epilogue - 4338 5d/pop-to-ebp - 4339 c3/return - 4340 - 4341 test-convert-index-into-array: - 4342 # . prologue - 4343 55/push-ebp - 4344 89/<- %ebp 4/r32/esp - 4345 # setup - 4346 (clear-stream _test-input-stream) - 4347 (clear-stream $_test-input-buffered-file->buffer) - 4348 (clear-stream _test-output-stream) - 4349 (clear-stream $_test-output-buffered-file->buffer) - 4350 # - 4351 (write _test-input-stream "fn foo {\n") - 4352 (write _test-input-stream " var arr/eax: (addr array int) <- copy 0\n") - 4353 (write _test-input-stream " var idx/ecx: int <- copy 3\n") - 4354 (write _test-input-stream " var x/eax: (addr int) <- index arr, idx\n") - 4355 (write _test-input-stream "}\n") - 4356 # convert - 4357 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 4358 (flush _test-output-buffered-file) - 4359 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 4365 # check output - 4366 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array/0") - 4367 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array/1") - 4368 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array/2") - 4369 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array/3") - 4370 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array/4") - 4371 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array/5") - 4372 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array/6") - 4373 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-index-into-array/7") - 4374 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-index-into-array/8") - 4375 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-convert-index-into-array/9") - 4376 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + ecx<<0x00000002 + 4) 0x00000000/r32" "F - test-convert-index-into-array/10") - 4377 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-index-into-array/11") - 4378 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array/12") - 4379 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array/13") - 4380 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array/14") - 4381 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array/15") - 4382 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array/16") - 4383 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array/17") - 4384 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array/18") - 4385 # . epilogue - 4386 89/<- %esp 5/r32/ebp - 4387 5d/pop-to-ebp - 4388 c3/return - 4389 - 4390 test-convert-index-into-array-of-bytes: - 4391 # . prologue - 4392 55/push-ebp - 4393 89/<- %ebp 4/r32/esp - 4394 # setup - 4395 (clear-stream _test-input-stream) - 4396 (clear-stream $_test-input-buffered-file->buffer) - 4397 (clear-stream _test-output-stream) - 4398 (clear-stream $_test-output-buffered-file->buffer) - 4399 # - 4400 (write _test-input-stream "fn foo {\n") - 4401 (write _test-input-stream " var arr/eax: (addr array byte) <- copy 0\n") - 4402 (write _test-input-stream " var idx/ecx: int <- copy 3\n") - 4403 (write _test-input-stream " var x/eax: (addr byte) <- index arr, idx\n") - 4404 (write _test-input-stream "}\n") - 4405 # convert - 4406 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 4407 (flush _test-output-buffered-file) - 4408 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 4414 # check output - 4415 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-of-bytes/0") - 4416 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-of-bytes/1") - 4417 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-of-bytes/2") - 4418 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-of-bytes/3") - 4419 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-of-bytes/4") - 4420 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-of-bytes/5") - 4421 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-of-bytes/6") - 4422 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-index-into-array-of-bytes/7") - 4423 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-index-into-array-of-bytes/8") - 4424 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-convert-index-into-array-of-bytes/9") - 4425 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + ecx<<0x00000000 + 4) 0x00000000/r32" "F - test-convert-index-into-array-of-bytes/11") - 4426 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-index-into-array-of-bytes/13") - 4427 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-of-bytes/14") - 4428 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-of-bytes/15") - 4429 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-of-bytes/16") - 4430 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-of-bytes/17") - 4431 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-of-bytes/18") - 4432 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-of-bytes/19") - 4433 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-of-bytes/20") - 4434 # . epilogue - 4435 89/<- %esp 5/r32/ebp - 4436 5d/pop-to-ebp - 4437 c3/return - 4438 - 4439 test-convert-index-into-array-with-literal: - 4440 # . prologue - 4441 55/push-ebp - 4442 89/<- %ebp 4/r32/esp - 4443 # setup - 4444 (clear-stream _test-input-stream) - 4445 (clear-stream $_test-input-buffered-file->buffer) - 4446 (clear-stream _test-output-stream) - 4447 (clear-stream $_test-output-buffered-file->buffer) - 4448 # - 4449 (write _test-input-stream "fn foo {\n") - 4450 (write _test-input-stream " var arr/eax: (addr array int) <- copy 0\n") - 4451 (write _test-input-stream " var x/eax: (addr int) <- index arr, 2\n") - 4452 (write _test-input-stream "}\n") - 4453 # convert - 4454 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 4455 (flush _test-output-buffered-file) - 4456 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 4462 # check output - 4463 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-with-literal/0") - 4464 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-with-literal/1") - 4465 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-with-literal/2") - 4466 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-with-literal/3") - 4467 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-with-literal/4") - 4468 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-with-literal/5") - 4469 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-with-literal/6") - 4470 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-index-into-array-with-literal/7") - 4471 # 2 * 4 bytes/elem + 4 bytes for size = offset 12 - 4472 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + 0x0000000c) 0x00000000/r32" "F - test-convert-index-into-array-with-literal/8") - 4473 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-with-literal/9") - 4474 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-with-literal/10") - 4475 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-with-literal/11") - 4476 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-with-literal/12") - 4477 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-with-literal/13") - 4478 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-with-literal/14") - 4479 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-with-literal/15") - 4480 # . epilogue - 4481 89/<- %esp 5/r32/ebp - 4482 5d/pop-to-ebp - 4483 c3/return - 4484 - 4485 test-convert-index-into-array-of-bytes-with-literal: - 4486 # . prologue - 4487 55/push-ebp - 4488 89/<- %ebp 4/r32/esp - 4489 # setup - 4490 (clear-stream _test-input-stream) - 4491 (clear-stream $_test-input-buffered-file->buffer) - 4492 (clear-stream _test-output-stream) - 4493 (clear-stream $_test-output-buffered-file->buffer) - 4494 # - 4495 (write _test-input-stream "fn foo {\n") - 4496 (write _test-input-stream " var arr/eax: (addr array byte) <- copy 0\n") - 4497 (write _test-input-stream " var x/eax: (addr byte) <- index arr, 2\n") - 4498 (write _test-input-stream "}\n") - 4499 # convert - 4500 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 4501 (flush _test-output-buffered-file) - 4502 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 4508 # check output - 4509 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-of-bytes-with-literal/0") - 4510 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-of-bytes-with-literal/1") - 4511 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-of-bytes-with-literal/2") - 4512 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-of-bytes-with-literal/3") - 4513 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-of-bytes-with-literal/4") - 4514 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-of-bytes-with-literal/5") - 4515 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-of-bytes-with-literal/6") - 4516 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-index-into-array-of-bytes-with-literal/7") - 4517 # 2 * 1 byte/elem + 4 bytes for size = offset 6 - 4518 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + 0x00000006) 0x00000000/r32" "F - test-convert-index-into-array-of-bytes-with-literal/8") - 4519 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-of-bytes-with-literal/9") - 4520 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-of-bytes-with-literal/10") - 4521 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-of-bytes-with-literal/11") - 4522 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-of-bytes-with-literal/12") - 4523 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-of-bytes-with-literal/13") - 4524 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-of-bytes-with-literal/14") - 4525 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-of-bytes-with-literal/15") - 4526 # . epilogue - 4527 89/<- %esp 5/r32/ebp - 4528 5d/pop-to-ebp - 4529 c3/return - 4530 - 4531 test-convert-index-into-array-on-stack: - 4532 # . prologue - 4533 55/push-ebp - 4534 89/<- %ebp 4/r32/esp - 4535 # setup - 4536 (clear-stream _test-input-stream) - 4537 (clear-stream $_test-input-buffered-file->buffer) - 4538 (clear-stream _test-output-stream) - 4539 (clear-stream $_test-output-buffered-file->buffer) - 4540 # - 4541 (write _test-input-stream "fn foo {\n") - 4542 (write _test-input-stream " var arr: (array int 3)\n") - 4543 (write _test-input-stream " var idx/eax: int <- copy 2\n") - 4544 (write _test-input-stream " var x/eax: (addr int) <- index arr, idx\n") - 4545 (write _test-input-stream "}\n") - 4546 # convert - 4547 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 4548 (flush _test-output-buffered-file) - 4549 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 4555 # check output - 4556 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-on-stack/0") - 4557 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-on-stack/1") - 4558 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-on-stack/2") - 4559 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-on-stack/3") - 4560 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-on-stack/4") - 4561 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-on-stack/5") - 4562 # var arr - 4563 (check-next-stream-line-equal _test-output-stream " (push-n-zero-bytes 0x0000000c)" "F - test-convert-index-into-array-on-stack/6") - 4564 (check-next-stream-line-equal _test-output-stream " 68/push 0x0000000c/imm32" "F - test-convert-index-into-array-on-stack/7") - 4565 # var idx - 4566 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-on-stack/8") - 4567 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 2/imm32" "F - test-convert-index-into-array-on-stack/9") - 4568 # var x is at (ebp-0x10) + idx<<2 + 4 = ebp + idx<<2 - 0xc - 4569 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(ebp + eax<<0x00000002 + 0xfffffff4) 0x00000000/r32" "F - test-convert-index-into-array-on-stack/10") - 4570 # reclaim idx - 4571 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-on-stack/11") - 4572 # reclaim arr - 4573 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000010/imm32" "F - test-convert-index-into-array-on-stack/12") - 4574 # - 4575 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-on-stack/13") - 4576 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-on-stack/14") - 4577 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-on-stack/15") - 4578 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-on-stack/16") - 4579 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-on-stack/17") - 4580 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-on-stack/18") - 4581 # . epilogue - 4582 89/<- %esp 5/r32/ebp - 4583 5d/pop-to-ebp - 4584 c3/return - 4585 - 4586 test-convert-index-into-array-on-stack-with-literal: - 4587 # . prologue - 4588 55/push-ebp - 4589 89/<- %ebp 4/r32/esp - 4590 # setup - 4591 (clear-stream _test-input-stream) - 4592 (clear-stream $_test-input-buffered-file->buffer) - 4593 (clear-stream _test-output-stream) - 4594 (clear-stream $_test-output-buffered-file->buffer) - 4595 # - 4596 (write _test-input-stream "fn foo {\n") - 4597 (write _test-input-stream " var arr: (array int 3)\n") - 4598 (write _test-input-stream " var x/eax: (addr int) <- index arr, 2\n") - 4599 (write _test-input-stream "}\n") - 4600 # convert - 4601 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 4602 (flush _test-output-buffered-file) - 4603 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 4609 # check output - 4610 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-on-stack-with-literal/0") - 4611 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-on-stack-with-literal/1") - 4612 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-on-stack-with-literal/2") - 4613 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-on-stack-with-literal/3") - 4614 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-on-stack-with-literal/4") - 4615 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-on-stack-with-literal/5") - 4616 # var arr - 4617 (check-next-stream-line-equal _test-output-stream " (push-n-zero-bytes 0x0000000c)" "F - test-convert-index-into-array-on-stack-with-literal/6") - 4618 (check-next-stream-line-equal _test-output-stream " 68/push 0x0000000c/imm32" "F - test-convert-index-into-array-on-stack-with-literal/7") - 4619 # var x - 4620 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-on-stack-with-literal/8") - 4621 # x is at (ebp-0x10) + 4 + 2*4 = ebp-4 - 4622 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(ebp + 0xfffffffc) 0x00000000/r32" "F - test-convert-index-into-array-on-stack-with-literal/9") - 4623 # reclaim x - 4624 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-on-stack-with-literal/10") - 4625 # reclaim arr - 4626 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000010/imm32" "F - test-convert-index-into-array-on-stack-with-literal/11") - 4627 # - 4628 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-on-stack-with-literal/12") - 4629 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-on-stack-with-literal/13") - 4630 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-on-stack-with-literal/14") - 4631 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-on-stack-with-literal/15") - 4632 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-on-stack-with-literal/16") - 4633 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-on-stack-with-literal/17") - 4634 # . epilogue - 4635 89/<- %esp 5/r32/ebp - 4636 5d/pop-to-ebp - 4637 c3/return - 4638 - 4639 test-convert-index-into-array-of-bytes-on-stack-with-literal: - 4640 # . prologue - 4641 55/push-ebp - 4642 89/<- %ebp 4/r32/esp - 4643 # setup - 4644 (clear-stream _test-input-stream) - 4645 (clear-stream $_test-input-buffered-file->buffer) - 4646 (clear-stream _test-output-stream) - 4647 (clear-stream $_test-output-buffered-file->buffer) - 4648 # - 4649 (write _test-input-stream "fn foo {\n") - 4650 (write _test-input-stream " var arr: (array byte 3)\n") - 4651 (write _test-input-stream " var x/eax: (addr byte) <- index arr, 2\n") - 4652 (write _test-input-stream "}\n") - 4653 # convert - 4654 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 4655 (flush _test-output-buffered-file) - 4656 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 4662 # check output - 4663 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/0") - 4664 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/1") - 4665 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/2") - 4666 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/3") - 4667 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/4") - 4668 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/5") - 4669 # var arr - 4670 (check-next-stream-line-equal _test-output-stream " (push-n-zero-bytes 0x00000003)" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/6") - 4671 (check-next-stream-line-equal _test-output-stream " 68/push 0x00000003/imm32" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/7") - 4672 # var x - 4673 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/8") - 4674 # x is at (ebp-7) + 4 + 2 = ebp-1 - 4675 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(ebp + 0xffffffff) 0x00000000/r32" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/9") - 4676 # reclaim x - 4677 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/10") - 4678 # reclaim arr - 4679 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000007/imm32" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/11") - 4680 # - 4681 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/12") - 4682 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/13") - 4683 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/14") - 4684 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/15") - 4685 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/16") - 4686 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/17") - 4687 # . epilogue - 4688 89/<- %esp 5/r32/ebp - 4689 5d/pop-to-ebp - 4690 c3/return - 4691 - 4692 test-convert-index-into-array-using-offset: - 4693 # . prologue - 4694 55/push-ebp - 4695 89/<- %ebp 4/r32/esp - 4696 # setup - 4697 (clear-stream _test-input-stream) - 4698 (clear-stream $_test-input-buffered-file->buffer) - 4699 (clear-stream _test-output-stream) - 4700 (clear-stream $_test-output-buffered-file->buffer) - 4701 # - 4702 (write _test-input-stream "fn foo {\n") - 4703 (write _test-input-stream " var arr/eax: (addr array int) <- copy 0\n") - 4704 (write _test-input-stream " var idx/ecx: int <- copy 3\n") - 4705 (write _test-input-stream " var off/ecx: (offset int) <- compute-offset arr, idx\n") - 4706 (write _test-input-stream " var x/eax: (addr int) <- index arr, off\n") - 4707 (write _test-input-stream "}\n") - 4708 # convert - 4709 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 4710 (flush _test-output-buffered-file) - 4711 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 4717 # check output - 4718 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-using-offset/0") - 4719 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-using-offset/1") - 4720 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-using-offset/2") - 4721 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-using-offset/3") - 4722 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-using-offset/4") - 4723 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-using-offset/5") - 4724 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-using-offset/6") - 4725 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-index-into-array-using-offset/7") - 4726 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-index-into-array-using-offset/8") - 4727 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-convert-index-into-array-using-offset/9") - 4728 (check-next-stream-line-equal _test-output-stream " 69/multiply %ecx 0x00000004/imm32 0x00000001/r32" "F - test-convert-index-into-array-using-offset/10") - 4729 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + ecx + 4) 0x00000000/r32" "F - test-convert-index-into-array-using-offset/11") - 4730 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-index-into-array-using-offset/12") - 4731 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-using-offset/13") - 4732 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-using-offset/14") - 4733 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-using-offset/15") - 4734 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-using-offset/16") - 4735 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-using-offset/17") - 4736 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-using-offset/18") - 4737 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-using-offset/19") - 4738 # . epilogue - 4739 89/<- %esp 5/r32/ebp - 4740 5d/pop-to-ebp - 4741 c3/return - 4742 - 4743 test-convert-index-into-array-of-bytes-using-offset: - 4744 # . prologue - 4745 55/push-ebp - 4746 89/<- %ebp 4/r32/esp - 4747 # setup - 4748 (clear-stream _test-input-stream) - 4749 (clear-stream $_test-input-buffered-file->buffer) - 4750 (clear-stream _test-output-stream) - 4751 (clear-stream $_test-output-buffered-file->buffer) - 4752 # - 4753 (write _test-input-stream "fn foo {\n") - 4754 (write _test-input-stream " var arr/eax: (addr array byte) <- copy 0\n") - 4755 (write _test-input-stream " var idx/ecx: int <- copy 3\n") - 4756 (write _test-input-stream " var off/ecx: (offset byte) <- compute-offset arr, idx\n") - 4757 (write _test-input-stream " var x/eax: (addr byte) <- index arr, off\n") - 4758 (write _test-input-stream "}\n") - 4759 # convert - 4760 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 4761 (flush _test-output-buffered-file) - 4762 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 4768 # check output - 4769 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-of-bytes-using-offset/0") - 4770 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-of-bytes-using-offset/1") - 4771 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-of-bytes-using-offset/2") - 4772 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-of-bytes-using-offset/3") - 4773 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-of-bytes-using-offset/4") - 4774 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-of-bytes-using-offset/5") - 4775 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-of-bytes-using-offset/6") - 4776 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-index-into-array-of-bytes-using-offset/7") - 4777 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-index-into-array-of-bytes-using-offset/8") - 4778 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-convert-index-into-array-of-bytes-using-offset/9") - 4779 (check-next-stream-line-equal _test-output-stream " 69/multiply %ecx 0x00000001/imm32 0x00000001/r32" "F - test-convert-index-into-array-of-bytes-using-offset/10") - 4780 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + ecx + 4) 0x00000000/r32" "F - test-convert-index-into-array-of-bytes-using-offset/11") - 4781 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-index-into-array-of-bytes-using-offset/12") - 4782 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-of-bytes-using-offset/13") - 4783 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-of-bytes-using-offset/14") - 4784 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-of-bytes-using-offset/15") - 4785 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-of-bytes-using-offset/16") - 4786 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-of-bytes-using-offset/17") - 4787 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-of-bytes-using-offset/18") - 4788 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-of-bytes-using-offset/19") - 4789 # . epilogue - 4790 89/<- %esp 5/r32/ebp - 4791 5d/pop-to-ebp - 4792 c3/return - 4793 - 4794 test-convert-index-into-array-using-offset-on-stack: - 4795 # . prologue - 4796 55/push-ebp - 4797 89/<- %ebp 4/r32/esp - 4798 # setup - 4799 (clear-stream _test-input-stream) - 4800 (clear-stream $_test-input-buffered-file->buffer) - 4801 (clear-stream _test-output-stream) - 4802 (clear-stream $_test-output-buffered-file->buffer) - 4803 # - 4804 (write _test-input-stream "fn foo {\n") - 4805 (write _test-input-stream " var arr/eax: (addr array int) <- copy 0\n") - 4806 (write _test-input-stream " var idx: int\n") - 4807 (write _test-input-stream " var off/ecx: (offset int) <- compute-offset arr, idx\n") - 4808 (write _test-input-stream " var x/eax: (addr int) <- index arr, off\n") - 4809 (write _test-input-stream "}\n") - 4810 # convert - 4811 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 4812 (flush _test-output-buffered-file) - 4813 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 4819 # check output - 4820 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-using-offset-on-stack/0") - 4821 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-using-offset-on-stack/1") - 4822 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-using-offset-on-stack/2") - 4823 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-using-offset-on-stack/3") - 4824 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-using-offset-on-stack/4") - 4825 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-using-offset-on-stack/5") - 4826 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-using-offset-on-stack/6") - 4827 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-index-into-array-using-offset-on-stack/7") - 4828 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-index-into-array-using-offset-on-stack/8") - 4829 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-index-into-array-using-offset-on-stack/9") - 4830 (check-next-stream-line-equal _test-output-stream " 69/multiply *(ebp+0xfffffff8) 0x00000004/imm32 0x00000001/r32" "F - test-convert-index-into-array-using-offset-on-stack/10") - 4831 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + ecx + 4) 0x00000000/r32" "F - test-convert-index-into-array-using-offset-on-stack/11") - 4832 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-index-into-array-using-offset-on-stack/12") - 4833 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-index-into-array-using-offset-on-stack/13") - 4834 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-using-offset-on-stack/14") - 4835 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-using-offset-on-stack/15") - 4836 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-using-offset-on-stack/16") - 4837 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-using-offset-on-stack/17") - 4838 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-using-offset-on-stack/18") - 4839 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-using-offset-on-stack/19") - 4840 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-using-offset-on-stack/20") - 4841 # . epilogue - 4842 89/<- %esp 5/r32/ebp - 4843 5d/pop-to-ebp - 4844 c3/return - 4845 - 4846 test-convert-index-into-array-of-bytes-using-offset-on-stack: - 4847 # . prologue - 4848 55/push-ebp - 4849 89/<- %ebp 4/r32/esp - 4850 # setup - 4851 (clear-stream _test-input-stream) - 4852 (clear-stream $_test-input-buffered-file->buffer) - 4853 (clear-stream _test-output-stream) - 4854 (clear-stream $_test-output-buffered-file->buffer) - 4855 # - 4856 (write _test-input-stream "fn foo {\n") - 4857 (write _test-input-stream " var arr/eax: (addr array byte) <- copy 0\n") - 4858 (write _test-input-stream " var idx: int\n") - 4859 (write _test-input-stream " var off/ecx: (offset byte) <- compute-offset arr, idx\n") - 4860 (write _test-input-stream " var x/eax: (addr byte) <- index arr, off\n") - 4861 (write _test-input-stream "}\n") - 4862 # convert - 4863 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 4864 (flush _test-output-buffered-file) - 4865 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 4871 # check output - 4872 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/0") - 4873 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/1") - 4874 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/2") - 4875 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/3") - 4876 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/4") - 4877 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/5") - 4878 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/6") - 4879 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/7") - 4880 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/8") - 4881 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/9") - 4882 (check-next-stream-line-equal _test-output-stream " 69/multiply *(ebp+0xfffffff8) 0x00000001/imm32 0x00000001/r32" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/10") - 4883 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + ecx + 4) 0x00000000/r32" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/11") - 4884 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/12") - 4885 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/13") - 4886 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/14") - 4887 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/15") - 4888 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/16") - 4889 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/17") - 4890 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/18") - 4891 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/19") - 4892 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/20") - 4893 # . epilogue - 4894 89/<- %esp 5/r32/ebp - 4895 5d/pop-to-ebp - 4896 c3/return - 4897 - 4898 test-convert-function-and-type-definition: - 4899 # . prologue - 4900 55/push-ebp - 4901 89/<- %ebp 4/r32/esp - 4902 # setup - 4903 (clear-stream _test-input-stream) - 4904 (clear-stream $_test-input-buffered-file->buffer) - 4905 (clear-stream _test-output-stream) - 4906 (clear-stream $_test-output-buffered-file->buffer) - 4907 # - 4908 (write _test-input-stream "fn foo a: (addr t) {\n") - 4909 (write _test-input-stream " var _a/eax: (addr t) <- copy a\n") - 4910 (write _test-input-stream " var b/ecx: (addr int) <- get _a, x\n") - 4911 (write _test-input-stream " var c/ecx: (addr int) <- get _a, y\n") - 4912 (write _test-input-stream "}\n") - 4913 (write _test-input-stream "type t {\n") - 4914 (write _test-input-stream " x: int\n") - 4915 (write _test-input-stream " y: int\n") - 4916 (write _test-input-stream "}\n") - 4917 # convert - 4918 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 4919 (flush _test-output-buffered-file) - 4920 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 4926 # check output - 4927 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-and-type-definition/0") - 4928 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-and-type-definition/1") - 4929 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-and-type-definition/2") - 4930 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-and-type-definition/3") - 4931 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-and-type-definition/4") - 4932 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-and-type-definition/5") - 4933 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-function-and-type-definition/6") - 4934 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x00000008) 0x00000000/r32" "F - test-convert-function-and-type-definition/7") - 4935 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-function-and-type-definition/8") - 4936 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + 0x00000000) 0x00000001/r32" "F - test-convert-function-and-type-definition/9") - 4937 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + 0x00000004) 0x00000001/r32" "F - test-convert-function-and-type-definition/11") - 4938 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-function-and-type-definition/13") - 4939 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-function-and-type-definition/14") - 4940 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-and-type-definition/15") - 4941 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-and-type-definition/16") - 4942 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-and-type-definition/17") - 4943 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-and-type-definition/18") - 4944 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-and-type-definition/19") - 4945 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-and-type-definition/20") - 4946 # . epilogue - 4947 89/<- %esp 5/r32/ebp - 4948 5d/pop-to-ebp - 4949 c3/return - 4950 - 4951 test-type-definition-with-array: - 4952 # . prologue - 4953 55/push-ebp - 4954 89/<- %ebp 4/r32/esp - 4955 # setup - 4956 (clear-stream _test-input-stream) - 4957 (clear-stream $_test-input-buffered-file->buffer) - 4958 (clear-stream _test-output-stream) - 4959 (clear-stream $_test-output-buffered-file->buffer) - 4960 (clear-stream _test-error-stream) - 4961 (clear-stream $_test-error-buffered-file->buffer) - 4962 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 4963 68/push 0/imm32 - 4964 68/push 0/imm32 - 4965 89/<- %edx 4/r32/esp - 4966 (tailor-exit-descriptor %edx 0x10) - 4967 # - 4968 (write _test-input-stream "type t {\n") - 4969 (write _test-input-stream " a: (array int 3)\n") - 4970 (write _test-input-stream "}\n") - 4971 # convert - 4972 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 4973 # registers except esp clobbered at this point - 4974 # restore ed - 4975 89/<- %edx 4/r32/esp - 4976 (flush _test-output-buffered-file) - 4977 (flush _test-error-buffered-file) - 4978 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 4984 # check output - 4985 (check-stream-equal _test-output-stream "" "F - test-type-definition-with-array: output should be empty") - 4986 (check-next-stream-line-equal _test-error-stream "type t: 'array' elements not allowed for now" "F - test-type-definition-with-array: error message") - 4987 # check that stop(1) was called - 4988 (check-ints-equal *(edx+4) 2 "F - test-type-definition-with-array: exit status") - 4989 # don't restore from ebp - 4990 81 0/subop/add %esp 8/imm32 - 4991 # . epilogue - 4992 5d/pop-to-ebp - 4993 c3/return - 4994 - 4995 test-type-definition-with-addr: - 4996 # . prologue - 4997 55/push-ebp - 4998 89/<- %ebp 4/r32/esp - 4999 # setup - 5000 (clear-stream _test-input-stream) - 5001 (clear-stream $_test-input-buffered-file->buffer) - 5002 (clear-stream _test-output-stream) - 5003 (clear-stream $_test-output-buffered-file->buffer) - 5004 (clear-stream _test-error-stream) - 5005 (clear-stream $_test-error-buffered-file->buffer) - 5006 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 5007 68/push 0/imm32 - 5008 68/push 0/imm32 - 5009 89/<- %edx 4/r32/esp - 5010 (tailor-exit-descriptor %edx 0x10) - 5011 # - 5012 (write _test-input-stream "type t {\n") - 5013 (write _test-input-stream " a: (addr int)\n") - 5014 (write _test-input-stream "}\n") - 5015 # convert - 5016 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 5017 # registers except esp clobbered at this point - 5018 # restore ed - 5019 89/<- %edx 4/r32/esp - 5020 (flush _test-output-buffered-file) - 5021 (flush _test-error-buffered-file) - 5022 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 5028 # check output - 5029 (check-stream-equal _test-output-stream "" "F - test-type-definition-with-addr: output should be empty") - 5030 (check-next-stream-line-equal _test-error-stream "type t: 'addr' elements not allowed" "F - test-type-definition-with-addr: error message") - 5031 # check that stop(1) was called - 5032 (check-ints-equal *(edx+4) 2 "F - test-type-definition-with-addr: exit status") - 5033 # don't restore from ebp - 5034 81 0/subop/add %esp 8/imm32 - 5035 # . epilogue - 5036 5d/pop-to-ebp - 5037 c3/return - 5038 - 5039 test-convert-function-with-local-var-with-user-defined-type: - 5040 # . prologue - 5041 55/push-ebp - 5042 89/<- %ebp 4/r32/esp - 5043 # setup - 5044 (clear-stream _test-input-stream) - 5045 (clear-stream $_test-input-buffered-file->buffer) - 5046 (clear-stream _test-output-stream) - 5047 (clear-stream $_test-output-buffered-file->buffer) - 5048 # - 5049 (write _test-input-stream "fn foo {\n") - 5050 (write _test-input-stream " var a: t\n") - 5051 (write _test-input-stream "}\n") - 5052 (write _test-input-stream "type t {\n") - 5053 (write _test-input-stream " x: int\n") - 5054 (write _test-input-stream " y: int\n") - 5055 (write _test-input-stream "}\n") - 5056 # convert - 5057 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 5058 (flush _test-output-buffered-file) - 5059 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 5065 # check output - 5066 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-var-with-user-defined-type/0") - 5067 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-var-with-user-defined-type/1") - 5068 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-var-with-user-defined-type/2") - 5069 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-local-var-with-user-defined-type/3") - 5070 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-with-user-defined-type/4") - 5071 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-var-with-user-defined-type/5") - 5072 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-local-var-with-user-defined-type/6") - 5073 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-local-var-with-user-defined-type/7") - 5074 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000008/imm32" "F - test-convert-function-with-local-var-with-user-defined-type/8") - 5075 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-with-user-defined-type/9") - 5076 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-var-with-user-defined-type/10") - 5077 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-var-with-user-defined-type/11") - 5078 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-local-var-with-user-defined-type/12") - 5079 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-var-with-user-defined-type/13") - 5080 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-var-with-user-defined-type/14") - 5081 # . epilogue - 5082 89/<- %esp 5/r32/ebp - 5083 5d/pop-to-ebp - 5084 c3/return - 5085 - 5086 test-convert-function-with-local-var-with-user-defined-type-containing-user-defined-type: - 5087 # . prologue - 5088 55/push-ebp - 5089 89/<- %ebp 4/r32/esp - 5090 # setup - 5091 (clear-stream _test-input-stream) - 5092 (clear-stream $_test-input-buffered-file->buffer) - 5093 (clear-stream _test-output-stream) - 5094 (clear-stream $_test-output-buffered-file->buffer) - 5095 # - 5096 (write _test-input-stream "fn foo {\n") - 5097 (write _test-input-stream " var a: t\n") - 5098 (write _test-input-stream "}\n") - 5099 (write _test-input-stream "type t {\n") - 5100 (write _test-input-stream " x: s\n") - 5101 (write _test-input-stream "}\n") - 5102 (write _test-input-stream "type s {\n") - 5103 (write _test-input-stream " z: int\n") + 4314 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 4320 (check-stream-equal _test-error-stream "" "F - test-reg-var-def-with-read-of-same-register: error stream should be empty") + 4321 # check output + 4322 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-reg-var-def-with-read-of-same-register/0") + 4323 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-reg-var-def-with-read-of-same-register/1") + 4324 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-reg-var-def-with-read-of-same-register/2") + 4325 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-reg-var-def-with-read-of-same-register/3") + 4326 (check-next-stream-line-equal _test-output-stream " {" "F - test-reg-var-def-with-read-of-same-register/4") + 4327 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-reg-var-def-with-read-of-same-register/5") + 4328 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-reg-var-def-with-read-of-same-register/6") + 4329 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-reg-var-def-with-read-of-same-register/7") + 4330 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-reg-var-def-with-read-of-same-register/8") + 4331 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-reg-var-def-with-read-of-same-register/9") + 4332 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + ecx<<0x00000002 + 4) 0x00000000/r32" "F - test-reg-var-def-with-read-of-same-register/11") + 4333 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-reg-var-def-with-read-of-same-register/13") + 4334 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-reg-var-def-with-read-of-same-register/14") + 4335 (check-next-stream-line-equal _test-output-stream " }" "F - test-reg-var-def-with-read-of-same-register/15") + 4336 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-reg-var-def-with-read-of-same-register/16") + 4337 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-reg-var-def-with-read-of-same-register/17") + 4338 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-reg-var-def-with-read-of-same-register/18") + 4339 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-reg-var-def-with-read-of-same-register/19") + 4340 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-reg-var-def-with-read-of-same-register/20") + 4341 # don't restore from ebp + 4342 81 0/subop/add %esp 8/imm32 + 4343 # . epilogue + 4344 5d/pop-to-ebp + 4345 c3/return + 4346 + 4347 test-convert-index-into-array: + 4348 # . prologue + 4349 55/push-ebp + 4350 89/<- %ebp 4/r32/esp + 4351 # setup + 4352 (clear-stream _test-input-stream) + 4353 (clear-stream $_test-input-buffered-file->buffer) + 4354 (clear-stream _test-output-stream) + 4355 (clear-stream $_test-output-buffered-file->buffer) + 4356 # + 4357 (write _test-input-stream "fn foo {\n") + 4358 (write _test-input-stream " var arr/eax: (addr array int) <- copy 0\n") + 4359 (write _test-input-stream " var idx/ecx: int <- copy 3\n") + 4360 (write _test-input-stream " var x/eax: (addr int) <- index arr, idx\n") + 4361 (write _test-input-stream "}\n") + 4362 # convert + 4363 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 4364 (flush _test-output-buffered-file) + 4365 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 4371 # check output + 4372 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array/0") + 4373 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array/1") + 4374 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array/2") + 4375 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array/3") + 4376 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array/4") + 4377 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array/5") + 4378 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array/6") + 4379 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-index-into-array/7") + 4380 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-index-into-array/8") + 4381 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-convert-index-into-array/9") + 4382 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + ecx<<0x00000002 + 4) 0x00000000/r32" "F - test-convert-index-into-array/10") + 4383 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-index-into-array/11") + 4384 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array/12") + 4385 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array/13") + 4386 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array/14") + 4387 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array/15") + 4388 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array/16") + 4389 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array/17") + 4390 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array/18") + 4391 # . epilogue + 4392 89/<- %esp 5/r32/ebp + 4393 5d/pop-to-ebp + 4394 c3/return + 4395 + 4396 test-convert-index-into-array-of-bytes: + 4397 # . prologue + 4398 55/push-ebp + 4399 89/<- %ebp 4/r32/esp + 4400 # setup + 4401 (clear-stream _test-input-stream) + 4402 (clear-stream $_test-input-buffered-file->buffer) + 4403 (clear-stream _test-output-stream) + 4404 (clear-stream $_test-output-buffered-file->buffer) + 4405 # + 4406 (write _test-input-stream "fn foo {\n") + 4407 (write _test-input-stream " var arr/eax: (addr array byte) <- copy 0\n") + 4408 (write _test-input-stream " var idx/ecx: int <- copy 3\n") + 4409 (write _test-input-stream " var x/eax: (addr byte) <- index arr, idx\n") + 4410 (write _test-input-stream "}\n") + 4411 # convert + 4412 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 4413 (flush _test-output-buffered-file) + 4414 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 4420 # check output + 4421 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-of-bytes/0") + 4422 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-of-bytes/1") + 4423 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-of-bytes/2") + 4424 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-of-bytes/3") + 4425 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-of-bytes/4") + 4426 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-of-bytes/5") + 4427 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-of-bytes/6") + 4428 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-index-into-array-of-bytes/7") + 4429 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-index-into-array-of-bytes/8") + 4430 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-convert-index-into-array-of-bytes/9") + 4431 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + ecx<<0x00000000 + 4) 0x00000000/r32" "F - test-convert-index-into-array-of-bytes/11") + 4432 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-index-into-array-of-bytes/13") + 4433 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-of-bytes/14") + 4434 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-of-bytes/15") + 4435 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-of-bytes/16") + 4436 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-of-bytes/17") + 4437 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-of-bytes/18") + 4438 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-of-bytes/19") + 4439 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-of-bytes/20") + 4440 # . epilogue + 4441 89/<- %esp 5/r32/ebp + 4442 5d/pop-to-ebp + 4443 c3/return + 4444 + 4445 test-convert-index-into-array-with-literal: + 4446 # . prologue + 4447 55/push-ebp + 4448 89/<- %ebp 4/r32/esp + 4449 # setup + 4450 (clear-stream _test-input-stream) + 4451 (clear-stream $_test-input-buffered-file->buffer) + 4452 (clear-stream _test-output-stream) + 4453 (clear-stream $_test-output-buffered-file->buffer) + 4454 # + 4455 (write _test-input-stream "fn foo {\n") + 4456 (write _test-input-stream " var arr/eax: (addr array int) <- copy 0\n") + 4457 (write _test-input-stream " var x/eax: (addr int) <- index arr, 2\n") + 4458 (write _test-input-stream "}\n") + 4459 # convert + 4460 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 4461 (flush _test-output-buffered-file) + 4462 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 4468 # check output + 4469 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-with-literal/0") + 4470 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-with-literal/1") + 4471 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-with-literal/2") + 4472 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-with-literal/3") + 4473 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-with-literal/4") + 4474 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-with-literal/5") + 4475 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-with-literal/6") + 4476 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-index-into-array-with-literal/7") + 4477 # 2 * 4 bytes/elem + 4 bytes for size = offset 12 + 4478 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + 0x0000000c) 0x00000000/r32" "F - test-convert-index-into-array-with-literal/8") + 4479 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-with-literal/9") + 4480 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-with-literal/10") + 4481 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-with-literal/11") + 4482 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-with-literal/12") + 4483 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-with-literal/13") + 4484 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-with-literal/14") + 4485 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-with-literal/15") + 4486 # . epilogue + 4487 89/<- %esp 5/r32/ebp + 4488 5d/pop-to-ebp + 4489 c3/return + 4490 + 4491 test-convert-index-into-array-of-bytes-with-literal: + 4492 # . prologue + 4493 55/push-ebp + 4494 89/<- %ebp 4/r32/esp + 4495 # setup + 4496 (clear-stream _test-input-stream) + 4497 (clear-stream $_test-input-buffered-file->buffer) + 4498 (clear-stream _test-output-stream) + 4499 (clear-stream $_test-output-buffered-file->buffer) + 4500 # + 4501 (write _test-input-stream "fn foo {\n") + 4502 (write _test-input-stream " var arr/eax: (addr array byte) <- copy 0\n") + 4503 (write _test-input-stream " var x/eax: (addr byte) <- index arr, 2\n") + 4504 (write _test-input-stream "}\n") + 4505 # convert + 4506 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 4507 (flush _test-output-buffered-file) + 4508 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 4514 # check output + 4515 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-of-bytes-with-literal/0") + 4516 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-of-bytes-with-literal/1") + 4517 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-of-bytes-with-literal/2") + 4518 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-of-bytes-with-literal/3") + 4519 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-of-bytes-with-literal/4") + 4520 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-of-bytes-with-literal/5") + 4521 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-of-bytes-with-literal/6") + 4522 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-index-into-array-of-bytes-with-literal/7") + 4523 # 2 * 1 byte/elem + 4 bytes for size = offset 6 + 4524 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + 0x00000006) 0x00000000/r32" "F - test-convert-index-into-array-of-bytes-with-literal/8") + 4525 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-of-bytes-with-literal/9") + 4526 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-of-bytes-with-literal/10") + 4527 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-of-bytes-with-literal/11") + 4528 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-of-bytes-with-literal/12") + 4529 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-of-bytes-with-literal/13") + 4530 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-of-bytes-with-literal/14") + 4531 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-of-bytes-with-literal/15") + 4532 # . epilogue + 4533 89/<- %esp 5/r32/ebp + 4534 5d/pop-to-ebp + 4535 c3/return + 4536 + 4537 test-convert-index-into-array-on-stack: + 4538 # . prologue + 4539 55/push-ebp + 4540 89/<- %ebp 4/r32/esp + 4541 # setup + 4542 (clear-stream _test-input-stream) + 4543 (clear-stream $_test-input-buffered-file->buffer) + 4544 (clear-stream _test-output-stream) + 4545 (clear-stream $_test-output-buffered-file->buffer) + 4546 # + 4547 (write _test-input-stream "fn foo {\n") + 4548 (write _test-input-stream " var arr: (array int 3)\n") + 4549 (write _test-input-stream " var idx/eax: int <- copy 2\n") + 4550 (write _test-input-stream " var x/eax: (addr int) <- index arr, idx\n") + 4551 (write _test-input-stream "}\n") + 4552 # convert + 4553 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 4554 (flush _test-output-buffered-file) + 4555 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 4561 # check output + 4562 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-on-stack/0") + 4563 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-on-stack/1") + 4564 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-on-stack/2") + 4565 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-on-stack/3") + 4566 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-on-stack/4") + 4567 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-on-stack/5") + 4568 # var arr + 4569 (check-next-stream-line-equal _test-output-stream " (push-n-zero-bytes 0x0000000c)" "F - test-convert-index-into-array-on-stack/6") + 4570 (check-next-stream-line-equal _test-output-stream " 68/push 0x0000000c/imm32" "F - test-convert-index-into-array-on-stack/7") + 4571 # var idx + 4572 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-on-stack/8") + 4573 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 2/imm32" "F - test-convert-index-into-array-on-stack/9") + 4574 # var x is at (ebp-0x10) + idx<<2 + 4 = ebp + idx<<2 - 0xc + 4575 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(ebp + eax<<0x00000002 + 0xfffffff4) 0x00000000/r32" "F - test-convert-index-into-array-on-stack/10") + 4576 # reclaim idx + 4577 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-on-stack/11") + 4578 # reclaim arr + 4579 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000010/imm32" "F - test-convert-index-into-array-on-stack/12") + 4580 # + 4581 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-on-stack/13") + 4582 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-on-stack/14") + 4583 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-on-stack/15") + 4584 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-on-stack/16") + 4585 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-on-stack/17") + 4586 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-on-stack/18") + 4587 # . epilogue + 4588 89/<- %esp 5/r32/ebp + 4589 5d/pop-to-ebp + 4590 c3/return + 4591 + 4592 test-convert-index-into-array-on-stack-with-literal: + 4593 # . prologue + 4594 55/push-ebp + 4595 89/<- %ebp 4/r32/esp + 4596 # setup + 4597 (clear-stream _test-input-stream) + 4598 (clear-stream $_test-input-buffered-file->buffer) + 4599 (clear-stream _test-output-stream) + 4600 (clear-stream $_test-output-buffered-file->buffer) + 4601 # + 4602 (write _test-input-stream "fn foo {\n") + 4603 (write _test-input-stream " var arr: (array int 3)\n") + 4604 (write _test-input-stream " var x/eax: (addr int) <- index arr, 2\n") + 4605 (write _test-input-stream "}\n") + 4606 # convert + 4607 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 4608 (flush _test-output-buffered-file) + 4609 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 4615 # check output + 4616 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-on-stack-with-literal/0") + 4617 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-on-stack-with-literal/1") + 4618 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-on-stack-with-literal/2") + 4619 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-on-stack-with-literal/3") + 4620 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-on-stack-with-literal/4") + 4621 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-on-stack-with-literal/5") + 4622 # var arr + 4623 (check-next-stream-line-equal _test-output-stream " (push-n-zero-bytes 0x0000000c)" "F - test-convert-index-into-array-on-stack-with-literal/6") + 4624 (check-next-stream-line-equal _test-output-stream " 68/push 0x0000000c/imm32" "F - test-convert-index-into-array-on-stack-with-literal/7") + 4625 # var x + 4626 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-on-stack-with-literal/8") + 4627 # x is at (ebp-0x10) + 4 + 2*4 = ebp-4 + 4628 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(ebp + 0xfffffffc) 0x00000000/r32" "F - test-convert-index-into-array-on-stack-with-literal/9") + 4629 # reclaim x + 4630 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-on-stack-with-literal/10") + 4631 # reclaim arr + 4632 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000010/imm32" "F - test-convert-index-into-array-on-stack-with-literal/11") + 4633 # + 4634 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-on-stack-with-literal/12") + 4635 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-on-stack-with-literal/13") + 4636 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-on-stack-with-literal/14") + 4637 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-on-stack-with-literal/15") + 4638 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-on-stack-with-literal/16") + 4639 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-on-stack-with-literal/17") + 4640 # . epilogue + 4641 89/<- %esp 5/r32/ebp + 4642 5d/pop-to-ebp + 4643 c3/return + 4644 + 4645 test-convert-index-into-array-of-bytes-on-stack-with-literal: + 4646 # . prologue + 4647 55/push-ebp + 4648 89/<- %ebp 4/r32/esp + 4649 # setup + 4650 (clear-stream _test-input-stream) + 4651 (clear-stream $_test-input-buffered-file->buffer) + 4652 (clear-stream _test-output-stream) + 4653 (clear-stream $_test-output-buffered-file->buffer) + 4654 # + 4655 (write _test-input-stream "fn foo {\n") + 4656 (write _test-input-stream " var arr: (array byte 3)\n") + 4657 (write _test-input-stream " var x/eax: (addr byte) <- index arr, 2\n") + 4658 (write _test-input-stream "}\n") + 4659 # convert + 4660 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 4661 (flush _test-output-buffered-file) + 4662 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 4668 # check output + 4669 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/0") + 4670 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/1") + 4671 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/2") + 4672 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/3") + 4673 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/4") + 4674 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/5") + 4675 # var arr + 4676 (check-next-stream-line-equal _test-output-stream " (push-n-zero-bytes 0x00000003)" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/6") + 4677 (check-next-stream-line-equal _test-output-stream " 68/push 0x00000003/imm32" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/7") + 4678 # var x + 4679 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/8") + 4680 # x is at (ebp-7) + 4 + 2 = ebp-1 + 4681 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(ebp + 0xffffffff) 0x00000000/r32" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/9") + 4682 # reclaim x + 4683 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/10") + 4684 # reclaim arr + 4685 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000007/imm32" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/11") + 4686 # + 4687 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/12") + 4688 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/13") + 4689 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/14") + 4690 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/15") + 4691 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/16") + 4692 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/17") + 4693 # . epilogue + 4694 89/<- %esp 5/r32/ebp + 4695 5d/pop-to-ebp + 4696 c3/return + 4697 + 4698 test-convert-index-into-array-using-offset: + 4699 # . prologue + 4700 55/push-ebp + 4701 89/<- %ebp 4/r32/esp + 4702 # setup + 4703 (clear-stream _test-input-stream) + 4704 (clear-stream $_test-input-buffered-file->buffer) + 4705 (clear-stream _test-output-stream) + 4706 (clear-stream $_test-output-buffered-file->buffer) + 4707 # + 4708 (write _test-input-stream "fn foo {\n") + 4709 (write _test-input-stream " var arr/eax: (addr array int) <- copy 0\n") + 4710 (write _test-input-stream " var idx/ecx: int <- copy 3\n") + 4711 (write _test-input-stream " var off/ecx: (offset int) <- compute-offset arr, idx\n") + 4712 (write _test-input-stream " var x/eax: (addr int) <- index arr, off\n") + 4713 (write _test-input-stream "}\n") + 4714 # convert + 4715 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 4716 (flush _test-output-buffered-file) + 4717 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 4723 # check output + 4724 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-using-offset/0") + 4725 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-using-offset/1") + 4726 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-using-offset/2") + 4727 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-using-offset/3") + 4728 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-using-offset/4") + 4729 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-using-offset/5") + 4730 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-using-offset/6") + 4731 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-index-into-array-using-offset/7") + 4732 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-index-into-array-using-offset/8") + 4733 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-convert-index-into-array-using-offset/9") + 4734 (check-next-stream-line-equal _test-output-stream " 69/multiply %ecx 0x00000004/imm32 0x00000001/r32" "F - test-convert-index-into-array-using-offset/10") + 4735 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + ecx + 4) 0x00000000/r32" "F - test-convert-index-into-array-using-offset/11") + 4736 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-index-into-array-using-offset/12") + 4737 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-using-offset/13") + 4738 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-using-offset/14") + 4739 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-using-offset/15") + 4740 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-using-offset/16") + 4741 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-using-offset/17") + 4742 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-using-offset/18") + 4743 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-using-offset/19") + 4744 # . epilogue + 4745 89/<- %esp 5/r32/ebp + 4746 5d/pop-to-ebp + 4747 c3/return + 4748 + 4749 test-convert-index-into-array-of-bytes-using-offset: + 4750 # . prologue + 4751 55/push-ebp + 4752 89/<- %ebp 4/r32/esp + 4753 # setup + 4754 (clear-stream _test-input-stream) + 4755 (clear-stream $_test-input-buffered-file->buffer) + 4756 (clear-stream _test-output-stream) + 4757 (clear-stream $_test-output-buffered-file->buffer) + 4758 # + 4759 (write _test-input-stream "fn foo {\n") + 4760 (write _test-input-stream " var arr/eax: (addr array byte) <- copy 0\n") + 4761 (write _test-input-stream " var idx/ecx: int <- copy 3\n") + 4762 (write _test-input-stream " var off/ecx: (offset byte) <- compute-offset arr, idx\n") + 4763 (write _test-input-stream " var x/eax: (addr byte) <- index arr, off\n") + 4764 (write _test-input-stream "}\n") + 4765 # convert + 4766 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 4767 (flush _test-output-buffered-file) + 4768 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 4774 # check output + 4775 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-of-bytes-using-offset/0") + 4776 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-of-bytes-using-offset/1") + 4777 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-of-bytes-using-offset/2") + 4778 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-of-bytes-using-offset/3") + 4779 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-of-bytes-using-offset/4") + 4780 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-of-bytes-using-offset/5") + 4781 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-of-bytes-using-offset/6") + 4782 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-index-into-array-of-bytes-using-offset/7") + 4783 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-index-into-array-of-bytes-using-offset/8") + 4784 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-convert-index-into-array-of-bytes-using-offset/9") + 4785 (check-next-stream-line-equal _test-output-stream " 69/multiply %ecx 0x00000001/imm32 0x00000001/r32" "F - test-convert-index-into-array-of-bytes-using-offset/10") + 4786 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + ecx + 4) 0x00000000/r32" "F - test-convert-index-into-array-of-bytes-using-offset/11") + 4787 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-index-into-array-of-bytes-using-offset/12") + 4788 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-of-bytes-using-offset/13") + 4789 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-of-bytes-using-offset/14") + 4790 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-of-bytes-using-offset/15") + 4791 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-of-bytes-using-offset/16") + 4792 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-of-bytes-using-offset/17") + 4793 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-of-bytes-using-offset/18") + 4794 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-of-bytes-using-offset/19") + 4795 # . epilogue + 4796 89/<- %esp 5/r32/ebp + 4797 5d/pop-to-ebp + 4798 c3/return + 4799 + 4800 test-convert-index-into-array-using-offset-on-stack: + 4801 # . prologue + 4802 55/push-ebp + 4803 89/<- %ebp 4/r32/esp + 4804 # setup + 4805 (clear-stream _test-input-stream) + 4806 (clear-stream $_test-input-buffered-file->buffer) + 4807 (clear-stream _test-output-stream) + 4808 (clear-stream $_test-output-buffered-file->buffer) + 4809 # + 4810 (write _test-input-stream "fn foo {\n") + 4811 (write _test-input-stream " var arr/eax: (addr array int) <- copy 0\n") + 4812 (write _test-input-stream " var idx: int\n") + 4813 (write _test-input-stream " var off/ecx: (offset int) <- compute-offset arr, idx\n") + 4814 (write _test-input-stream " var x/eax: (addr int) <- index arr, off\n") + 4815 (write _test-input-stream "}\n") + 4816 # convert + 4817 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 4818 (flush _test-output-buffered-file) + 4819 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 4825 # check output + 4826 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-using-offset-on-stack/0") + 4827 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-using-offset-on-stack/1") + 4828 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-using-offset-on-stack/2") + 4829 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-using-offset-on-stack/3") + 4830 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-using-offset-on-stack/4") + 4831 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-using-offset-on-stack/5") + 4832 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-using-offset-on-stack/6") + 4833 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-index-into-array-using-offset-on-stack/7") + 4834 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-index-into-array-using-offset-on-stack/8") + 4835 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-index-into-array-using-offset-on-stack/9") + 4836 (check-next-stream-line-equal _test-output-stream " 69/multiply *(ebp+0xfffffff8) 0x00000004/imm32 0x00000001/r32" "F - test-convert-index-into-array-using-offset-on-stack/10") + 4837 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + ecx + 4) 0x00000000/r32" "F - test-convert-index-into-array-using-offset-on-stack/11") + 4838 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-index-into-array-using-offset-on-stack/12") + 4839 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-index-into-array-using-offset-on-stack/13") + 4840 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-using-offset-on-stack/14") + 4841 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-using-offset-on-stack/15") + 4842 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-using-offset-on-stack/16") + 4843 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-using-offset-on-stack/17") + 4844 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-using-offset-on-stack/18") + 4845 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-using-offset-on-stack/19") + 4846 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-using-offset-on-stack/20") + 4847 # . epilogue + 4848 89/<- %esp 5/r32/ebp + 4849 5d/pop-to-ebp + 4850 c3/return + 4851 + 4852 test-convert-index-into-array-of-bytes-using-offset-on-stack: + 4853 # . prologue + 4854 55/push-ebp + 4855 89/<- %ebp 4/r32/esp + 4856 # setup + 4857 (clear-stream _test-input-stream) + 4858 (clear-stream $_test-input-buffered-file->buffer) + 4859 (clear-stream _test-output-stream) + 4860 (clear-stream $_test-output-buffered-file->buffer) + 4861 # + 4862 (write _test-input-stream "fn foo {\n") + 4863 (write _test-input-stream " var arr/eax: (addr array byte) <- copy 0\n") + 4864 (write _test-input-stream " var idx: int\n") + 4865 (write _test-input-stream " var off/ecx: (offset byte) <- compute-offset arr, idx\n") + 4866 (write _test-input-stream " var x/eax: (addr byte) <- index arr, off\n") + 4867 (write _test-input-stream "}\n") + 4868 # convert + 4869 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 4870 (flush _test-output-buffered-file) + 4871 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 4877 # check output + 4878 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/0") + 4879 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/1") + 4880 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/2") + 4881 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/3") + 4882 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/4") + 4883 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/5") + 4884 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/6") + 4885 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/7") + 4886 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/8") + 4887 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/9") + 4888 (check-next-stream-line-equal _test-output-stream " 69/multiply *(ebp+0xfffffff8) 0x00000001/imm32 0x00000001/r32" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/10") + 4889 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + ecx + 4) 0x00000000/r32" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/11") + 4890 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/12") + 4891 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/13") + 4892 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/14") + 4893 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/15") + 4894 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/16") + 4895 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/17") + 4896 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/18") + 4897 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/19") + 4898 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/20") + 4899 # . epilogue + 4900 89/<- %esp 5/r32/ebp + 4901 5d/pop-to-ebp + 4902 c3/return + 4903 + 4904 test-convert-function-and-type-definition: + 4905 # . prologue + 4906 55/push-ebp + 4907 89/<- %ebp 4/r32/esp + 4908 # setup + 4909 (clear-stream _test-input-stream) + 4910 (clear-stream $_test-input-buffered-file->buffer) + 4911 (clear-stream _test-output-stream) + 4912 (clear-stream $_test-output-buffered-file->buffer) + 4913 # + 4914 (write _test-input-stream "fn foo a: (addr t) {\n") + 4915 (write _test-input-stream " var _a/eax: (addr t) <- copy a\n") + 4916 (write _test-input-stream " var b/ecx: (addr int) <- get _a, x\n") + 4917 (write _test-input-stream " var c/ecx: (addr int) <- get _a, y\n") + 4918 (write _test-input-stream "}\n") + 4919 (write _test-input-stream "type t {\n") + 4920 (write _test-input-stream " x: int\n") + 4921 (write _test-input-stream " y: int\n") + 4922 (write _test-input-stream "}\n") + 4923 # convert + 4924 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 4925 (flush _test-output-buffered-file) + 4926 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 4932 # check output + 4933 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-and-type-definition/0") + 4934 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-and-type-definition/1") + 4935 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-and-type-definition/2") + 4936 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-and-type-definition/3") + 4937 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-and-type-definition/4") + 4938 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-and-type-definition/5") + 4939 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-function-and-type-definition/6") + 4940 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x00000008) 0x00000000/r32" "F - test-convert-function-and-type-definition/7") + 4941 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-function-and-type-definition/8") + 4942 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + 0x00000000) 0x00000001/r32" "F - test-convert-function-and-type-definition/9") + 4943 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + 0x00000004) 0x00000001/r32" "F - test-convert-function-and-type-definition/11") + 4944 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-function-and-type-definition/13") + 4945 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-function-and-type-definition/14") + 4946 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-and-type-definition/15") + 4947 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-and-type-definition/16") + 4948 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-and-type-definition/17") + 4949 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-and-type-definition/18") + 4950 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-and-type-definition/19") + 4951 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-and-type-definition/20") + 4952 # . epilogue + 4953 89/<- %esp 5/r32/ebp + 4954 5d/pop-to-ebp + 4955 c3/return + 4956 + 4957 test-type-definition-with-array: + 4958 # . prologue + 4959 55/push-ebp + 4960 89/<- %ebp 4/r32/esp + 4961 # setup + 4962 (clear-stream _test-input-stream) + 4963 (clear-stream $_test-input-buffered-file->buffer) + 4964 (clear-stream _test-output-stream) + 4965 (clear-stream $_test-output-buffered-file->buffer) + 4966 (clear-stream _test-error-stream) + 4967 (clear-stream $_test-error-buffered-file->buffer) + 4968 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 4969 68/push 0/imm32 + 4970 68/push 0/imm32 + 4971 89/<- %edx 4/r32/esp + 4972 (tailor-exit-descriptor %edx 0x10) + 4973 # + 4974 (write _test-input-stream "type t {\n") + 4975 (write _test-input-stream " a: (array int 3)\n") + 4976 (write _test-input-stream "}\n") + 4977 # convert + 4978 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 4979 # registers except esp clobbered at this point + 4980 # restore ed + 4981 89/<- %edx 4/r32/esp + 4982 (flush _test-output-buffered-file) + 4983 (flush _test-error-buffered-file) + 4984 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 4990 # check output + 4991 (check-stream-equal _test-output-stream "" "F - test-type-definition-with-array: output should be empty") + 4992 (check-next-stream-line-equal _test-error-stream "type t: 'array' elements not allowed for now" "F - test-type-definition-with-array: error message") + 4993 # check that stop(1) was called + 4994 (check-ints-equal *(edx+4) 2 "F - test-type-definition-with-array: exit status") + 4995 # don't restore from ebp + 4996 81 0/subop/add %esp 8/imm32 + 4997 # . epilogue + 4998 5d/pop-to-ebp + 4999 c3/return + 5000 + 5001 test-type-definition-with-addr: + 5002 # . prologue + 5003 55/push-ebp + 5004 89/<- %ebp 4/r32/esp + 5005 # setup + 5006 (clear-stream _test-input-stream) + 5007 (clear-stream $_test-input-buffered-file->buffer) + 5008 (clear-stream _test-output-stream) + 5009 (clear-stream $_test-output-buffered-file->buffer) + 5010 (clear-stream _test-error-stream) + 5011 (clear-stream $_test-error-buffered-file->buffer) + 5012 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 5013 68/push 0/imm32 + 5014 68/push 0/imm32 + 5015 89/<- %edx 4/r32/esp + 5016 (tailor-exit-descriptor %edx 0x10) + 5017 # + 5018 (write _test-input-stream "type t {\n") + 5019 (write _test-input-stream " a: (addr int)\n") + 5020 (write _test-input-stream "}\n") + 5021 # convert + 5022 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 5023 # registers except esp clobbered at this point + 5024 # restore ed + 5025 89/<- %edx 4/r32/esp + 5026 (flush _test-output-buffered-file) + 5027 (flush _test-error-buffered-file) + 5028 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 5034 # check output + 5035 (check-stream-equal _test-output-stream "" "F - test-type-definition-with-addr: output should be empty") + 5036 (check-next-stream-line-equal _test-error-stream "type t: 'addr' elements not allowed" "F - test-type-definition-with-addr: error message") + 5037 # check that stop(1) was called + 5038 (check-ints-equal *(edx+4) 2 "F - test-type-definition-with-addr: exit status") + 5039 # don't restore from ebp + 5040 81 0/subop/add %esp 8/imm32 + 5041 # . epilogue + 5042 5d/pop-to-ebp + 5043 c3/return + 5044 + 5045 test-convert-function-with-local-var-with-user-defined-type: + 5046 # . prologue + 5047 55/push-ebp + 5048 89/<- %ebp 4/r32/esp + 5049 # setup + 5050 (clear-stream _test-input-stream) + 5051 (clear-stream $_test-input-buffered-file->buffer) + 5052 (clear-stream _test-output-stream) + 5053 (clear-stream $_test-output-buffered-file->buffer) + 5054 # + 5055 (write _test-input-stream "fn foo {\n") + 5056 (write _test-input-stream " var a: t\n") + 5057 (write _test-input-stream "}\n") + 5058 (write _test-input-stream "type t {\n") + 5059 (write _test-input-stream " x: int\n") + 5060 (write _test-input-stream " y: int\n") + 5061 (write _test-input-stream "}\n") + 5062 # convert + 5063 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 5064 (flush _test-output-buffered-file) + 5065 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 5071 # check output + 5072 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-var-with-user-defined-type/0") + 5073 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-var-with-user-defined-type/1") + 5074 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-var-with-user-defined-type/2") + 5075 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-local-var-with-user-defined-type/3") + 5076 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-with-user-defined-type/4") + 5077 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-var-with-user-defined-type/5") + 5078 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-local-var-with-user-defined-type/6") + 5079 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-local-var-with-user-defined-type/7") + 5080 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000008/imm32" "F - test-convert-function-with-local-var-with-user-defined-type/8") + 5081 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-with-user-defined-type/9") + 5082 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-var-with-user-defined-type/10") + 5083 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-var-with-user-defined-type/11") + 5084 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-local-var-with-user-defined-type/12") + 5085 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-var-with-user-defined-type/13") + 5086 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-var-with-user-defined-type/14") + 5087 # . epilogue + 5088 89/<- %esp 5/r32/ebp + 5089 5d/pop-to-ebp + 5090 c3/return + 5091 + 5092 test-convert-function-with-local-var-with-user-defined-type-containing-user-defined-type: + 5093 # . prologue + 5094 55/push-ebp + 5095 89/<- %ebp 4/r32/esp + 5096 # setup + 5097 (clear-stream _test-input-stream) + 5098 (clear-stream $_test-input-buffered-file->buffer) + 5099 (clear-stream _test-output-stream) + 5100 (clear-stream $_test-output-buffered-file->buffer) + 5101 # + 5102 (write _test-input-stream "fn foo {\n") + 5103 (write _test-input-stream " var a: t\n") 5104 (write _test-input-stream "}\n") - 5105 # convert - 5106 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 5107 (flush _test-output-buffered-file) - 5108 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 5114 # check output - 5115 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-var-with-user-defined-type-containing-user-defined-type/0") - 5116 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-var-with-user-defined-type-containing-user-defined-type/1") - 5117 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-var-with-user-defined-type-containing-user-defined-type/2") - 5118 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-local-var-with-user-defined-type-containing-user-defined-type/3") - 5119 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-with-user-defined-type-containing-user-defined-type/4") - 5120 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-var-with-user-defined-type-containing-user-defined-type/5") - 5121 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-local-var-with-user-defined-type-containing-user-defined-type/7") - 5122 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-local-var-with-user-defined-type-containing-user-defined-type/8") - 5123 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-with-user-defined-type-containing-user-defined-type/9") - 5124 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-var-with-user-defined-type-containing-user-defined-type/10") - 5125 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-var-with-user-defined-type-containing-user-defined-type/11") - 5126 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-local-var-with-user-defined-type-containing-user-defined-type/12") - 5127 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-var-with-user-defined-type-containing-user-defined-type/13") - 5128 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-var-with-user-defined-type-containing-user-defined-type/14") - 5129 # . epilogue - 5130 89/<- %esp 5/r32/ebp - 5131 5d/pop-to-ebp - 5132 c3/return - 5133 - 5134 test-convert-function-call-with-arg-of-user-defined-type: - 5135 # . prologue - 5136 55/push-ebp - 5137 89/<- %ebp 4/r32/esp - 5138 # setup - 5139 (clear-stream _test-input-stream) - 5140 (clear-stream $_test-input-buffered-file->buffer) - 5141 (clear-stream _test-output-stream) - 5142 (clear-stream $_test-output-buffered-file->buffer) - 5143 # - 5144 (write _test-input-stream "fn f {\n") - 5145 (write _test-input-stream " var a: t\n") - 5146 (write _test-input-stream " foo a\n") - 5147 (write _test-input-stream "}\n") - 5148 (write _test-input-stream "fn foo x: t {\n") - 5149 (write _test-input-stream "}\n") - 5150 (write _test-input-stream "type t {\n") - 5151 (write _test-input-stream " x: int\n") - 5152 (write _test-input-stream " y: int\n") + 5105 (write _test-input-stream "type t {\n") + 5106 (write _test-input-stream " x: s\n") + 5107 (write _test-input-stream "}\n") + 5108 (write _test-input-stream "type s {\n") + 5109 (write _test-input-stream " z: int\n") + 5110 (write _test-input-stream "}\n") + 5111 # convert + 5112 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 5113 (flush _test-output-buffered-file) + 5114 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 5120 # check output + 5121 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-var-with-user-defined-type-containing-user-defined-type/0") + 5122 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-var-with-user-defined-type-containing-user-defined-type/1") + 5123 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-var-with-user-defined-type-containing-user-defined-type/2") + 5124 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-local-var-with-user-defined-type-containing-user-defined-type/3") + 5125 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-with-user-defined-type-containing-user-defined-type/4") + 5126 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-var-with-user-defined-type-containing-user-defined-type/5") + 5127 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-local-var-with-user-defined-type-containing-user-defined-type/7") + 5128 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-local-var-with-user-defined-type-containing-user-defined-type/8") + 5129 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-with-user-defined-type-containing-user-defined-type/9") + 5130 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-var-with-user-defined-type-containing-user-defined-type/10") + 5131 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-var-with-user-defined-type-containing-user-defined-type/11") + 5132 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-local-var-with-user-defined-type-containing-user-defined-type/12") + 5133 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-var-with-user-defined-type-containing-user-defined-type/13") + 5134 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-var-with-user-defined-type-containing-user-defined-type/14") + 5135 # . epilogue + 5136 89/<- %esp 5/r32/ebp + 5137 5d/pop-to-ebp + 5138 c3/return + 5139 + 5140 test-convert-function-call-with-arg-of-user-defined-type: + 5141 # . prologue + 5142 55/push-ebp + 5143 89/<- %ebp 4/r32/esp + 5144 # setup + 5145 (clear-stream _test-input-stream) + 5146 (clear-stream $_test-input-buffered-file->buffer) + 5147 (clear-stream _test-output-stream) + 5148 (clear-stream $_test-output-buffered-file->buffer) + 5149 # + 5150 (write _test-input-stream "fn f {\n") + 5151 (write _test-input-stream " var a: t\n") + 5152 (write _test-input-stream " foo a\n") 5153 (write _test-input-stream "}\n") - 5154 # convert - 5155 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 5156 (flush _test-output-buffered-file) - 5157 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 5163 # check output - 5164 (check-next-stream-line-equal _test-output-stream "f:" "F - test-convert-function-call-with-arg-of-user-defined-type/0") - 5165 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-arg-of-user-defined-type/1") - 5166 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/2") - 5167 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call-with-arg-of-user-defined-type/3") - 5168 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call-with-arg-of-user-defined-type/4") - 5169 (check-next-stream-line-equal _test-output-stream "$f:0x00000001:loop:" "F - test-convert-function-call-with-arg-of-user-defined-type/5") - 5170 # var a: t - 5171 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-call-with-arg-of-user-defined-type/6") - 5172 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-call-with-arg-of-user-defined-type/7") - 5173 # foo a - 5174 (check-next-stream-line-equal _test-output-stream " (foo *(ebp+0xfffffff8) *(ebp+0xfffffffc))" "F - test-convert-function-call-with-arg-of-user-defined-type/8") - 5175 # - 5176 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000008/imm32" "F - test-convert-function-call-with-arg-of-user-defined-type/9") - 5177 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call-with-arg-of-user-defined-type/10") - 5178 (check-next-stream-line-equal _test-output-stream "$f:0x00000001:break:" "F - test-convert-function-call-with-arg-of-user-defined-type/11") - 5179 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-arg-of-user-defined-type/12") - 5180 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/13") - 5181 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/14") - 5182 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-arg-of-user-defined-type/15") - 5183 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-call-with-arg-of-user-defined-type/16") - 5184 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-arg-of-user-defined-type/17") - 5185 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/18") - 5186 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call-with-arg-of-user-defined-type/19") - 5187 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-arg-of-user-defined-type/20") - 5188 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/21") - 5189 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/22") - 5190 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-arg-of-user-defined-type/23") - 5191 # . epilogue - 5192 89/<- %esp 5/r32/ebp - 5193 5d/pop-to-ebp - 5194 c3/return - 5195 - 5196 test-convert-function-call-with-arg-of-user-defined-type-register-indirect: - 5197 # . prologue - 5198 55/push-ebp - 5199 89/<- %ebp 4/r32/esp - 5200 # setup - 5201 (clear-stream _test-input-stream) - 5202 (clear-stream $_test-input-buffered-file->buffer) - 5203 (clear-stream _test-output-stream) - 5204 (clear-stream $_test-output-buffered-file->buffer) - 5205 # - 5206 (write _test-input-stream "fn f {\n") - 5207 (write _test-input-stream " var a/eax: (addr t) <- copy 0\n") - 5208 (write _test-input-stream " foo *a\n") - 5209 (write _test-input-stream "}\n") - 5210 (write _test-input-stream "fn foo x: t {\n") - 5211 (write _test-input-stream "}\n") - 5212 (write _test-input-stream "type t {\n") - 5213 (write _test-input-stream " x: int\n") - 5214 (write _test-input-stream " y: int\n") + 5154 (write _test-input-stream "fn foo x: t {\n") + 5155 (write _test-input-stream "}\n") + 5156 (write _test-input-stream "type t {\n") + 5157 (write _test-input-stream " x: int\n") + 5158 (write _test-input-stream " y: int\n") + 5159 (write _test-input-stream "}\n") + 5160 # convert + 5161 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 5162 (flush _test-output-buffered-file) + 5163 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 5169 # check output + 5170 (check-next-stream-line-equal _test-output-stream "f:" "F - test-convert-function-call-with-arg-of-user-defined-type/0") + 5171 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-arg-of-user-defined-type/1") + 5172 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/2") + 5173 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call-with-arg-of-user-defined-type/3") + 5174 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call-with-arg-of-user-defined-type/4") + 5175 (check-next-stream-line-equal _test-output-stream "$f:0x00000001:loop:" "F - test-convert-function-call-with-arg-of-user-defined-type/5") + 5176 # var a: t + 5177 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-call-with-arg-of-user-defined-type/6") + 5178 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-call-with-arg-of-user-defined-type/7") + 5179 # foo a + 5180 (check-next-stream-line-equal _test-output-stream " (foo *(ebp+0xfffffff8) *(ebp+0xfffffffc))" "F - test-convert-function-call-with-arg-of-user-defined-type/8") + 5181 # + 5182 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000008/imm32" "F - test-convert-function-call-with-arg-of-user-defined-type/9") + 5183 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call-with-arg-of-user-defined-type/10") + 5184 (check-next-stream-line-equal _test-output-stream "$f:0x00000001:break:" "F - test-convert-function-call-with-arg-of-user-defined-type/11") + 5185 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-arg-of-user-defined-type/12") + 5186 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/13") + 5187 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/14") + 5188 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-arg-of-user-defined-type/15") + 5189 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-call-with-arg-of-user-defined-type/16") + 5190 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-arg-of-user-defined-type/17") + 5191 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/18") + 5192 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call-with-arg-of-user-defined-type/19") + 5193 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-arg-of-user-defined-type/20") + 5194 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/21") + 5195 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/22") + 5196 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-arg-of-user-defined-type/23") + 5197 # . epilogue + 5198 89/<- %esp 5/r32/ebp + 5199 5d/pop-to-ebp + 5200 c3/return + 5201 + 5202 test-convert-function-call-with-arg-of-user-defined-type-register-indirect: + 5203 # . prologue + 5204 55/push-ebp + 5205 89/<- %ebp 4/r32/esp + 5206 # setup + 5207 (clear-stream _test-input-stream) + 5208 (clear-stream $_test-input-buffered-file->buffer) + 5209 (clear-stream _test-output-stream) + 5210 (clear-stream $_test-output-buffered-file->buffer) + 5211 # + 5212 (write _test-input-stream "fn f {\n") + 5213 (write _test-input-stream " var a/eax: (addr t) <- copy 0\n") + 5214 (write _test-input-stream " foo *a\n") 5215 (write _test-input-stream "}\n") - 5216 # convert - 5217 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 5218 (flush _test-output-buffered-file) - 5219 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 5225 # check output - 5226 (check-next-stream-line-equal _test-output-stream "f:" "F - test-convert-function-call-with-arg-of-user-defined-type/0") - 5227 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-arg-of-user-defined-type/1") - 5228 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/2") - 5229 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call-with-arg-of-user-defined-type/3") - 5230 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call-with-arg-of-user-defined-type/4") - 5231 (check-next-stream-line-equal _test-output-stream "$f:0x00000001:loop:" "F - test-convert-function-call-with-arg-of-user-defined-type/5") - 5232 # var a - 5233 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-function-call-with-arg-of-user-defined-type/6") - 5234 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-function-call-with-arg-of-user-defined-type/7") - 5235 # foo a - 5236 (check-next-stream-line-equal _test-output-stream " (foo *(eax+0x00000000) *(eax+0x00000004))" "F - test-convert-function-call-with-arg-of-user-defined-type/8") - 5237 # - 5238 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-function-call-with-arg-of-user-defined-type/9") - 5239 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call-with-arg-of-user-defined-type/10") - 5240 (check-next-stream-line-equal _test-output-stream "$f:0x00000001:break:" "F - test-convert-function-call-with-arg-of-user-defined-type/11") - 5241 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-arg-of-user-defined-type/12") - 5242 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/13") - 5243 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/14") - 5244 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-arg-of-user-defined-type/15") - 5245 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-call-with-arg-of-user-defined-type/16") - 5246 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-arg-of-user-defined-type/17") - 5247 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/18") - 5248 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call-with-arg-of-user-defined-type/19") - 5249 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-arg-of-user-defined-type/20") - 5250 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/21") - 5251 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/22") - 5252 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-arg-of-user-defined-type/23") - 5253 # . epilogue - 5254 89/<- %esp 5/r32/ebp - 5255 5d/pop-to-ebp - 5256 c3/return - 5257 - 5258 # we don't have special support for call-by-reference; just explicitly create - 5259 # a new variable with the address of the arg - 5260 test-convert-function-call-with-arg-of-user-defined-type-by-reference: - 5261 # . prologue - 5262 55/push-ebp - 5263 89/<- %ebp 4/r32/esp - 5264 # setup - 5265 (clear-stream _test-input-stream) - 5266 (clear-stream $_test-input-buffered-file->buffer) - 5267 (clear-stream _test-output-stream) - 5268 (clear-stream $_test-output-buffered-file->buffer) - 5269 # - 5270 (write _test-input-stream "fn f {\n") - 5271 (write _test-input-stream " var a: t\n") - 5272 (write _test-input-stream " var b/eax: (addr t) <- address a\n") - 5273 (write _test-input-stream " foo b\n") - 5274 (write _test-input-stream "}\n") - 5275 (write _test-input-stream "fn foo x: (addr t) {\n") - 5276 (write _test-input-stream " var x/ecx: (addr int) <- copy x\n") - 5277 (write _test-input-stream " increment *x\n") - 5278 (write _test-input-stream "}\n") - 5279 (write _test-input-stream "type t {\n") - 5280 (write _test-input-stream " x: int\n") - 5281 (write _test-input-stream " y: int\n") - 5282 (write _test-input-stream "}\n") - 5283 # convert - 5284 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 5285 (flush _test-output-buffered-file) - 5286 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 5292 # check output - 5293 (check-next-stream-line-equal _test-output-stream "f:" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/0") - 5294 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/1") - 5295 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/2") - 5296 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/3") - 5297 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/4") - 5298 (check-next-stream-line-equal _test-output-stream "$f:0x00000001:loop:" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/5") - 5299 # var a: t - 5300 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/6") - 5301 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/7") - 5302 # var b/eax: (addr t) - 5303 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/8") - 5304 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(ebp+0xfffffff8) 0x00000000/r32" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/9") - 5305 # foo a - 5306 (check-next-stream-line-equal _test-output-stream " (foo %eax)" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/10") - 5307 # - 5308 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/11") - 5309 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000008/imm32" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/12") - 5310 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/13") - 5311 (check-next-stream-line-equal _test-output-stream "$f:0x00000001:break:" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/14") - 5312 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/15") - 5313 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/16") - 5314 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/17") - 5315 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/18") - 5316 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/19") - 5317 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/20") - 5318 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/21") - 5319 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/22") - 5320 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/23") - 5321 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/24") - 5322 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/25") - 5323 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x00000008) 0x00000001/r32" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/26") - 5324 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *ecx" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/27") - 5325 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/28") - 5326 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/29") - 5327 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/30") - 5328 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/31") - 5329 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/32") - 5330 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/33") - 5331 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/34") - 5332 # . epilogue - 5333 89/<- %esp 5/r32/ebp - 5334 5d/pop-to-ebp - 5335 c3/return - 5336 - 5337 test-convert-get-on-local-variable: - 5338 # . prologue - 5339 55/push-ebp - 5340 89/<- %ebp 4/r32/esp - 5341 # setup - 5342 (clear-stream _test-input-stream) - 5343 (clear-stream $_test-input-buffered-file->buffer) - 5344 (clear-stream _test-output-stream) - 5345 (clear-stream $_test-output-buffered-file->buffer) - 5346 # - 5347 (write _test-input-stream "fn foo {\n") - 5348 (write _test-input-stream " var a: t\n") - 5349 (write _test-input-stream " var c/ecx: (addr int) <- get a, y\n") - 5350 (write _test-input-stream "}\n") - 5351 (write _test-input-stream "type t {\n") - 5352 (write _test-input-stream " x: int\n") - 5353 (write _test-input-stream " y: int\n") - 5354 (write _test-input-stream "}\n") - 5355 # convert - 5356 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 5357 (flush _test-output-buffered-file) - 5358 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 5364 # check output - 5365 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-get-on-local-variable/0") - 5366 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-get-on-local-variable/1") - 5367 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-get-on-local-variable/2") - 5368 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-get-on-local-variable/3") - 5369 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-get-on-local-variable/4") - 5370 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-get-on-local-variable/5") - 5371 # var a - 5372 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-get-on-local-variable/6") - 5373 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-get-on-local-variable/7") - 5374 # var c - 5375 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-get-on-local-variable/8") - 5376 # get - 5377 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(ebp+0xfffffffc) 0x00000001/r32" "F - test-convert-get-on-local-variable/9") - 5378 # reclaim c - 5379 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-get-on-local-variable/10") - 5380 # reclaim a - 5381 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000008/imm32" "F - test-convert-get-on-local-variable/11") - 5382 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-get-on-local-variable/12") - 5383 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-get-on-local-variable/13") - 5384 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-get-on-local-variable/14") - 5385 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-get-on-local-variable/15") - 5386 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-get-on-local-variable/16") - 5387 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-get-on-local-variable/17") - 5388 # . epilogue - 5389 89/<- %esp 5/r32/ebp - 5390 5d/pop-to-ebp - 5391 c3/return - 5392 - 5393 test-convert-get-on-function-argument: - 5394 # . prologue - 5395 55/push-ebp - 5396 89/<- %ebp 4/r32/esp - 5397 # setup - 5398 (clear-stream _test-input-stream) - 5399 (clear-stream $_test-input-buffered-file->buffer) - 5400 (clear-stream _test-output-stream) - 5401 (clear-stream $_test-output-buffered-file->buffer) - 5402 # - 5403 (write _test-input-stream "fn foo a: t {\n") - 5404 (write _test-input-stream " var c/ecx: (addr int) <- get a, y\n") - 5405 (write _test-input-stream "}\n") - 5406 (write _test-input-stream "type t {\n") - 5407 (write _test-input-stream " x: int\n") - 5408 (write _test-input-stream " y: int\n") - 5409 (write _test-input-stream "}\n") - 5410 # convert - 5411 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 5412 (flush _test-output-buffered-file) - 5413 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 5419 # check output - 5420 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-get-on-function-argument/0") - 5421 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-get-on-function-argument/1") - 5422 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-get-on-function-argument/2") - 5423 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-get-on-function-argument/3") - 5424 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-get-on-function-argument/4") - 5425 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-get-on-function-argument/5") - 5426 # var c - 5427 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-get-on-function-argument/6") - 5428 # get - 5429 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(ebp+0x0000000c) 0x00000001/r32" "F - test-convert-get-on-function-argument/7") - 5430 # reclaim c - 5431 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-get-on-function-argument/8") - 5432 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-get-on-function-argument/9") - 5433 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-get-on-function-argument/10") - 5434 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-get-on-function-argument/11") - 5435 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-get-on-function-argument/12") - 5436 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-get-on-function-argument/13") - 5437 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-get-on-function-argument/14") - 5438 # . epilogue - 5439 89/<- %esp 5/r32/ebp - 5440 5d/pop-to-ebp - 5441 c3/return - 5442 - 5443 test-convert-get-on-function-argument-with-known-type: - 5444 # . prologue - 5445 55/push-ebp - 5446 89/<- %ebp 4/r32/esp - 5447 # setup - 5448 (clear-stream _test-input-stream) - 5449 (clear-stream $_test-input-buffered-file->buffer) - 5450 (clear-stream _test-output-stream) - 5451 (clear-stream $_test-output-buffered-file->buffer) - 5452 # - 5453 (write _test-input-stream "type t {\n") - 5454 (write _test-input-stream " x: int\n") - 5455 (write _test-input-stream " y: int\n") - 5456 (write _test-input-stream "}\n") - 5457 (write _test-input-stream "fn foo a: t {\n") - 5458 (write _test-input-stream " var c/ecx: (addr int) <- get a, y\n") - 5459 (write _test-input-stream "}\n") - 5460 # convert - 5461 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 5462 (flush _test-output-buffered-file) - 5463 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 5469 # check output - 5470 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-get-on-function-argument-with-known-type/0") - 5471 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-get-on-function-argument-with-known-type/1") - 5472 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-get-on-function-argument-with-known-type/2") - 5473 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-get-on-function-argument-with-known-type/3") - 5474 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-get-on-function-argument-with-known-type/4") - 5475 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-get-on-function-argument-with-known-type/5") - 5476 # var c - 5477 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-get-on-function-argument-with-known-type/6") - 5478 # get - 5479 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(ebp+0x0000000c) 0x00000001/r32" "F - test-convert-get-on-function-argument-with-known-type/7") - 5480 # reclaim c - 5481 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-get-on-function-argument-with-known-type/8") - 5482 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-get-on-function-argument-with-known-type/9") - 5483 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-get-on-function-argument-with-known-type/10") - 5484 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-get-on-function-argument-with-known-type/11") - 5485 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-get-on-function-argument-with-known-type/12") - 5486 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-get-on-function-argument-with-known-type/13") - 5487 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-get-on-function-argument-with-known-type/14") - 5488 # . epilogue - 5489 89/<- %esp 5/r32/ebp - 5490 5d/pop-to-ebp - 5491 c3/return - 5492 - 5493 test-add-with-too-many-inouts: - 5494 # . prologue - 5495 55/push-ebp - 5496 89/<- %ebp 4/r32/esp - 5497 # setup - 5498 (clear-stream _test-input-stream) - 5499 (clear-stream $_test-input-buffered-file->buffer) - 5500 (clear-stream _test-output-stream) - 5501 (clear-stream $_test-output-buffered-file->buffer) - 5502 (clear-stream _test-error-stream) - 5503 (clear-stream $_test-error-buffered-file->buffer) - 5504 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 5505 68/push 0/imm32 - 5506 68/push 0/imm32 - 5507 89/<- %edx 4/r32/esp - 5508 (tailor-exit-descriptor %edx 0x10) - 5509 # - 5510 (write _test-input-stream "fn foo {\n") - 5511 (write _test-input-stream " var a: int\n") - 5512 (write _test-input-stream " var b/ecx: int <- add a, 0\n") - 5513 (write _test-input-stream "}\n") - 5514 # convert - 5515 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 5516 # registers except esp clobbered at this point - 5517 # restore ed - 5518 89/<- %edx 4/r32/esp - 5519 (flush _test-output-buffered-file) - 5520 (flush _test-error-buffered-file) - 5521 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 5527 # check output - 5528 (check-stream-equal _test-output-stream "" "F - test-add-with-too-many-inouts: output should be empty") - 5529 (check-next-stream-line-equal _test-error-stream "fn foo: stmt add: too many inouts; most primitives support at most two arguments, across inouts and outputs" "F - test-add-with-too-many-inouts: error message") - 5530 # check that stop(1) was called - 5531 (check-ints-equal *(edx+4) 2 "F - test-add-with-too-many-inouts: exit status") - 5532 # don't restore from ebp - 5533 81 0/subop/add %esp 8/imm32 - 5534 # . epilogue - 5535 5d/pop-to-ebp - 5536 c3/return - 5537 - 5538 test-add-with-too-many-inouts-2: - 5539 # . prologue - 5540 55/push-ebp - 5541 89/<- %ebp 4/r32/esp - 5542 # setup - 5543 (clear-stream _test-input-stream) - 5544 (clear-stream $_test-input-buffered-file->buffer) - 5545 (clear-stream _test-output-stream) - 5546 (clear-stream $_test-output-buffered-file->buffer) - 5547 (clear-stream _test-error-stream) - 5548 (clear-stream $_test-error-buffered-file->buffer) - 5549 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 5550 68/push 0/imm32 - 5551 68/push 0/imm32 - 5552 89/<- %edx 4/r32/esp - 5553 (tailor-exit-descriptor %edx 0x10) - 5554 # - 5555 (write _test-input-stream "fn foo {\n") - 5556 (write _test-input-stream " var a: int\n") - 5557 (write _test-input-stream " add-to a, 0, 1\n") - 5558 (write _test-input-stream "}\n") - 5559 # convert - 5560 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 5561 # registers except esp clobbered at this point - 5562 # restore ed - 5563 89/<- %edx 4/r32/esp - 5564 (flush _test-output-buffered-file) - 5565 (flush _test-error-buffered-file) - 5566 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 5572 # check output - 5573 (check-stream-equal _test-output-stream "" "F - test-add-with-too-many-inouts-2: output should be empty") - 5574 (check-next-stream-line-equal _test-error-stream "fn foo: stmt add-to: too many inouts; most primitives support at most two arguments, across inouts and outputs" "F - test-add-with-too-many-inouts-2: error message") - 5575 # check that stop(1) was called - 5576 (check-ints-equal *(edx+4) 2 "F - test-add-with-too-many-inouts-2: exit status") - 5577 # don't restore from ebp - 5578 81 0/subop/add %esp 8/imm32 - 5579 # . epilogue - 5580 5d/pop-to-ebp - 5581 c3/return - 5582 - 5583 test-add-with-too-many-outputs: - 5584 # . prologue - 5585 55/push-ebp - 5586 89/<- %ebp 4/r32/esp - 5587 # setup - 5588 (clear-stream _test-input-stream) - 5589 (clear-stream $_test-input-buffered-file->buffer) - 5590 (clear-stream _test-output-stream) - 5591 (clear-stream $_test-output-buffered-file->buffer) - 5592 (clear-stream _test-error-stream) - 5593 (clear-stream $_test-error-buffered-file->buffer) - 5594 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 5595 68/push 0/imm32 - 5596 68/push 0/imm32 - 5597 89/<- %edx 4/r32/esp - 5598 (tailor-exit-descriptor %edx 0x10) - 5599 # - 5600 (write _test-input-stream "fn foo {\n") - 5601 (write _test-input-stream " var a/eax: int <- copy 0\n") - 5602 (write _test-input-stream " var b/ebx: int <- copy 0\n") - 5603 (write _test-input-stream " var c/ecx: int <- copy 0\n") - 5604 (write _test-input-stream " c, b <- add a\n") - 5605 (write _test-input-stream "}\n") - 5606 # convert - 5607 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 5608 # registers except esp clobbered at this point - 5609 # restore ed - 5610 89/<- %edx 4/r32/esp - 5611 (flush _test-output-buffered-file) - 5612 (flush _test-error-buffered-file) - 5613 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 5619 # check output - 5620 (check-stream-equal _test-output-stream "" "F - test-add-with-too-many-outputs: output should be empty") - 5621 (check-next-stream-line-equal _test-error-stream "fn foo: stmt add: too many outputs; most primitives support at most one output" "F - test-add-with-too-many-outputs: error message") - 5622 # check that stop(1) was called - 5623 (check-ints-equal *(edx+4) 2 "F - test-add-with-too-many-outputs: exit status") - 5624 # don't restore from ebp - 5625 81 0/subop/add %esp 8/imm32 - 5626 # . epilogue - 5627 5d/pop-to-ebp - 5628 c3/return - 5629 - 5630 test-add-with-non-number: - 5631 # . prologue - 5632 55/push-ebp - 5633 89/<- %ebp 4/r32/esp - 5634 # setup - 5635 (clear-stream _test-input-stream) - 5636 (clear-stream $_test-input-buffered-file->buffer) - 5637 (clear-stream _test-output-stream) - 5638 (clear-stream $_test-output-buffered-file->buffer) - 5639 (clear-stream _test-error-stream) - 5640 (clear-stream $_test-error-buffered-file->buffer) - 5641 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 5642 68/push 0/imm32 - 5643 68/push 0/imm32 - 5644 89/<- %edx 4/r32/esp - 5645 (tailor-exit-descriptor %edx 0x10) - 5646 # - 5647 (write _test-input-stream "fn foo {\n") - 5648 (write _test-input-stream " var a: int\n") - 5649 (write _test-input-stream " var b/ecx: (addr int) <- add a\n") - 5650 (write _test-input-stream "}\n") - 5651 # convert - 5652 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 5653 # registers except esp clobbered at this point - 5654 # restore ed - 5655 89/<- %edx 4/r32/esp - 5656 (flush _test-output-buffered-file) - 5657 (flush _test-error-buffered-file) - 5658 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 5664 # check output - 5665 (check-stream-equal _test-output-stream "" "F - test-add-with-non-number: output should be empty") - 5666 (check-next-stream-line-equal _test-error-stream "fn foo: stmt add: only non-addr scalar args permitted" "F - test-add-with-non-number: error message") - 5667 # check that stop(1) was called - 5668 (check-ints-equal *(edx+4) 2 "F - test-add-with-non-number: exit status") - 5669 # don't restore from ebp - 5670 81 0/subop/add %esp 8/imm32 - 5671 # . epilogue - 5672 5d/pop-to-ebp - 5673 c3/return - 5674 - 5675 test-add-with-addr-dereferenced: - 5676 # . prologue - 5677 55/push-ebp - 5678 89/<- %ebp 4/r32/esp - 5679 # setup - 5680 (clear-stream _test-input-stream) - 5681 (clear-stream $_test-input-buffered-file->buffer) - 5682 (clear-stream _test-output-stream) - 5683 (clear-stream $_test-output-buffered-file->buffer) - 5684 # - 5685 (write _test-input-stream "fn foo {\n") - 5686 (write _test-input-stream " var a/eax: (addr int) <- copy 0\n") - 5687 (write _test-input-stream " add-to *a, 1\n") - 5688 (write _test-input-stream "}\n") - 5689 # convert - 5690 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 5691 (flush _test-output-buffered-file) - 5692 # no error - 5693 # . epilogue - 5694 89/<- %esp 5/r32/ebp - 5695 5d/pop-to-ebp - 5696 c3/return - 5697 - 5698 test-get-with-wrong-field: - 5699 # . prologue - 5700 55/push-ebp - 5701 89/<- %ebp 4/r32/esp - 5702 # setup - 5703 (clear-stream _test-input-stream) - 5704 (clear-stream $_test-input-buffered-file->buffer) - 5705 (clear-stream _test-output-stream) - 5706 (clear-stream $_test-output-buffered-file->buffer) - 5707 (clear-stream _test-error-stream) - 5708 (clear-stream $_test-error-buffered-file->buffer) - 5709 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 5710 68/push 0/imm32 - 5711 68/push 0/imm32 - 5712 89/<- %edx 4/r32/esp - 5713 (tailor-exit-descriptor %edx 0x10) - 5714 # - 5715 (write _test-input-stream "fn foo {\n") - 5716 (write _test-input-stream " var a: t\n") - 5717 (write _test-input-stream " var c/ecx: (addr int) <- get a, y\n") - 5718 (write _test-input-stream "}\n") - 5719 (write _test-input-stream "type t {\n") - 5720 (write _test-input-stream " x: int\n") - 5721 (write _test-input-stream "}\n") - 5722 # convert - 5723 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 5724 # registers except esp clobbered at this point - 5725 # restore ed - 5726 89/<- %edx 4/r32/esp - 5727 (flush _test-output-buffered-file) - 5728 (flush _test-error-buffered-file) - 5729 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 5735 # check output - 5736 (check-stream-equal _test-output-stream "" "F - test-get-with-wrong-field: output should be empty") - 5737 (check-next-stream-line-equal _test-error-stream "fn foo: stmt get: type 't' has no member called 'y'" "F - test-get-with-wrong-field: error message") - 5738 # check that stop(1) was called - 5739 (check-ints-equal *(edx+4) 2 "F - test-get-with-wrong-field: exit status") - 5740 # don't restore from ebp - 5741 81 0/subop/add %esp 8/imm32 - 5742 # . epilogue - 5743 5d/pop-to-ebp - 5744 c3/return - 5745 - 5746 test-get-with-wrong-base-type: - 5747 # . prologue - 5748 55/push-ebp - 5749 89/<- %ebp 4/r32/esp - 5750 # setup - 5751 (clear-stream _test-input-stream) - 5752 (clear-stream $_test-input-buffered-file->buffer) - 5753 (clear-stream _test-output-stream) - 5754 (clear-stream $_test-output-buffered-file->buffer) - 5755 (clear-stream _test-error-stream) - 5756 (clear-stream $_test-error-buffered-file->buffer) - 5757 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 5758 68/push 0/imm32 - 5759 68/push 0/imm32 - 5760 89/<- %edx 4/r32/esp - 5761 (tailor-exit-descriptor %edx 0x10) - 5762 # - 5763 (write _test-input-stream "fn foo {\n") - 5764 (write _test-input-stream " var a: int\n") - 5765 (write _test-input-stream " var c/ecx: (addr int) <- get a, y\n") - 5766 (write _test-input-stream "}\n") - 5767 # convert - 5768 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 5769 # registers except esp clobbered at this point - 5770 # restore ed - 5771 89/<- %edx 4/r32/esp - 5772 (flush _test-output-buffered-file) - 5773 (flush _test-error-buffered-file) - 5774 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 5780 # check output - 5781 (check-stream-equal _test-output-stream "" "F - test-get-with-wrong-base-type: output should be empty") - 5782 (check-next-stream-line-equal _test-error-stream "fn foo: stmt get: var 'a' must have a 'type' definition" "F - test-get-with-wrong-base-type: error message") - 5783 # check that stop(1) was called - 5784 (check-ints-equal *(edx+4) 2 "F - test-get-with-wrong-base-type: exit status") - 5785 # don't restore from ebp - 5786 81 0/subop/add %esp 8/imm32 - 5787 # . epilogue - 5788 5d/pop-to-ebp - 5789 c3/return - 5790 - 5791 test-get-with-wrong-base-type-2: - 5792 # . prologue - 5793 55/push-ebp - 5794 89/<- %ebp 4/r32/esp - 5795 # setup - 5796 (clear-stream _test-input-stream) - 5797 (clear-stream $_test-input-buffered-file->buffer) - 5798 (clear-stream _test-output-stream) - 5799 (clear-stream $_test-output-buffered-file->buffer) - 5800 (clear-stream _test-error-stream) - 5801 (clear-stream $_test-error-buffered-file->buffer) - 5802 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 5803 68/push 0/imm32 - 5804 68/push 0/imm32 - 5805 89/<- %edx 4/r32/esp - 5806 (tailor-exit-descriptor %edx 0x10) - 5807 # - 5808 (write _test-input-stream "fn foo {\n") - 5809 (write _test-input-stream " var a: (addr t)\n") - 5810 (write _test-input-stream " var c/ecx: (addr int) <- get a, y\n") - 5811 (write _test-input-stream "}\n") - 5812 (write _test-input-stream "type t {\n") - 5813 (write _test-input-stream " x: int\n") - 5814 (write _test-input-stream "}\n") - 5815 # convert - 5816 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 5817 # registers except esp clobbered at this point - 5818 # restore ed - 5819 89/<- %edx 4/r32/esp - 5820 (flush _test-output-buffered-file) - 5821 (flush _test-error-buffered-file) - 5822 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 5828 # check output - 5829 (check-stream-equal _test-output-stream "" "F - test-get-with-wrong-base-type-2: output should be empty") - 5830 (check-next-stream-line-equal _test-error-stream "fn foo: stmt get: var 'a' is an 'addr' type, and so must live in a register" "F - test-get-with-wrong-base-type-2: error message") - 5831 # check that stop(1) was called - 5832 (check-ints-equal *(edx+4) 2 "F - test-get-with-wrong-base-type-2: exit status") - 5833 # don't restore from ebp - 5834 81 0/subop/add %esp 8/imm32 - 5835 # . epilogue - 5836 5d/pop-to-ebp - 5837 c3/return - 5838 - 5839 test-get-with-wrong-offset-type: - 5840 # . prologue - 5841 55/push-ebp - 5842 89/<- %ebp 4/r32/esp - 5843 # setup - 5844 (clear-stream _test-input-stream) - 5845 (clear-stream $_test-input-buffered-file->buffer) - 5846 (clear-stream _test-output-stream) - 5847 (clear-stream $_test-output-buffered-file->buffer) - 5848 (clear-stream _test-error-stream) - 5849 (clear-stream $_test-error-buffered-file->buffer) - 5850 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 5851 68/push 0/imm32 - 5852 68/push 0/imm32 - 5853 89/<- %edx 4/r32/esp - 5854 (tailor-exit-descriptor %edx 0x10) - 5855 # - 5856 (write _test-input-stream "fn foo {\n") - 5857 (write _test-input-stream " var a: t\n") - 5858 (write _test-input-stream " var b: int\n") - 5859 (write _test-input-stream " var c/ecx: (addr int) <- get a, b\n") - 5860 (write _test-input-stream "}\n") - 5861 (write _test-input-stream "type t {\n") - 5862 (write _test-input-stream " x: int\n") - 5863 (write _test-input-stream "}\n") - 5864 # convert - 5865 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 5866 # registers except esp clobbered at this point - 5867 # restore ed - 5868 89/<- %edx 4/r32/esp - 5869 (flush _test-output-buffered-file) - 5870 (flush _test-error-buffered-file) - 5871 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 5877 # check output - 5878 (check-stream-equal _test-output-stream "" "F - test-get-with-wrong-offset-type: output should be empty") - 5879 (check-next-stream-line-equal _test-error-stream "fn foo: stmt get: type 't' has no member called 'b'" "F - test-get-with-wrong-offset-type: error message") - 5880 # check that stop(1) was called - 5881 (check-ints-equal *(edx+4) 2 "F - test-get-with-wrong-offset-type: exit status") - 5882 # don't restore from ebp - 5883 81 0/subop/add %esp 8/imm32 - 5884 # . epilogue - 5885 5d/pop-to-ebp - 5886 c3/return - 5887 - 5888 test-get-with-wrong-output-type: - 5889 # . prologue - 5890 55/push-ebp - 5891 89/<- %ebp 4/r32/esp - 5892 # setup - 5893 (clear-stream _test-input-stream) - 5894 (clear-stream $_test-input-buffered-file->buffer) - 5895 (clear-stream _test-output-stream) - 5896 (clear-stream $_test-output-buffered-file->buffer) - 5897 (clear-stream _test-error-stream) - 5898 (clear-stream $_test-error-buffered-file->buffer) - 5899 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 5900 68/push 0/imm32 - 5901 68/push 0/imm32 - 5902 89/<- %edx 4/r32/esp - 5903 (tailor-exit-descriptor %edx 0x10) - 5904 # - 5905 (write _test-input-stream "fn foo {\n") - 5906 (write _test-input-stream " var a: t\n") - 5907 (write _test-input-stream " var c: (addr int)\n") - 5908 (write _test-input-stream " c <- get a, x\n") - 5909 (write _test-input-stream "}\n") - 5910 (write _test-input-stream "type t {\n") - 5911 (write _test-input-stream " x: int\n") - 5912 (write _test-input-stream "}\n") - 5913 # convert - 5914 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 5915 # registers except esp clobbered at this point - 5916 # restore ed - 5917 89/<- %edx 4/r32/esp - 5918 (flush _test-output-buffered-file) - 5919 (flush _test-error-buffered-file) - 5920 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 5926 # check output - 5927 (check-stream-equal _test-output-stream "" "F - test-get-with-wrong-output-type: output should be empty") - 5928 (check-next-stream-line-equal _test-error-stream "fn foo: stmt get: output 'c' is not in a register" "F - test-get-with-wrong-output-type: error message") - 5929 # check that stop(1) was called - 5930 (check-ints-equal *(edx+4) 2 "F - test-get-with-wrong-output-type: exit status") - 5931 # don't restore from ebp - 5932 81 0/subop/add %esp 8/imm32 - 5933 # . epilogue - 5934 5d/pop-to-ebp - 5935 c3/return - 5936 - 5937 test-get-with-wrong-output-type-2: - 5938 # . prologue - 5939 55/push-ebp - 5940 89/<- %ebp 4/r32/esp - 5941 # setup - 5942 (clear-stream _test-input-stream) - 5943 (clear-stream $_test-input-buffered-file->buffer) - 5944 (clear-stream _test-output-stream) - 5945 (clear-stream $_test-output-buffered-file->buffer) - 5946 (clear-stream _test-error-stream) - 5947 (clear-stream $_test-error-buffered-file->buffer) - 5948 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 5949 68/push 0/imm32 - 5950 68/push 0/imm32 - 5951 89/<- %edx 4/r32/esp - 5952 (tailor-exit-descriptor %edx 0x10) - 5953 # - 5954 (write _test-input-stream "fn foo {\n") - 5955 (write _test-input-stream " var a: t\n") - 5956 (write _test-input-stream " var c/ecx: int <- get a, x\n") - 5957 (write _test-input-stream "}\n") - 5958 (write _test-input-stream "type t {\n") - 5959 (write _test-input-stream " x: int\n") - 5960 (write _test-input-stream "}\n") - 5961 # convert - 5962 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 5963 # registers except esp clobbered at this point - 5964 # restore ed - 5965 89/<- %edx 4/r32/esp - 5966 (flush _test-output-buffered-file) - 5967 (flush _test-error-buffered-file) - 5968 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 5974 # check output - 5975 (check-stream-equal _test-output-stream "" "F - test-get-with-wrong-output-type-2: output should be empty") - 5976 (check-next-stream-line-equal _test-error-stream "fn foo: stmt get: output must be an address" "F - test-get-with-wrong-output-type-2: error message") - 5977 # check that stop(1) was called - 5978 (check-ints-equal *(edx+4) 2 "F - test-get-with-wrong-output-type-2: exit status") - 5979 # don't restore from ebp - 5980 81 0/subop/add %esp 8/imm32 - 5981 # . epilogue - 5982 5d/pop-to-ebp - 5983 c3/return - 5984 - 5985 test-get-with-wrong-output-type-3: - 5986 # . prologue - 5987 55/push-ebp - 5988 89/<- %ebp 4/r32/esp - 5989 # setup - 5990 (clear-stream _test-input-stream) - 5991 (clear-stream $_test-input-buffered-file->buffer) - 5992 (clear-stream _test-output-stream) - 5993 (clear-stream $_test-output-buffered-file->buffer) - 5994 (clear-stream _test-error-stream) - 5995 (clear-stream $_test-error-buffered-file->buffer) - 5996 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 5997 68/push 0/imm32 - 5998 68/push 0/imm32 - 5999 89/<- %edx 4/r32/esp - 6000 (tailor-exit-descriptor %edx 0x10) - 6001 # - 6002 (write _test-input-stream "fn foo {\n") - 6003 (write _test-input-stream " var a: t\n") - 6004 (write _test-input-stream " var c/ecx: (array int) <- get a, x\n") - 6005 (write _test-input-stream "}\n") - 6006 (write _test-input-stream "type t {\n") - 6007 (write _test-input-stream " x: int\n") - 6008 (write _test-input-stream "}\n") - 6009 # convert - 6010 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 6011 # registers except esp clobbered at this point - 6012 # restore ed - 6013 89/<- %edx 4/r32/esp - 6014 (flush _test-output-buffered-file) - 6015 (flush _test-error-buffered-file) - 6016 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 6022 # check output - 6023 (check-stream-equal _test-output-stream "" "F - test-get-with-wrong-output-type-3: output should be empty") - 6024 (check-next-stream-line-equal _test-error-stream "fn foo: stmt get: output must be an address" "F - test-get-with-wrong-output-type-3: error message") - 6025 # check that stop(1) was called - 6026 (check-ints-equal *(edx+4) 2 "F - test-get-with-wrong-output-type-3: exit status") - 6027 # don't restore from ebp - 6028 81 0/subop/add %esp 8/imm32 - 6029 # . epilogue - 6030 5d/pop-to-ebp - 6031 c3/return - 6032 - 6033 test-get-with-wrong-output-type-4: - 6034 # . prologue - 6035 55/push-ebp - 6036 89/<- %ebp 4/r32/esp - 6037 # setup - 6038 (clear-stream _test-input-stream) - 6039 (clear-stream $_test-input-buffered-file->buffer) - 6040 (clear-stream _test-output-stream) - 6041 (clear-stream $_test-output-buffered-file->buffer) - 6042 (clear-stream _test-error-stream) - 6043 (clear-stream $_test-error-buffered-file->buffer) - 6044 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 6045 68/push 0/imm32 - 6046 68/push 0/imm32 - 6047 89/<- %edx 4/r32/esp - 6048 (tailor-exit-descriptor %edx 0x10) - 6049 # - 6050 (write _test-input-stream "fn foo {\n") - 6051 (write _test-input-stream " var a: t\n") - 6052 (write _test-input-stream " var c/ecx: (addr boolean) <- get a, x\n") - 6053 (write _test-input-stream "}\n") - 6054 (write _test-input-stream "type t {\n") - 6055 (write _test-input-stream " x: int\n") - 6056 (write _test-input-stream "}\n") - 6057 # convert - 6058 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 6059 # registers except esp clobbered at this point - 6060 # restore ed - 6061 89/<- %edx 4/r32/esp - 6062 (flush _test-output-buffered-file) - 6063 (flush _test-error-buffered-file) - 6064 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 6070 # check output - 6071 (check-stream-equal _test-output-stream "" "F - test-get-with-wrong-output-type-4: output should be empty") - 6072 (check-next-stream-line-equal _test-error-stream "fn foo: stmt get: wrong output type for member 'x' of type 't'" "F - test-get-with-wrong-output-type-4: error message") - 6073 # check that stop(1) was called - 6074 (check-ints-equal *(edx+4) 2 "F - test-get-with-wrong-output-type-4: exit status") - 6075 # don't restore from ebp - 6076 81 0/subop/add %esp 8/imm32 - 6077 # . epilogue - 6078 5d/pop-to-ebp - 6079 c3/return - 6080 - 6081 test-get-with-wrong-output-type-5: - 6082 # . prologue - 6083 55/push-ebp - 6084 89/<- %ebp 4/r32/esp - 6085 # setup - 6086 (clear-stream _test-input-stream) - 6087 (clear-stream $_test-input-buffered-file->buffer) - 6088 (clear-stream _test-output-stream) - 6089 (clear-stream $_test-output-buffered-file->buffer) - 6090 # - 6091 (write _test-input-stream "fn foo {\n") - 6092 (write _test-input-stream " var a: t\n") - 6093 (write _test-input-stream " var c/ecx: (addr handle int) <- get a, x\n") - 6094 (write _test-input-stream "}\n") - 6095 (write _test-input-stream "type t {\n") - 6096 (write _test-input-stream " x: (handle int)\n") - 6097 (write _test-input-stream "}\n") - 6098 # convert - 6099 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 6100 (flush _test-output-buffered-file) - 6101 # no errors - 6102 # . epilogue - 6103 89/<- %esp 5/r32/ebp - 6104 5d/pop-to-ebp - 6105 c3/return - 6106 - 6107 test-get-with-too-few-inouts: - 6108 # . prologue - 6109 55/push-ebp - 6110 89/<- %ebp 4/r32/esp - 6111 # setup - 6112 (clear-stream _test-input-stream) - 6113 (clear-stream $_test-input-buffered-file->buffer) - 6114 (clear-stream _test-output-stream) - 6115 (clear-stream $_test-output-buffered-file->buffer) - 6116 (clear-stream _test-error-stream) - 6117 (clear-stream $_test-error-buffered-file->buffer) - 6118 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 6119 68/push 0/imm32 - 6120 68/push 0/imm32 - 6121 89/<- %edx 4/r32/esp - 6122 (tailor-exit-descriptor %edx 0x10) - 6123 # - 6124 (write _test-input-stream "fn foo {\n") - 6125 (write _test-input-stream " var a: t\n") - 6126 (write _test-input-stream " var c/ecx: (addr int) <- get a\n") - 6127 (write _test-input-stream "}\n") - 6128 (write _test-input-stream "type t {\n") - 6129 (write _test-input-stream " x: int\n") - 6130 (write _test-input-stream "}\n") - 6131 # convert - 6132 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 6133 # registers except esp clobbered at this point - 6134 # restore ed - 6135 89/<- %edx 4/r32/esp - 6136 (flush _test-output-buffered-file) - 6137 (flush _test-error-buffered-file) - 6138 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 6144 # check output - 6145 (check-stream-equal _test-output-stream "" "F - test-get-with-too-few-inouts: output should be empty") - 6146 (check-next-stream-line-equal _test-error-stream "fn foo: stmt get: too few inouts (2 required)" "F - test-get-with-too-few-inouts: error message") - 6147 # check that stop(1) was called - 6148 (check-ints-equal *(edx+4) 2 "F - test-get-with-too-few-inouts: exit status") - 6149 # don't restore from ebp - 6150 81 0/subop/add %esp 8/imm32 - 6151 # . epilogue - 6152 5d/pop-to-ebp - 6153 c3/return - 6154 - 6155 test-get-with-too-many-inouts: - 6156 # . prologue - 6157 55/push-ebp - 6158 89/<- %ebp 4/r32/esp - 6159 # setup - 6160 (clear-stream _test-input-stream) - 6161 (clear-stream $_test-input-buffered-file->buffer) - 6162 (clear-stream _test-output-stream) - 6163 (clear-stream $_test-output-buffered-file->buffer) - 6164 (clear-stream _test-error-stream) - 6165 (clear-stream $_test-error-buffered-file->buffer) - 6166 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 6167 68/push 0/imm32 - 6168 68/push 0/imm32 - 6169 89/<- %edx 4/r32/esp - 6170 (tailor-exit-descriptor %edx 0x10) - 6171 # - 6172 (write _test-input-stream "fn foo {\n") - 6173 (write _test-input-stream " var a: t\n") - 6174 (write _test-input-stream " var c/ecx: (addr int) <- get a, x, 0\n") - 6175 (write _test-input-stream "}\n") - 6176 (write _test-input-stream "type t {\n") - 6177 (write _test-input-stream " x: int\n") - 6178 (write _test-input-stream "}\n") - 6179 # convert - 6180 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 6181 # registers except esp clobbered at this point - 6182 # restore ed - 6183 89/<- %edx 4/r32/esp - 6184 (flush _test-output-buffered-file) - 6185 (flush _test-error-buffered-file) - 6186 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 6192 # check output - 6193 (check-stream-equal _test-output-stream "" "F - test-get-with-too-many-inouts: output should be empty") - 6194 (check-next-stream-line-equal _test-error-stream "fn foo: stmt get: too many inouts (2 required)" "F - test-get-with-too-many-inouts: error message") - 6195 # check that stop(1) was called - 6196 (check-ints-equal *(edx+4) 2 "F - test-get-with-too-many-inouts: exit status") - 6197 # don't restore from ebp - 6198 81 0/subop/add %esp 8/imm32 - 6199 # . epilogue - 6200 5d/pop-to-ebp - 6201 c3/return - 6202 - 6203 test-get-with-no-output: - 6204 # . prologue - 6205 55/push-ebp - 6206 89/<- %ebp 4/r32/esp - 6207 # setup - 6208 (clear-stream _test-input-stream) - 6209 (clear-stream $_test-input-buffered-file->buffer) - 6210 (clear-stream _test-output-stream) - 6211 (clear-stream $_test-output-buffered-file->buffer) - 6212 (clear-stream _test-error-stream) - 6213 (clear-stream $_test-error-buffered-file->buffer) - 6214 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 6215 68/push 0/imm32 - 6216 68/push 0/imm32 - 6217 89/<- %edx 4/r32/esp - 6218 (tailor-exit-descriptor %edx 0x10) - 6219 # - 6220 (write _test-input-stream "fn foo {\n") - 6221 (write _test-input-stream " var a: t\n") - 6222 (write _test-input-stream " get a, x\n") - 6223 (write _test-input-stream "}\n") - 6224 (write _test-input-stream "type t {\n") - 6225 (write _test-input-stream " x: int\n") - 6226 (write _test-input-stream "}\n") - 6227 # convert - 6228 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 6229 # registers except esp clobbered at this point - 6230 # restore ed - 6231 89/<- %edx 4/r32/esp - 6232 (flush _test-output-buffered-file) - 6233 (flush _test-error-buffered-file) - 6234 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 6240 # check output - 6241 (check-stream-equal _test-output-stream "" "F - test-get-with-no-output: output should be empty") - 6242 (check-next-stream-line-equal _test-error-stream "fn foo: stmt get: must have an output" "F - test-get-with-no-output: error message") - 6243 # check that stop(1) was called - 6244 (check-ints-equal *(edx+4) 2 "F - test-get-with-no-output: exit status") - 6245 # don't restore from ebp - 6246 81 0/subop/add %esp 8/imm32 - 6247 # . epilogue - 6248 5d/pop-to-ebp - 6249 c3/return - 6250 - 6251 test-get-with-too-many-outputs: - 6252 # . prologue - 6253 55/push-ebp - 6254 89/<- %ebp 4/r32/esp - 6255 # setup - 6256 (clear-stream _test-input-stream) - 6257 (clear-stream $_test-input-buffered-file->buffer) - 6258 (clear-stream _test-output-stream) - 6259 (clear-stream $_test-output-buffered-file->buffer) - 6260 (clear-stream _test-error-stream) - 6261 (clear-stream $_test-error-buffered-file->buffer) - 6262 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 6263 68/push 0/imm32 - 6264 68/push 0/imm32 - 6265 89/<- %edx 4/r32/esp - 6266 (tailor-exit-descriptor %edx 0x10) - 6267 # - 6268 (write _test-input-stream "fn foo {\n") - 6269 (write _test-input-stream " var a: t\n") - 6270 (write _test-input-stream " var b: int\n") - 6271 (write _test-input-stream " var c/eax: (addr int) <- copy 0\n") - 6272 (write _test-input-stream " c, b <- get a, x\n") - 6273 (write _test-input-stream "}\n") - 6274 (write _test-input-stream "type t {\n") - 6275 (write _test-input-stream " x: int\n") - 6276 (write _test-input-stream "}\n") - 6277 # convert - 6278 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 6279 # registers except esp clobbered at this point - 6280 # restore ed - 6281 89/<- %edx 4/r32/esp - 6282 (flush _test-output-buffered-file) - 6283 (flush _test-error-buffered-file) - 6284 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 6290 # check output - 6291 (check-stream-equal _test-output-stream "" "F - test-get-with-too-many-outputs: output should be empty") - 6292 (check-next-stream-line-equal _test-error-stream "fn foo: stmt get: too many outputs (1 required)" "F - test-get-with-too-many-outputs: error message") - 6293 # check that stop(1) was called - 6294 (check-ints-equal *(edx+4) 2 "F - test-get-with-too-many-outputs: exit status") - 6295 # don't restore from ebp - 6296 81 0/subop/add %esp 8/imm32 - 6297 # . epilogue - 6298 5d/pop-to-ebp - 6299 c3/return - 6300 - 6301 test-convert-array-of-user-defined-types: - 6302 # . prologue - 6303 55/push-ebp - 6304 89/<- %ebp 4/r32/esp - 6305 # setup - 6306 (clear-stream _test-input-stream) - 6307 (clear-stream $_test-input-buffered-file->buffer) - 6308 (clear-stream _test-output-stream) - 6309 (clear-stream $_test-output-buffered-file->buffer) - 6310 # - 6311 (write _test-input-stream "type t {\n") # each t is 8 bytes, which is a power of 2 - 6312 (write _test-input-stream " x: int\n") - 6313 (write _test-input-stream " y: int\n") - 6314 (write _test-input-stream "}\n") - 6315 (write _test-input-stream "fn foo {\n") - 6316 (write _test-input-stream " var arr/eax: (addr array t) <- copy 0\n") - 6317 (write _test-input-stream " var idx/ecx: int <- copy 3\n") - 6318 (write _test-input-stream " var x/eax: (addr int) <- index arr, idx\n") - 6319 (write _test-input-stream "}\n") - 6320 # convert - 6321 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 6322 (flush _test-output-buffered-file) - 6323 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 6329 # check output - 6330 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-array-of-user-defined-types/0") - 6331 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-array-of-user-defined-types/1") - 6332 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-array-of-user-defined-types/2") - 6333 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-array-of-user-defined-types/3") - 6334 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-array-of-user-defined-types/4") - 6335 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-array-of-user-defined-types/5") - 6336 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-array-of-user-defined-types/6") - 6337 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-array-of-user-defined-types/7") - 6338 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-array-of-user-defined-types/8") - 6339 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-convert-array-of-user-defined-types/9") - 6340 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + ecx<<0x00000003 + 4) 0x00000000/r32" "F - test-convert-array-of-user-defined-types/11") - 6341 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-array-of-user-defined-types/13") - 6342 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-array-of-user-defined-types/14") - 6343 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-array-of-user-defined-types/15") - 6344 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-array-of-user-defined-types/16") - 6345 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-array-of-user-defined-types/17") - 6346 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-array-of-user-defined-types/18") - 6347 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-array-of-user-defined-types/19") - 6348 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-array-of-user-defined-types/20") - 6349 # . epilogue - 6350 89/<- %esp 5/r32/ebp - 6351 5d/pop-to-ebp - 6352 c3/return - 6353 - 6354 test-convert-length-of-array-of-user-defined-types-to-eax: - 6355 # . prologue - 6356 55/push-ebp - 6357 89/<- %ebp 4/r32/esp - 6358 # setup - 6359 (clear-stream _test-input-stream) - 6360 (clear-stream $_test-input-buffered-file->buffer) - 6361 (clear-stream _test-output-stream) - 6362 (clear-stream $_test-output-buffered-file->buffer) - 6363 # - 6364 (write _test-input-stream "type t {\n") # size = 12, which is not a power of 2 - 6365 (write _test-input-stream " x: int\n") - 6366 (write _test-input-stream " y: int\n") - 6367 (write _test-input-stream " z: int\n") - 6368 (write _test-input-stream "}\n") - 6369 (write _test-input-stream "fn foo {\n") - 6370 (write _test-input-stream " var arr/eax: (addr array t) <- copy 0\n") - 6371 (write _test-input-stream " var x/eax: (addr t) <- length arr\n") - 6372 (write _test-input-stream "}\n") - 6373 # convert - 6374 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 6375 (flush _test-output-buffered-file) - 6376 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 6382 # check output - 6383 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-length-of-array-of-user-defined-types-to-eax/0") - 6384 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-length-of-array-of-user-defined-types-to-eax/1") - 6385 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-length-of-array-of-user-defined-types-to-eax/2") - 6386 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-length-of-array-of-user-defined-types-to-eax/3") - 6387 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-length-of-array-of-user-defined-types-to-eax/4") - 6388 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-length-of-array-of-user-defined-types-to-eax/5") - 6389 # var arr - 6390 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-length-of-array-of-user-defined-types-to-eax/6") - 6391 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-length-of-array-of-user-defined-types-to-eax/7") - 6392 # length instruction - 6393 (check-next-stream-line-equal _test-output-stream " 51/push-ecx" "F - test-convert-length-of-array-of-user-defined-types-to-eax/8") - 6394 (check-next-stream-line-equal _test-output-stream " 52/push-edx" "F - test-convert-length-of-array-of-user-defined-types-to-eax/9") - 6395 (check-next-stream-line-equal _test-output-stream " 8b/-> *eax 0x00000000/r32" "F - test-convert-length-of-array-of-user-defined-types-to-eax/10") - 6396 (check-next-stream-line-equal _test-output-stream " 31/xor %edx 2/r32/edx" "F - test-convert-length-of-array-of-user-defined-types-to-eax/11") - 6397 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 0x0000000c/imm32" "F - test-convert-length-of-array-of-user-defined-types-to-eax/12") - 6398 (check-next-stream-line-equal _test-output-stream " f7 7/subop/idiv-eax-edx-by %ecx" "F - test-convert-length-of-array-of-user-defined-types-to-eax/13") - 6399 (check-next-stream-line-equal _test-output-stream " 5a/pop-to-edx" "F - test-convert-length-of-array-of-user-defined-types-to-eax/14") - 6400 (check-next-stream-line-equal _test-output-stream " 59/pop-to-ecx" "F - test-convert-length-of-array-of-user-defined-types-to-eax/15") - 6401 # reclaim arr - 6402 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-length-of-array-of-user-defined-types-to-eax/16") - 6403 # - 6404 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-length-of-array-of-user-defined-types-to-eax/17") - 6405 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-length-of-array-of-user-defined-types-to-eax/18") - 6406 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-length-of-array-of-user-defined-types-to-eax/19") - 6407 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-length-of-array-of-user-defined-types-to-eax/20") - 6408 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-length-of-array-of-user-defined-types-to-eax/21") - 6409 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-length-of-array-of-user-defined-types-to-eax/22") - 6410 # . epilogue - 6411 89/<- %esp 5/r32/ebp - 6412 5d/pop-to-ebp - 6413 c3/return - 6414 - 6415 test-convert-length-of-array-of-user-defined-types-to-ecx: - 6416 # . prologue - 6417 55/push-ebp - 6418 89/<- %ebp 4/r32/esp - 6419 # setup - 6420 (clear-stream _test-input-stream) - 6421 (clear-stream $_test-input-buffered-file->buffer) - 6422 (clear-stream _test-output-stream) - 6423 (clear-stream $_test-output-buffered-file->buffer) - 6424 # - 6425 (write _test-input-stream "type t {\n") # size = 12, which is not a power of 2 - 6426 (write _test-input-stream " x: int\n") - 6427 (write _test-input-stream " y: int\n") - 6428 (write _test-input-stream " z: int\n") - 6429 (write _test-input-stream "}\n") - 6430 (write _test-input-stream "fn foo {\n") - 6431 (write _test-input-stream " var arr/eax: (addr array t) <- copy 0\n") - 6432 (write _test-input-stream " var x/ecx: (addr t) <- length arr\n") - 6433 (write _test-input-stream "}\n") - 6434 # convert - 6435 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 6436 (flush _test-output-buffered-file) - 6437 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 6443 # check output - 6444 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/0") - 6445 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/1") - 6446 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/2") - 6447 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/3") - 6448 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/4") - 6449 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/5") - 6450 # var a - 6451 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/6") - 6452 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/7") - 6453 # var x - 6454 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/8") - 6455 # length instruction - 6456 (check-next-stream-line-equal _test-output-stream " 50/push-eax" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/9") - 6457 (check-next-stream-line-equal _test-output-stream " 52/push-edx" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/10") - 6458 (check-next-stream-line-equal _test-output-stream " 8b/-> *eax 0x00000000/r32" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/11") - 6459 (check-next-stream-line-equal _test-output-stream " 31/xor %edx 2/r32/edx" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/12") - 6460 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 0x0000000c/imm32" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/13") - 6461 (check-next-stream-line-equal _test-output-stream " f7 7/subop/idiv-eax-edx-by %ecx" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/14") - 6462 (check-next-stream-line-equal _test-output-stream " 89/<- %ecx 0/r32/eax" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/15") - 6463 (check-next-stream-line-equal _test-output-stream " 5a/pop-to-edx" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/16") - 6464 (check-next-stream-line-equal _test-output-stream " 58/pop-to-eax" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/17") - 6465 # reclaim x - 6466 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/18") - 6467 # reclaim a - 6468 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/19") - 6469 # - 6470 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/20") - 6471 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/21") - 6472 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/22") - 6473 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/23") - 6474 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/24") - 6475 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/25") - 6476 # . epilogue - 6477 89/<- %esp 5/r32/ebp - 6478 5d/pop-to-ebp - 6479 c3/return - 6480 - 6481 test-convert-length-of-array-of-user-defined-types-to-edx: - 6482 # . prologue - 6483 55/push-ebp - 6484 89/<- %ebp 4/r32/esp - 6485 # setup - 6486 (clear-stream _test-input-stream) - 6487 (clear-stream $_test-input-buffered-file->buffer) - 6488 (clear-stream _test-output-stream) - 6489 (clear-stream $_test-output-buffered-file->buffer) - 6490 # - 6491 (write _test-input-stream "type t {\n") # size = 12, which is not a power of 2 - 6492 (write _test-input-stream " x: int\n") - 6493 (write _test-input-stream " y: int\n") - 6494 (write _test-input-stream " z: int\n") - 6495 (write _test-input-stream "}\n") - 6496 (write _test-input-stream "fn foo {\n") - 6497 (write _test-input-stream " var arr/eax: (addr array t) <- copy 0\n") - 6498 (write _test-input-stream " var x/edx: (addr t) <- length arr\n") - 6499 (write _test-input-stream "}\n") - 6500 # convert - 6501 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 6502 (flush _test-output-buffered-file) - 6503 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 6509 # check output - 6510 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-length-of-array-of-user-defined-types-to-edx/0") - 6511 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-length-of-array-of-user-defined-types-to-edx/1") - 6512 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-length-of-array-of-user-defined-types-to-edx/2") - 6513 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-length-of-array-of-user-defined-types-to-edx/3") - 6514 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-length-of-array-of-user-defined-types-to-edx/4") - 6515 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-length-of-array-of-user-defined-types-to-edx/5") - 6516 # var a - 6517 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-length-of-array-of-user-defined-types-to-edx/6") - 6518 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-length-of-array-of-user-defined-types-to-edx/7") - 6519 # var x - 6520 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %edx" "F - test-convert-length-of-array-of-user-defined-types-to-edx/8") - 6521 # length instruction - 6522 (check-next-stream-line-equal _test-output-stream " 50/push-eax" "F - test-convert-length-of-array-of-user-defined-types-to-edx/9") - 6523 (check-next-stream-line-equal _test-output-stream " 51/push-ecx" "F - test-convert-length-of-array-of-user-defined-types-to-edx/10") - 6524 (check-next-stream-line-equal _test-output-stream " 8b/-> *eax 0x00000000/r32" "F - test-convert-length-of-array-of-user-defined-types-to-edx/11") - 6525 (check-next-stream-line-equal _test-output-stream " 31/xor %edx 2/r32/edx" "F - test-convert-length-of-array-of-user-defined-types-to-edx/12") - 6526 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 0x0000000c/imm32" "F - test-convert-length-of-array-of-user-defined-types-to-edx/13") - 6527 (check-next-stream-line-equal _test-output-stream " f7 7/subop/idiv-eax-edx-by %ecx" "F - test-convert-length-of-array-of-user-defined-types-to-edx/14") - 6528 (check-next-stream-line-equal _test-output-stream " 89/<- %edx 0/r32/eax" "F - test-convert-length-of-array-of-user-defined-types-to-edx/15") - 6529 (check-next-stream-line-equal _test-output-stream " 59/pop-to-ecx" "F - test-convert-length-of-array-of-user-defined-types-to-edx/16") - 6530 (check-next-stream-line-equal _test-output-stream " 58/pop-to-eax" "F - test-convert-length-of-array-of-user-defined-types-to-edx/17") - 6531 # reclaim x - 6532 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %edx" "F - test-convert-length-of-array-of-user-defined-types-to-edx/18") - 6533 # reclaim a - 6534 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-length-of-array-of-user-defined-types-to-edx/19") - 6535 # - 6536 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-length-of-array-of-user-defined-types-to-edx/20") - 6537 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-length-of-array-of-user-defined-types-to-edx/21") - 6538 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-length-of-array-of-user-defined-types-to-edx/22") - 6539 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-length-of-array-of-user-defined-types-to-edx/23") - 6540 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-length-of-array-of-user-defined-types-to-edx/24") - 6541 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-length-of-array-of-user-defined-types-to-edx/25") - 6542 # . epilogue - 6543 89/<- %esp 5/r32/ebp - 6544 5d/pop-to-ebp - 6545 c3/return - 6546 - 6547 test-convert-length-of-array-of-user-defined-types: - 6548 # . prologue - 6549 55/push-ebp - 6550 89/<- %ebp 4/r32/esp - 6551 # setup - 6552 (clear-stream _test-input-stream) - 6553 (clear-stream $_test-input-buffered-file->buffer) - 6554 (clear-stream _test-output-stream) - 6555 (clear-stream $_test-output-buffered-file->buffer) - 6556 # - 6557 (write _test-input-stream "type t {\n") # each t is 8 bytes, which is a power of 2 - 6558 (write _test-input-stream " x: int\n") - 6559 (write _test-input-stream " y: int\n") - 6560 (write _test-input-stream " z: int\n") - 6561 (write _test-input-stream "}\n") - 6562 (write _test-input-stream "fn foo {\n") - 6563 (write _test-input-stream " var arr/eax: (addr array t) <- copy 0\n") - 6564 (write _test-input-stream " var x/ebx: (addr t) <- length arr\n") - 6565 (write _test-input-stream "}\n") - 6566 # convert - 6567 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 6568 (flush _test-output-buffered-file) - 6569 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 6575 # check output - 6576 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-length-of-array-of-user-defined-types/0") - 6577 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-length-of-array-of-user-defined-types/1") - 6578 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-length-of-array-of-user-defined-types/2") - 6579 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-length-of-array-of-user-defined-types/3") - 6580 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-length-of-array-of-user-defined-types/4") - 6581 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-length-of-array-of-user-defined-types/5") - 6582 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-length-of-array-of-user-defined-types/6") - 6583 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-length-of-array-of-user-defined-types/7") - 6584 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ebx" "F - test-convert-length-of-array-of-user-defined-types/8") - 6585 (check-next-stream-line-equal _test-output-stream " 50/push-eax" "F - test-convert-length-of-array-of-user-defined-types/9") - 6586 (check-next-stream-line-equal _test-output-stream " 51/push-ecx" "F - test-convert-length-of-array-of-user-defined-types/10") - 6587 (check-next-stream-line-equal _test-output-stream " 52/push-edx" "F - test-convert-length-of-array-of-user-defined-types/11") - 6588 (check-next-stream-line-equal _test-output-stream " 8b/-> *eax 0x00000000/r32" "F - test-convert-length-of-array-of-user-defined-types/12") - 6589 (check-next-stream-line-equal _test-output-stream " 31/xor %edx 2/r32/edx" "F - test-convert-length-of-array-of-user-defined-types/13") - 6590 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 0x0000000c/imm32" "F - test-convert-length-of-array-of-user-defined-types/14") - 6591 (check-next-stream-line-equal _test-output-stream " f7 7/subop/idiv-eax-edx-by %ecx" "F - test-convert-length-of-array-of-user-defined-types/15") - 6592 (check-next-stream-line-equal _test-output-stream " 89/<- %ebx 0/r32/eax" "F - test-convert-length-of-array-of-user-defined-types/16") - 6593 (check-next-stream-line-equal _test-output-stream " 5a/pop-to-edx" "F - test-convert-length-of-array-of-user-defined-types/17") - 6594 (check-next-stream-line-equal _test-output-stream " 59/pop-to-ecx" "F - test-convert-length-of-array-of-user-defined-types/18") - 6595 (check-next-stream-line-equal _test-output-stream " 58/pop-to-eax" "F - test-convert-length-of-array-of-user-defined-types/19") - 6596 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ebx" "F - test-convert-length-of-array-of-user-defined-types/20") - 6597 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-length-of-array-of-user-defined-types/21") - 6598 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-length-of-array-of-user-defined-types/22") - 6599 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-length-of-array-of-user-defined-types/23") - 6600 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-length-of-array-of-user-defined-types/24") - 6601 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-length-of-array-of-user-defined-types/25") - 6602 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-length-of-array-of-user-defined-types/26") - 6603 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-length-of-array-of-user-defined-types/27") - 6604 # . epilogue - 6605 89/<- %esp 5/r32/ebp - 6606 5d/pop-to-ebp - 6607 c3/return - 6608 - 6609 ####################################################### - 6610 # Parsing - 6611 ####################################################### - 6612 - 6613 == data + 5216 (write _test-input-stream "fn foo x: t {\n") + 5217 (write _test-input-stream "}\n") + 5218 (write _test-input-stream "type t {\n") + 5219 (write _test-input-stream " x: int\n") + 5220 (write _test-input-stream " y: int\n") + 5221 (write _test-input-stream "}\n") + 5222 # convert + 5223 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 5224 (flush _test-output-buffered-file) + 5225 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 5231 # check output + 5232 (check-next-stream-line-equal _test-output-stream "f:" "F - test-convert-function-call-with-arg-of-user-defined-type/0") + 5233 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-arg-of-user-defined-type/1") + 5234 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/2") + 5235 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call-with-arg-of-user-defined-type/3") + 5236 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call-with-arg-of-user-defined-type/4") + 5237 (check-next-stream-line-equal _test-output-stream "$f:0x00000001:loop:" "F - test-convert-function-call-with-arg-of-user-defined-type/5") + 5238 # var a + 5239 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-function-call-with-arg-of-user-defined-type/6") + 5240 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-function-call-with-arg-of-user-defined-type/7") + 5241 # foo a + 5242 (check-next-stream-line-equal _test-output-stream " (foo *(eax+0x00000000) *(eax+0x00000004))" "F - test-convert-function-call-with-arg-of-user-defined-type/8") + 5243 # + 5244 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-function-call-with-arg-of-user-defined-type/9") + 5245 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call-with-arg-of-user-defined-type/10") + 5246 (check-next-stream-line-equal _test-output-stream "$f:0x00000001:break:" "F - test-convert-function-call-with-arg-of-user-defined-type/11") + 5247 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-arg-of-user-defined-type/12") + 5248 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/13") + 5249 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/14") + 5250 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-arg-of-user-defined-type/15") + 5251 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-call-with-arg-of-user-defined-type/16") + 5252 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-arg-of-user-defined-type/17") + 5253 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/18") + 5254 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call-with-arg-of-user-defined-type/19") + 5255 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-arg-of-user-defined-type/20") + 5256 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/21") + 5257 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/22") + 5258 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-arg-of-user-defined-type/23") + 5259 # . epilogue + 5260 89/<- %esp 5/r32/ebp + 5261 5d/pop-to-ebp + 5262 c3/return + 5263 + 5264 # we don't have special support for call-by-reference; just explicitly create + 5265 # a new variable with the address of the arg + 5266 test-convert-function-call-with-arg-of-user-defined-type-by-reference: + 5267 # . prologue + 5268 55/push-ebp + 5269 89/<- %ebp 4/r32/esp + 5270 # setup + 5271 (clear-stream _test-input-stream) + 5272 (clear-stream $_test-input-buffered-file->buffer) + 5273 (clear-stream _test-output-stream) + 5274 (clear-stream $_test-output-buffered-file->buffer) + 5275 # + 5276 (write _test-input-stream "fn f {\n") + 5277 (write _test-input-stream " var a: t\n") + 5278 (write _test-input-stream " var b/eax: (addr t) <- address a\n") + 5279 (write _test-input-stream " foo b\n") + 5280 (write _test-input-stream "}\n") + 5281 (write _test-input-stream "fn foo x: (addr t) {\n") + 5282 (write _test-input-stream " var x/ecx: (addr int) <- copy x\n") + 5283 (write _test-input-stream " increment *x\n") + 5284 (write _test-input-stream "}\n") + 5285 (write _test-input-stream "type t {\n") + 5286 (write _test-input-stream " x: int\n") + 5287 (write _test-input-stream " y: int\n") + 5288 (write _test-input-stream "}\n") + 5289 # convert + 5290 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 5291 (flush _test-output-buffered-file) + 5292 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 5298 # check output + 5299 (check-next-stream-line-equal _test-output-stream "f:" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/0") + 5300 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/1") + 5301 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/2") + 5302 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/3") + 5303 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/4") + 5304 (check-next-stream-line-equal _test-output-stream "$f:0x00000001:loop:" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/5") + 5305 # var a: t + 5306 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/6") + 5307 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/7") + 5308 # var b/eax: (addr t) + 5309 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/8") + 5310 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(ebp+0xfffffff8) 0x00000000/r32" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/9") + 5311 # foo a + 5312 (check-next-stream-line-equal _test-output-stream " (foo %eax)" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/10") + 5313 # + 5314 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/11") + 5315 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000008/imm32" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/12") + 5316 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/13") + 5317 (check-next-stream-line-equal _test-output-stream "$f:0x00000001:break:" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/14") + 5318 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/15") + 5319 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/16") + 5320 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/17") + 5321 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/18") + 5322 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/19") + 5323 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/20") + 5324 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/21") + 5325 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/22") + 5326 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/23") + 5327 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/24") + 5328 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/25") + 5329 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x00000008) 0x00000001/r32" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/26") + 5330 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *ecx" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/27") + 5331 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/28") + 5332 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/29") + 5333 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/30") + 5334 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/31") + 5335 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/32") + 5336 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/33") + 5337 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/34") + 5338 # . epilogue + 5339 89/<- %esp 5/r32/ebp + 5340 5d/pop-to-ebp + 5341 c3/return + 5342 + 5343 test-convert-get-on-local-variable: + 5344 # . prologue + 5345 55/push-ebp + 5346 89/<- %ebp 4/r32/esp + 5347 # setup + 5348 (clear-stream _test-input-stream) + 5349 (clear-stream $_test-input-buffered-file->buffer) + 5350 (clear-stream _test-output-stream) + 5351 (clear-stream $_test-output-buffered-file->buffer) + 5352 # + 5353 (write _test-input-stream "fn foo {\n") + 5354 (write _test-input-stream " var a: t\n") + 5355 (write _test-input-stream " var c/ecx: (addr int) <- get a, y\n") + 5356 (write _test-input-stream "}\n") + 5357 (write _test-input-stream "type t {\n") + 5358 (write _test-input-stream " x: int\n") + 5359 (write _test-input-stream " y: int\n") + 5360 (write _test-input-stream "}\n") + 5361 # convert + 5362 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 5363 (flush _test-output-buffered-file) + 5364 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 5370 # check output + 5371 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-get-on-local-variable/0") + 5372 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-get-on-local-variable/1") + 5373 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-get-on-local-variable/2") + 5374 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-get-on-local-variable/3") + 5375 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-get-on-local-variable/4") + 5376 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-get-on-local-variable/5") + 5377 # var a + 5378 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-get-on-local-variable/6") + 5379 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-get-on-local-variable/7") + 5380 # var c + 5381 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-get-on-local-variable/8") + 5382 # get + 5383 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(ebp+0xfffffffc) 0x00000001/r32" "F - test-convert-get-on-local-variable/9") + 5384 # reclaim c + 5385 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-get-on-local-variable/10") + 5386 # reclaim a + 5387 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000008/imm32" "F - test-convert-get-on-local-variable/11") + 5388 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-get-on-local-variable/12") + 5389 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-get-on-local-variable/13") + 5390 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-get-on-local-variable/14") + 5391 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-get-on-local-variable/15") + 5392 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-get-on-local-variable/16") + 5393 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-get-on-local-variable/17") + 5394 # . epilogue + 5395 89/<- %esp 5/r32/ebp + 5396 5d/pop-to-ebp + 5397 c3/return + 5398 + 5399 test-convert-get-on-function-argument: + 5400 # . prologue + 5401 55/push-ebp + 5402 89/<- %ebp 4/r32/esp + 5403 # setup + 5404 (clear-stream _test-input-stream) + 5405 (clear-stream $_test-input-buffered-file->buffer) + 5406 (clear-stream _test-output-stream) + 5407 (clear-stream $_test-output-buffered-file->buffer) + 5408 # + 5409 (write _test-input-stream "fn foo a: t {\n") + 5410 (write _test-input-stream " var c/ecx: (addr int) <- get a, y\n") + 5411 (write _test-input-stream "}\n") + 5412 (write _test-input-stream "type t {\n") + 5413 (write _test-input-stream " x: int\n") + 5414 (write _test-input-stream " y: int\n") + 5415 (write _test-input-stream "}\n") + 5416 # convert + 5417 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 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 "foo:" "F - test-convert-get-on-function-argument/0") + 5427 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-get-on-function-argument/1") + 5428 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-get-on-function-argument/2") + 5429 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-get-on-function-argument/3") + 5430 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-get-on-function-argument/4") + 5431 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-get-on-function-argument/5") + 5432 # var c + 5433 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-get-on-function-argument/6") + 5434 # get + 5435 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(ebp+0x0000000c) 0x00000001/r32" "F - test-convert-get-on-function-argument/7") + 5436 # reclaim c + 5437 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-get-on-function-argument/8") + 5438 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-get-on-function-argument/9") + 5439 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-get-on-function-argument/10") + 5440 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-get-on-function-argument/11") + 5441 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-get-on-function-argument/12") + 5442 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-get-on-function-argument/13") + 5443 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-get-on-function-argument/14") + 5444 # . epilogue + 5445 89/<- %esp 5/r32/ebp + 5446 5d/pop-to-ebp + 5447 c3/return + 5448 + 5449 test-convert-get-on-function-argument-with-known-type: + 5450 # . prologue + 5451 55/push-ebp + 5452 89/<- %ebp 4/r32/esp + 5453 # setup + 5454 (clear-stream _test-input-stream) + 5455 (clear-stream $_test-input-buffered-file->buffer) + 5456 (clear-stream _test-output-stream) + 5457 (clear-stream $_test-output-buffered-file->buffer) + 5458 # + 5459 (write _test-input-stream "type t {\n") + 5460 (write _test-input-stream " x: int\n") + 5461 (write _test-input-stream " y: int\n") + 5462 (write _test-input-stream "}\n") + 5463 (write _test-input-stream "fn foo a: t {\n") + 5464 (write _test-input-stream " var c/ecx: (addr int) <- get a, y\n") + 5465 (write _test-input-stream "}\n") + 5466 # convert + 5467 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 5468 (flush _test-output-buffered-file) + 5469 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 5475 # check output + 5476 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-get-on-function-argument-with-known-type/0") + 5477 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-get-on-function-argument-with-known-type/1") + 5478 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-get-on-function-argument-with-known-type/2") + 5479 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-get-on-function-argument-with-known-type/3") + 5480 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-get-on-function-argument-with-known-type/4") + 5481 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-get-on-function-argument-with-known-type/5") + 5482 # var c + 5483 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-get-on-function-argument-with-known-type/6") + 5484 # get + 5485 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(ebp+0x0000000c) 0x00000001/r32" "F - test-convert-get-on-function-argument-with-known-type/7") + 5486 # reclaim c + 5487 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-get-on-function-argument-with-known-type/8") + 5488 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-get-on-function-argument-with-known-type/9") + 5489 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-get-on-function-argument-with-known-type/10") + 5490 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-get-on-function-argument-with-known-type/11") + 5491 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-get-on-function-argument-with-known-type/12") + 5492 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-get-on-function-argument-with-known-type/13") + 5493 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-get-on-function-argument-with-known-type/14") + 5494 # . epilogue + 5495 89/<- %esp 5/r32/ebp + 5496 5d/pop-to-ebp + 5497 c3/return + 5498 + 5499 test-add-with-too-many-inouts: + 5500 # . prologue + 5501 55/push-ebp + 5502 89/<- %ebp 4/r32/esp + 5503 # setup + 5504 (clear-stream _test-input-stream) + 5505 (clear-stream $_test-input-buffered-file->buffer) + 5506 (clear-stream _test-output-stream) + 5507 (clear-stream $_test-output-buffered-file->buffer) + 5508 (clear-stream _test-error-stream) + 5509 (clear-stream $_test-error-buffered-file->buffer) + 5510 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 5511 68/push 0/imm32 + 5512 68/push 0/imm32 + 5513 89/<- %edx 4/r32/esp + 5514 (tailor-exit-descriptor %edx 0x10) + 5515 # + 5516 (write _test-input-stream "fn foo {\n") + 5517 (write _test-input-stream " var a: int\n") + 5518 (write _test-input-stream " var b/ecx: int <- add a, 0\n") + 5519 (write _test-input-stream "}\n") + 5520 # convert + 5521 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 5522 # registers except esp clobbered at this point + 5523 # restore ed + 5524 89/<- %edx 4/r32/esp + 5525 (flush _test-output-buffered-file) + 5526 (flush _test-error-buffered-file) + 5527 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 5533 # check output + 5534 (check-stream-equal _test-output-stream "" "F - test-add-with-too-many-inouts: output should be empty") + 5535 (check-next-stream-line-equal _test-error-stream "fn foo: stmt add: too many inouts; most primitives support at most two arguments, across inouts and outputs" "F - test-add-with-too-many-inouts: error message") + 5536 # check that stop(1) was called + 5537 (check-ints-equal *(edx+4) 2 "F - test-add-with-too-many-inouts: exit status") + 5538 # don't restore from ebp + 5539 81 0/subop/add %esp 8/imm32 + 5540 # . epilogue + 5541 5d/pop-to-ebp + 5542 c3/return + 5543 + 5544 test-add-with-too-many-inouts-2: + 5545 # . prologue + 5546 55/push-ebp + 5547 89/<- %ebp 4/r32/esp + 5548 # setup + 5549 (clear-stream _test-input-stream) + 5550 (clear-stream $_test-input-buffered-file->buffer) + 5551 (clear-stream _test-output-stream) + 5552 (clear-stream $_test-output-buffered-file->buffer) + 5553 (clear-stream _test-error-stream) + 5554 (clear-stream $_test-error-buffered-file->buffer) + 5555 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 5556 68/push 0/imm32 + 5557 68/push 0/imm32 + 5558 89/<- %edx 4/r32/esp + 5559 (tailor-exit-descriptor %edx 0x10) + 5560 # + 5561 (write _test-input-stream "fn foo {\n") + 5562 (write _test-input-stream " var a: int\n") + 5563 (write _test-input-stream " add-to a, 0, 1\n") + 5564 (write _test-input-stream "}\n") + 5565 # convert + 5566 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 5567 # registers except esp clobbered at this point + 5568 # restore ed + 5569 89/<- %edx 4/r32/esp + 5570 (flush _test-output-buffered-file) + 5571 (flush _test-error-buffered-file) + 5572 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 5578 # check output + 5579 (check-stream-equal _test-output-stream "" "F - test-add-with-too-many-inouts-2: output should be empty") + 5580 (check-next-stream-line-equal _test-error-stream "fn foo: stmt add-to: too many inouts; most primitives support at most two arguments, across inouts and outputs" "F - test-add-with-too-many-inouts-2: error message") + 5581 # check that stop(1) was called + 5582 (check-ints-equal *(edx+4) 2 "F - test-add-with-too-many-inouts-2: exit status") + 5583 # don't restore from ebp + 5584 81 0/subop/add %esp 8/imm32 + 5585 # . epilogue + 5586 5d/pop-to-ebp + 5587 c3/return + 5588 + 5589 test-add-with-too-many-outputs: + 5590 # . prologue + 5591 55/push-ebp + 5592 89/<- %ebp 4/r32/esp + 5593 # setup + 5594 (clear-stream _test-input-stream) + 5595 (clear-stream $_test-input-buffered-file->buffer) + 5596 (clear-stream _test-output-stream) + 5597 (clear-stream $_test-output-buffered-file->buffer) + 5598 (clear-stream _test-error-stream) + 5599 (clear-stream $_test-error-buffered-file->buffer) + 5600 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 5601 68/push 0/imm32 + 5602 68/push 0/imm32 + 5603 89/<- %edx 4/r32/esp + 5604 (tailor-exit-descriptor %edx 0x10) + 5605 # + 5606 (write _test-input-stream "fn foo {\n") + 5607 (write _test-input-stream " var a/eax: int <- copy 0\n") + 5608 (write _test-input-stream " var b/ebx: int <- copy 0\n") + 5609 (write _test-input-stream " var c/ecx: int <- copy 0\n") + 5610 (write _test-input-stream " c, b <- add a\n") + 5611 (write _test-input-stream "}\n") + 5612 # convert + 5613 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 5614 # registers except esp clobbered at this point + 5615 # restore ed + 5616 89/<- %edx 4/r32/esp + 5617 (flush _test-output-buffered-file) + 5618 (flush _test-error-buffered-file) + 5619 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 5625 # check output + 5626 (check-stream-equal _test-output-stream "" "F - test-add-with-too-many-outputs: output should be empty") + 5627 (check-next-stream-line-equal _test-error-stream "fn foo: stmt add: too many outputs; most primitives support at most one output" "F - test-add-with-too-many-outputs: error message") + 5628 # check that stop(1) was called + 5629 (check-ints-equal *(edx+4) 2 "F - test-add-with-too-many-outputs: exit status") + 5630 # don't restore from ebp + 5631 81 0/subop/add %esp 8/imm32 + 5632 # . epilogue + 5633 5d/pop-to-ebp + 5634 c3/return + 5635 + 5636 test-add-with-non-number: + 5637 # . prologue + 5638 55/push-ebp + 5639 89/<- %ebp 4/r32/esp + 5640 # setup + 5641 (clear-stream _test-input-stream) + 5642 (clear-stream $_test-input-buffered-file->buffer) + 5643 (clear-stream _test-output-stream) + 5644 (clear-stream $_test-output-buffered-file->buffer) + 5645 (clear-stream _test-error-stream) + 5646 (clear-stream $_test-error-buffered-file->buffer) + 5647 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 5648 68/push 0/imm32 + 5649 68/push 0/imm32 + 5650 89/<- %edx 4/r32/esp + 5651 (tailor-exit-descriptor %edx 0x10) + 5652 # + 5653 (write _test-input-stream "fn foo {\n") + 5654 (write _test-input-stream " var a: int\n") + 5655 (write _test-input-stream " var b/ecx: (addr int) <- add a\n") + 5656 (write _test-input-stream "}\n") + 5657 # convert + 5658 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 5659 # registers except esp clobbered at this point + 5660 # restore ed + 5661 89/<- %edx 4/r32/esp + 5662 (flush _test-output-buffered-file) + 5663 (flush _test-error-buffered-file) + 5664 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 5670 # check output + 5671 (check-stream-equal _test-output-stream "" "F - test-add-with-non-number: output should be empty") + 5672 (check-next-stream-line-equal _test-error-stream "fn foo: stmt add: only non-addr scalar args permitted" "F - test-add-with-non-number: error message") + 5673 # check that stop(1) was called + 5674 (check-ints-equal *(edx+4) 2 "F - test-add-with-non-number: exit status") + 5675 # don't restore from ebp + 5676 81 0/subop/add %esp 8/imm32 + 5677 # . epilogue + 5678 5d/pop-to-ebp + 5679 c3/return + 5680 + 5681 test-add-with-addr-dereferenced: + 5682 # . prologue + 5683 55/push-ebp + 5684 89/<- %ebp 4/r32/esp + 5685 # setup + 5686 (clear-stream _test-input-stream) + 5687 (clear-stream $_test-input-buffered-file->buffer) + 5688 (clear-stream _test-output-stream) + 5689 (clear-stream $_test-output-buffered-file->buffer) + 5690 # + 5691 (write _test-input-stream "fn foo {\n") + 5692 (write _test-input-stream " var a/eax: (addr int) <- copy 0\n") + 5693 (write _test-input-stream " add-to *a, 1\n") + 5694 (write _test-input-stream "}\n") + 5695 # convert + 5696 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 5697 (flush _test-output-buffered-file) + 5698 # no error + 5699 # . epilogue + 5700 89/<- %esp 5/r32/ebp + 5701 5d/pop-to-ebp + 5702 c3/return + 5703 + 5704 test-get-with-wrong-field: + 5705 # . prologue + 5706 55/push-ebp + 5707 89/<- %ebp 4/r32/esp + 5708 # setup + 5709 (clear-stream _test-input-stream) + 5710 (clear-stream $_test-input-buffered-file->buffer) + 5711 (clear-stream _test-output-stream) + 5712 (clear-stream $_test-output-buffered-file->buffer) + 5713 (clear-stream _test-error-stream) + 5714 (clear-stream $_test-error-buffered-file->buffer) + 5715 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 5716 68/push 0/imm32 + 5717 68/push 0/imm32 + 5718 89/<- %edx 4/r32/esp + 5719 (tailor-exit-descriptor %edx 0x10) + 5720 # + 5721 (write _test-input-stream "fn foo {\n") + 5722 (write _test-input-stream " var a: t\n") + 5723 (write _test-input-stream " var c/ecx: (addr int) <- get a, y\n") + 5724 (write _test-input-stream "}\n") + 5725 (write _test-input-stream "type t {\n") + 5726 (write _test-input-stream " x: int\n") + 5727 (write _test-input-stream "}\n") + 5728 # convert + 5729 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 5730 # registers except esp clobbered at this point + 5731 # restore ed + 5732 89/<- %edx 4/r32/esp + 5733 (flush _test-output-buffered-file) + 5734 (flush _test-error-buffered-file) + 5735 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 5741 # check output + 5742 (check-stream-equal _test-output-stream "" "F - test-get-with-wrong-field: output should be empty") + 5743 (check-next-stream-line-equal _test-error-stream "fn foo: stmt get: type 't' has no member called 'y'" "F - test-get-with-wrong-field: error message") + 5744 # check that stop(1) was called + 5745 (check-ints-equal *(edx+4) 2 "F - test-get-with-wrong-field: exit status") + 5746 # don't restore from ebp + 5747 81 0/subop/add %esp 8/imm32 + 5748 # . epilogue + 5749 5d/pop-to-ebp + 5750 c3/return + 5751 + 5752 test-get-with-wrong-base-type: + 5753 # . prologue + 5754 55/push-ebp + 5755 89/<- %ebp 4/r32/esp + 5756 # setup + 5757 (clear-stream _test-input-stream) + 5758 (clear-stream $_test-input-buffered-file->buffer) + 5759 (clear-stream _test-output-stream) + 5760 (clear-stream $_test-output-buffered-file->buffer) + 5761 (clear-stream _test-error-stream) + 5762 (clear-stream $_test-error-buffered-file->buffer) + 5763 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 5764 68/push 0/imm32 + 5765 68/push 0/imm32 + 5766 89/<- %edx 4/r32/esp + 5767 (tailor-exit-descriptor %edx 0x10) + 5768 # + 5769 (write _test-input-stream "fn foo {\n") + 5770 (write _test-input-stream " var a: int\n") + 5771 (write _test-input-stream " var c/ecx: (addr int) <- get a, y\n") + 5772 (write _test-input-stream "}\n") + 5773 # convert + 5774 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 5775 # registers except esp clobbered at this point + 5776 # restore ed + 5777 89/<- %edx 4/r32/esp + 5778 (flush _test-output-buffered-file) + 5779 (flush _test-error-buffered-file) + 5780 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 5786 # check output + 5787 (check-stream-equal _test-output-stream "" "F - test-get-with-wrong-base-type: output should be empty") + 5788 (check-next-stream-line-equal _test-error-stream "fn foo: stmt get: var 'a' must have a 'type' definition" "F - test-get-with-wrong-base-type: error message") + 5789 # check that stop(1) was called + 5790 (check-ints-equal *(edx+4) 2 "F - test-get-with-wrong-base-type: exit status") + 5791 # don't restore from ebp + 5792 81 0/subop/add %esp 8/imm32 + 5793 # . epilogue + 5794 5d/pop-to-ebp + 5795 c3/return + 5796 + 5797 test-get-with-wrong-base-type-2: + 5798 # . prologue + 5799 55/push-ebp + 5800 89/<- %ebp 4/r32/esp + 5801 # setup + 5802 (clear-stream _test-input-stream) + 5803 (clear-stream $_test-input-buffered-file->buffer) + 5804 (clear-stream _test-output-stream) + 5805 (clear-stream $_test-output-buffered-file->buffer) + 5806 (clear-stream _test-error-stream) + 5807 (clear-stream $_test-error-buffered-file->buffer) + 5808 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 5809 68/push 0/imm32 + 5810 68/push 0/imm32 + 5811 89/<- %edx 4/r32/esp + 5812 (tailor-exit-descriptor %edx 0x10) + 5813 # + 5814 (write _test-input-stream "fn foo {\n") + 5815 (write _test-input-stream " var a: (addr t)\n") + 5816 (write _test-input-stream " var c/ecx: (addr int) <- get a, y\n") + 5817 (write _test-input-stream "}\n") + 5818 (write _test-input-stream "type t {\n") + 5819 (write _test-input-stream " x: int\n") + 5820 (write _test-input-stream "}\n") + 5821 # convert + 5822 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 5823 # registers except esp clobbered at this point + 5824 # restore ed + 5825 89/<- %edx 4/r32/esp + 5826 (flush _test-output-buffered-file) + 5827 (flush _test-error-buffered-file) + 5828 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 5834 # check output + 5835 (check-stream-equal _test-output-stream "" "F - test-get-with-wrong-base-type-2: output should be empty") + 5836 (check-next-stream-line-equal _test-error-stream "fn foo: stmt get: var 'a' is an 'addr' type, and so must live in a register" "F - test-get-with-wrong-base-type-2: error message") + 5837 # check that stop(1) was called + 5838 (check-ints-equal *(edx+4) 2 "F - test-get-with-wrong-base-type-2: exit status") + 5839 # don't restore from ebp + 5840 81 0/subop/add %esp 8/imm32 + 5841 # . epilogue + 5842 5d/pop-to-ebp + 5843 c3/return + 5844 + 5845 test-get-with-wrong-offset-type: + 5846 # . prologue + 5847 55/push-ebp + 5848 89/<- %ebp 4/r32/esp + 5849 # setup + 5850 (clear-stream _test-input-stream) + 5851 (clear-stream $_test-input-buffered-file->buffer) + 5852 (clear-stream _test-output-stream) + 5853 (clear-stream $_test-output-buffered-file->buffer) + 5854 (clear-stream _test-error-stream) + 5855 (clear-stream $_test-error-buffered-file->buffer) + 5856 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 5857 68/push 0/imm32 + 5858 68/push 0/imm32 + 5859 89/<- %edx 4/r32/esp + 5860 (tailor-exit-descriptor %edx 0x10) + 5861 # + 5862 (write _test-input-stream "fn foo {\n") + 5863 (write _test-input-stream " var a: t\n") + 5864 (write _test-input-stream " var b: int\n") + 5865 (write _test-input-stream " var c/ecx: (addr int) <- get a, b\n") + 5866 (write _test-input-stream "}\n") + 5867 (write _test-input-stream "type t {\n") + 5868 (write _test-input-stream " x: int\n") + 5869 (write _test-input-stream "}\n") + 5870 # convert + 5871 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 5872 # registers except esp clobbered at this point + 5873 # restore ed + 5874 89/<- %edx 4/r32/esp + 5875 (flush _test-output-buffered-file) + 5876 (flush _test-error-buffered-file) + 5877 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 5883 # check output + 5884 (check-stream-equal _test-output-stream "" "F - test-get-with-wrong-offset-type: output should be empty") + 5885 (check-next-stream-line-equal _test-error-stream "fn foo: stmt get: type 't' has no member called 'b'" "F - test-get-with-wrong-offset-type: error message") + 5886 # check that stop(1) was called + 5887 (check-ints-equal *(edx+4) 2 "F - test-get-with-wrong-offset-type: exit status") + 5888 # don't restore from ebp + 5889 81 0/subop/add %esp 8/imm32 + 5890 # . epilogue + 5891 5d/pop-to-ebp + 5892 c3/return + 5893 + 5894 test-get-with-wrong-output-type: + 5895 # . prologue + 5896 55/push-ebp + 5897 89/<- %ebp 4/r32/esp + 5898 # setup + 5899 (clear-stream _test-input-stream) + 5900 (clear-stream $_test-input-buffered-file->buffer) + 5901 (clear-stream _test-output-stream) + 5902 (clear-stream $_test-output-buffered-file->buffer) + 5903 (clear-stream _test-error-stream) + 5904 (clear-stream $_test-error-buffered-file->buffer) + 5905 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 5906 68/push 0/imm32 + 5907 68/push 0/imm32 + 5908 89/<- %edx 4/r32/esp + 5909 (tailor-exit-descriptor %edx 0x10) + 5910 # + 5911 (write _test-input-stream "fn foo {\n") + 5912 (write _test-input-stream " var a: t\n") + 5913 (write _test-input-stream " var c: (addr int)\n") + 5914 (write _test-input-stream " c <- get a, x\n") + 5915 (write _test-input-stream "}\n") + 5916 (write _test-input-stream "type t {\n") + 5917 (write _test-input-stream " x: int\n") + 5918 (write _test-input-stream "}\n") + 5919 # convert + 5920 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 5921 # registers except esp clobbered at this point + 5922 # restore ed + 5923 89/<- %edx 4/r32/esp + 5924 (flush _test-output-buffered-file) + 5925 (flush _test-error-buffered-file) + 5926 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 5932 # check output + 5933 (check-stream-equal _test-output-stream "" "F - test-get-with-wrong-output-type: output should be empty") + 5934 (check-next-stream-line-equal _test-error-stream "fn foo: stmt get: output 'c' is not in a register" "F - test-get-with-wrong-output-type: error message") + 5935 # check that stop(1) was called + 5936 (check-ints-equal *(edx+4) 2 "F - test-get-with-wrong-output-type: exit status") + 5937 # don't restore from ebp + 5938 81 0/subop/add %esp 8/imm32 + 5939 # . epilogue + 5940 5d/pop-to-ebp + 5941 c3/return + 5942 + 5943 test-get-with-wrong-output-type-2: + 5944 # . prologue + 5945 55/push-ebp + 5946 89/<- %ebp 4/r32/esp + 5947 # setup + 5948 (clear-stream _test-input-stream) + 5949 (clear-stream $_test-input-buffered-file->buffer) + 5950 (clear-stream _test-output-stream) + 5951 (clear-stream $_test-output-buffered-file->buffer) + 5952 (clear-stream _test-error-stream) + 5953 (clear-stream $_test-error-buffered-file->buffer) + 5954 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 5955 68/push 0/imm32 + 5956 68/push 0/imm32 + 5957 89/<- %edx 4/r32/esp + 5958 (tailor-exit-descriptor %edx 0x10) + 5959 # + 5960 (write _test-input-stream "fn foo {\n") + 5961 (write _test-input-stream " var a: t\n") + 5962 (write _test-input-stream " var c/ecx: int <- get a, x\n") + 5963 (write _test-input-stream "}\n") + 5964 (write _test-input-stream "type t {\n") + 5965 (write _test-input-stream " x: int\n") + 5966 (write _test-input-stream "}\n") + 5967 # convert + 5968 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 5969 # registers except esp clobbered at this point + 5970 # restore ed + 5971 89/<- %edx 4/r32/esp + 5972 (flush _test-output-buffered-file) + 5973 (flush _test-error-buffered-file) + 5974 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 5980 # check output + 5981 (check-stream-equal _test-output-stream "" "F - test-get-with-wrong-output-type-2: output should be empty") + 5982 (check-next-stream-line-equal _test-error-stream "fn foo: stmt get: output must be an address" "F - test-get-with-wrong-output-type-2: error message") + 5983 # check that stop(1) was called + 5984 (check-ints-equal *(edx+4) 2 "F - test-get-with-wrong-output-type-2: exit status") + 5985 # don't restore from ebp + 5986 81 0/subop/add %esp 8/imm32 + 5987 # . epilogue + 5988 5d/pop-to-ebp + 5989 c3/return + 5990 + 5991 test-get-with-wrong-output-type-3: + 5992 # . prologue + 5993 55/push-ebp + 5994 89/<- %ebp 4/r32/esp + 5995 # setup + 5996 (clear-stream _test-input-stream) + 5997 (clear-stream $_test-input-buffered-file->buffer) + 5998 (clear-stream _test-output-stream) + 5999 (clear-stream $_test-output-buffered-file->buffer) + 6000 (clear-stream _test-error-stream) + 6001 (clear-stream $_test-error-buffered-file->buffer) + 6002 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 6003 68/push 0/imm32 + 6004 68/push 0/imm32 + 6005 89/<- %edx 4/r32/esp + 6006 (tailor-exit-descriptor %edx 0x10) + 6007 # + 6008 (write _test-input-stream "fn foo {\n") + 6009 (write _test-input-stream " var a: t\n") + 6010 (write _test-input-stream " var c/ecx: (array int) <- get a, x\n") + 6011 (write _test-input-stream "}\n") + 6012 (write _test-input-stream "type t {\n") + 6013 (write _test-input-stream " x: int\n") + 6014 (write _test-input-stream "}\n") + 6015 # convert + 6016 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 6017 # registers except esp clobbered at this point + 6018 # restore ed + 6019 89/<- %edx 4/r32/esp + 6020 (flush _test-output-buffered-file) + 6021 (flush _test-error-buffered-file) + 6022 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 6028 # check output + 6029 (check-stream-equal _test-output-stream "" "F - test-get-with-wrong-output-type-3: output should be empty") + 6030 (check-next-stream-line-equal _test-error-stream "fn foo: stmt get: output must be an address" "F - test-get-with-wrong-output-type-3: error message") + 6031 # check that stop(1) was called + 6032 (check-ints-equal *(edx+4) 2 "F - test-get-with-wrong-output-type-3: exit status") + 6033 # don't restore from ebp + 6034 81 0/subop/add %esp 8/imm32 + 6035 # . epilogue + 6036 5d/pop-to-ebp + 6037 c3/return + 6038 + 6039 test-get-with-wrong-output-type-4: + 6040 # . prologue + 6041 55/push-ebp + 6042 89/<- %ebp 4/r32/esp + 6043 # setup + 6044 (clear-stream _test-input-stream) + 6045 (clear-stream $_test-input-buffered-file->buffer) + 6046 (clear-stream _test-output-stream) + 6047 (clear-stream $_test-output-buffered-file->buffer) + 6048 (clear-stream _test-error-stream) + 6049 (clear-stream $_test-error-buffered-file->buffer) + 6050 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 6051 68/push 0/imm32 + 6052 68/push 0/imm32 + 6053 89/<- %edx 4/r32/esp + 6054 (tailor-exit-descriptor %edx 0x10) + 6055 # + 6056 (write _test-input-stream "fn foo {\n") + 6057 (write _test-input-stream " var a: t\n") + 6058 (write _test-input-stream " var c/ecx: (addr boolean) <- get a, x\n") + 6059 (write _test-input-stream "}\n") + 6060 (write _test-input-stream "type t {\n") + 6061 (write _test-input-stream " x: int\n") + 6062 (write _test-input-stream "}\n") + 6063 # convert + 6064 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 6065 # registers except esp clobbered at this point + 6066 # restore ed + 6067 89/<- %edx 4/r32/esp + 6068 (flush _test-output-buffered-file) + 6069 (flush _test-error-buffered-file) + 6070 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 6076 # check output + 6077 (check-stream-equal _test-output-stream "" "F - test-get-with-wrong-output-type-4: output should be empty") + 6078 (check-next-stream-line-equal _test-error-stream "fn foo: stmt get: wrong output type for member 'x' of type 't'" "F - test-get-with-wrong-output-type-4: error message") + 6079 # check that stop(1) was called + 6080 (check-ints-equal *(edx+4) 2 "F - test-get-with-wrong-output-type-4: exit status") + 6081 # don't restore from ebp + 6082 81 0/subop/add %esp 8/imm32 + 6083 # . epilogue + 6084 5d/pop-to-ebp + 6085 c3/return + 6086 + 6087 test-get-with-wrong-output-type-5: + 6088 # . prologue + 6089 55/push-ebp + 6090 89/<- %ebp 4/r32/esp + 6091 # setup + 6092 (clear-stream _test-input-stream) + 6093 (clear-stream $_test-input-buffered-file->buffer) + 6094 (clear-stream _test-output-stream) + 6095 (clear-stream $_test-output-buffered-file->buffer) + 6096 # + 6097 (write _test-input-stream "fn foo {\n") + 6098 (write _test-input-stream " var a: t\n") + 6099 (write _test-input-stream " var c/ecx: (addr handle int) <- get a, x\n") + 6100 (write _test-input-stream "}\n") + 6101 (write _test-input-stream "type t {\n") + 6102 (write _test-input-stream " x: (handle int)\n") + 6103 (write _test-input-stream "}\n") + 6104 # convert + 6105 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 6106 (flush _test-output-buffered-file) + 6107 # no errors + 6108 # . epilogue + 6109 89/<- %esp 5/r32/ebp + 6110 5d/pop-to-ebp + 6111 c3/return + 6112 + 6113 test-get-with-too-few-inouts: + 6114 # . prologue + 6115 55/push-ebp + 6116 89/<- %ebp 4/r32/esp + 6117 # setup + 6118 (clear-stream _test-input-stream) + 6119 (clear-stream $_test-input-buffered-file->buffer) + 6120 (clear-stream _test-output-stream) + 6121 (clear-stream $_test-output-buffered-file->buffer) + 6122 (clear-stream _test-error-stream) + 6123 (clear-stream $_test-error-buffered-file->buffer) + 6124 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 6125 68/push 0/imm32 + 6126 68/push 0/imm32 + 6127 89/<- %edx 4/r32/esp + 6128 (tailor-exit-descriptor %edx 0x10) + 6129 # + 6130 (write _test-input-stream "fn foo {\n") + 6131 (write _test-input-stream " var a: t\n") + 6132 (write _test-input-stream " var c/ecx: (addr int) <- get a\n") + 6133 (write _test-input-stream "}\n") + 6134 (write _test-input-stream "type t {\n") + 6135 (write _test-input-stream " x: int\n") + 6136 (write _test-input-stream "}\n") + 6137 # convert + 6138 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 6139 # registers except esp clobbered at this point + 6140 # restore ed + 6141 89/<- %edx 4/r32/esp + 6142 (flush _test-output-buffered-file) + 6143 (flush _test-error-buffered-file) + 6144 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 6150 # check output + 6151 (check-stream-equal _test-output-stream "" "F - test-get-with-too-few-inouts: output should be empty") + 6152 (check-next-stream-line-equal _test-error-stream "fn foo: stmt get: too few inouts (2 required)" "F - test-get-with-too-few-inouts: error message") + 6153 # check that stop(1) was called + 6154 (check-ints-equal *(edx+4) 2 "F - test-get-with-too-few-inouts: exit status") + 6155 # don't restore from ebp + 6156 81 0/subop/add %esp 8/imm32 + 6157 # . epilogue + 6158 5d/pop-to-ebp + 6159 c3/return + 6160 + 6161 test-get-with-too-many-inouts: + 6162 # . prologue + 6163 55/push-ebp + 6164 89/<- %ebp 4/r32/esp + 6165 # setup + 6166 (clear-stream _test-input-stream) + 6167 (clear-stream $_test-input-buffered-file->buffer) + 6168 (clear-stream _test-output-stream) + 6169 (clear-stream $_test-output-buffered-file->buffer) + 6170 (clear-stream _test-error-stream) + 6171 (clear-stream $_test-error-buffered-file->buffer) + 6172 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 6173 68/push 0/imm32 + 6174 68/push 0/imm32 + 6175 89/<- %edx 4/r32/esp + 6176 (tailor-exit-descriptor %edx 0x10) + 6177 # + 6178 (write _test-input-stream "fn foo {\n") + 6179 (write _test-input-stream " var a: t\n") + 6180 (write _test-input-stream " var c/ecx: (addr int) <- get a, x, 0\n") + 6181 (write _test-input-stream "}\n") + 6182 (write _test-input-stream "type t {\n") + 6183 (write _test-input-stream " x: int\n") + 6184 (write _test-input-stream "}\n") + 6185 # convert + 6186 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 6187 # registers except esp clobbered at this point + 6188 # restore ed + 6189 89/<- %edx 4/r32/esp + 6190 (flush _test-output-buffered-file) + 6191 (flush _test-error-buffered-file) + 6192 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 6198 # check output + 6199 (check-stream-equal _test-output-stream "" "F - test-get-with-too-many-inouts: output should be empty") + 6200 (check-next-stream-line-equal _test-error-stream "fn foo: stmt get: too many inouts (2 required)" "F - test-get-with-too-many-inouts: error message") + 6201 # check that stop(1) was called + 6202 (check-ints-equal *(edx+4) 2 "F - test-get-with-too-many-inouts: exit status") + 6203 # don't restore from ebp + 6204 81 0/subop/add %esp 8/imm32 + 6205 # . epilogue + 6206 5d/pop-to-ebp + 6207 c3/return + 6208 + 6209 test-get-with-no-output: + 6210 # . prologue + 6211 55/push-ebp + 6212 89/<- %ebp 4/r32/esp + 6213 # setup + 6214 (clear-stream _test-input-stream) + 6215 (clear-stream $_test-input-buffered-file->buffer) + 6216 (clear-stream _test-output-stream) + 6217 (clear-stream $_test-output-buffered-file->buffer) + 6218 (clear-stream _test-error-stream) + 6219 (clear-stream $_test-error-buffered-file->buffer) + 6220 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 6221 68/push 0/imm32 + 6222 68/push 0/imm32 + 6223 89/<- %edx 4/r32/esp + 6224 (tailor-exit-descriptor %edx 0x10) + 6225 # + 6226 (write _test-input-stream "fn foo {\n") + 6227 (write _test-input-stream " var a: t\n") + 6228 (write _test-input-stream " get a, x\n") + 6229 (write _test-input-stream "}\n") + 6230 (write _test-input-stream "type t {\n") + 6231 (write _test-input-stream " x: int\n") + 6232 (write _test-input-stream "}\n") + 6233 # convert + 6234 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 6235 # registers except esp clobbered at this point + 6236 # restore ed + 6237 89/<- %edx 4/r32/esp + 6238 (flush _test-output-buffered-file) + 6239 (flush _test-error-buffered-file) + 6240 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 6246 # check output + 6247 (check-stream-equal _test-output-stream "" "F - test-get-with-no-output: output should be empty") + 6248 (check-next-stream-line-equal _test-error-stream "fn foo: stmt get: must have an output" "F - test-get-with-no-output: error message") + 6249 # check that stop(1) was called + 6250 (check-ints-equal *(edx+4) 2 "F - test-get-with-no-output: exit status") + 6251 # don't restore from ebp + 6252 81 0/subop/add %esp 8/imm32 + 6253 # . epilogue + 6254 5d/pop-to-ebp + 6255 c3/return + 6256 + 6257 test-get-with-too-many-outputs: + 6258 # . prologue + 6259 55/push-ebp + 6260 89/<- %ebp 4/r32/esp + 6261 # setup + 6262 (clear-stream _test-input-stream) + 6263 (clear-stream $_test-input-buffered-file->buffer) + 6264 (clear-stream _test-output-stream) + 6265 (clear-stream $_test-output-buffered-file->buffer) + 6266 (clear-stream _test-error-stream) + 6267 (clear-stream $_test-error-buffered-file->buffer) + 6268 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 6269 68/push 0/imm32 + 6270 68/push 0/imm32 + 6271 89/<- %edx 4/r32/esp + 6272 (tailor-exit-descriptor %edx 0x10) + 6273 # + 6274 (write _test-input-stream "fn foo {\n") + 6275 (write _test-input-stream " var a: t\n") + 6276 (write _test-input-stream " var b: int\n") + 6277 (write _test-input-stream " var c/eax: (addr int) <- copy 0\n") + 6278 (write _test-input-stream " c, b <- get a, x\n") + 6279 (write _test-input-stream "}\n") + 6280 (write _test-input-stream "type t {\n") + 6281 (write _test-input-stream " x: int\n") + 6282 (write _test-input-stream "}\n") + 6283 # convert + 6284 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 6285 # registers except esp clobbered at this point + 6286 # restore ed + 6287 89/<- %edx 4/r32/esp + 6288 (flush _test-output-buffered-file) + 6289 (flush _test-error-buffered-file) + 6290 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 6296 # check output + 6297 (check-stream-equal _test-output-stream "" "F - test-get-with-too-many-outputs: output should be empty") + 6298 (check-next-stream-line-equal _test-error-stream "fn foo: stmt get: too many outputs (1 required)" "F - test-get-with-too-many-outputs: error message") + 6299 # check that stop(1) was called + 6300 (check-ints-equal *(edx+4) 2 "F - test-get-with-too-many-outputs: exit status") + 6301 # don't restore from ebp + 6302 81 0/subop/add %esp 8/imm32 + 6303 # . epilogue + 6304 5d/pop-to-ebp + 6305 c3/return + 6306 + 6307 test-convert-array-of-user-defined-types: + 6308 # . prologue + 6309 55/push-ebp + 6310 89/<- %ebp 4/r32/esp + 6311 # setup + 6312 (clear-stream _test-input-stream) + 6313 (clear-stream $_test-input-buffered-file->buffer) + 6314 (clear-stream _test-output-stream) + 6315 (clear-stream $_test-output-buffered-file->buffer) + 6316 # + 6317 (write _test-input-stream "type t {\n") # each t is 8 bytes, which is a power of 2 + 6318 (write _test-input-stream " x: int\n") + 6319 (write _test-input-stream " y: int\n") + 6320 (write _test-input-stream "}\n") + 6321 (write _test-input-stream "fn foo {\n") + 6322 (write _test-input-stream " var arr/eax: (addr array t) <- copy 0\n") + 6323 (write _test-input-stream " var idx/ecx: int <- copy 3\n") + 6324 (write _test-input-stream " var x/eax: (addr t) <- index arr, idx\n") + 6325 (write _test-input-stream "}\n") + 6326 # convert + 6327 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 6328 (flush _test-output-buffered-file) + 6329 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 6335 # check output + 6336 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-array-of-user-defined-types/0") + 6337 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-array-of-user-defined-types/1") + 6338 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-array-of-user-defined-types/2") + 6339 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-array-of-user-defined-types/3") + 6340 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-array-of-user-defined-types/4") + 6341 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-array-of-user-defined-types/5") + 6342 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-array-of-user-defined-types/6") + 6343 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-array-of-user-defined-types/7") + 6344 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-array-of-user-defined-types/8") + 6345 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-convert-array-of-user-defined-types/9") + 6346 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + ecx<<0x00000003 + 4) 0x00000000/r32" "F - test-convert-array-of-user-defined-types/11") + 6347 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-array-of-user-defined-types/13") + 6348 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-array-of-user-defined-types/14") + 6349 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-array-of-user-defined-types/15") + 6350 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-array-of-user-defined-types/16") + 6351 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-array-of-user-defined-types/17") + 6352 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-array-of-user-defined-types/18") + 6353 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-array-of-user-defined-types/19") + 6354 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-array-of-user-defined-types/20") + 6355 # . epilogue + 6356 89/<- %esp 5/r32/ebp + 6357 5d/pop-to-ebp + 6358 c3/return + 6359 + 6360 test-convert-length-of-array-of-user-defined-types-to-eax: + 6361 # . prologue + 6362 55/push-ebp + 6363 89/<- %ebp 4/r32/esp + 6364 # setup + 6365 (clear-stream _test-input-stream) + 6366 (clear-stream $_test-input-buffered-file->buffer) + 6367 (clear-stream _test-output-stream) + 6368 (clear-stream $_test-output-buffered-file->buffer) + 6369 # + 6370 (write _test-input-stream "type t {\n") # size = 12, which is not a power of 2 + 6371 (write _test-input-stream " x: int\n") + 6372 (write _test-input-stream " y: int\n") + 6373 (write _test-input-stream " z: int\n") + 6374 (write _test-input-stream "}\n") + 6375 (write _test-input-stream "fn foo {\n") + 6376 (write _test-input-stream " var arr/eax: (addr array t) <- copy 0\n") + 6377 (write _test-input-stream " var x/eax: (addr t) <- length arr\n") + 6378 (write _test-input-stream "}\n") + 6379 # convert + 6380 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 6381 (flush _test-output-buffered-file) + 6382 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 6388 # check output + 6389 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-length-of-array-of-user-defined-types-to-eax/0") + 6390 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-length-of-array-of-user-defined-types-to-eax/1") + 6391 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-length-of-array-of-user-defined-types-to-eax/2") + 6392 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-length-of-array-of-user-defined-types-to-eax/3") + 6393 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-length-of-array-of-user-defined-types-to-eax/4") + 6394 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-length-of-array-of-user-defined-types-to-eax/5") + 6395 # var arr + 6396 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-length-of-array-of-user-defined-types-to-eax/6") + 6397 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-length-of-array-of-user-defined-types-to-eax/7") + 6398 # length instruction + 6399 (check-next-stream-line-equal _test-output-stream " 51/push-ecx" "F - test-convert-length-of-array-of-user-defined-types-to-eax/8") + 6400 (check-next-stream-line-equal _test-output-stream " 52/push-edx" "F - test-convert-length-of-array-of-user-defined-types-to-eax/9") + 6401 (check-next-stream-line-equal _test-output-stream " 8b/-> *eax 0x00000000/r32" "F - test-convert-length-of-array-of-user-defined-types-to-eax/10") + 6402 (check-next-stream-line-equal _test-output-stream " 31/xor %edx 2/r32/edx" "F - test-convert-length-of-array-of-user-defined-types-to-eax/11") + 6403 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 0x0000000c/imm32" "F - test-convert-length-of-array-of-user-defined-types-to-eax/12") + 6404 (check-next-stream-line-equal _test-output-stream " f7 7/subop/idiv-eax-edx-by %ecx" "F - test-convert-length-of-array-of-user-defined-types-to-eax/13") + 6405 (check-next-stream-line-equal _test-output-stream " 5a/pop-to-edx" "F - test-convert-length-of-array-of-user-defined-types-to-eax/14") + 6406 (check-next-stream-line-equal _test-output-stream " 59/pop-to-ecx" "F - test-convert-length-of-array-of-user-defined-types-to-eax/15") + 6407 # reclaim arr + 6408 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-length-of-array-of-user-defined-types-to-eax/16") + 6409 # + 6410 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-length-of-array-of-user-defined-types-to-eax/17") + 6411 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-length-of-array-of-user-defined-types-to-eax/18") + 6412 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-length-of-array-of-user-defined-types-to-eax/19") + 6413 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-length-of-array-of-user-defined-types-to-eax/20") + 6414 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-length-of-array-of-user-defined-types-to-eax/21") + 6415 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-length-of-array-of-user-defined-types-to-eax/22") + 6416 # . epilogue + 6417 89/<- %esp 5/r32/ebp + 6418 5d/pop-to-ebp + 6419 c3/return + 6420 + 6421 test-convert-length-of-array-of-user-defined-types-to-ecx: + 6422 # . prologue + 6423 55/push-ebp + 6424 89/<- %ebp 4/r32/esp + 6425 # setup + 6426 (clear-stream _test-input-stream) + 6427 (clear-stream $_test-input-buffered-file->buffer) + 6428 (clear-stream _test-output-stream) + 6429 (clear-stream $_test-output-buffered-file->buffer) + 6430 # + 6431 (write _test-input-stream "type t {\n") # size = 12, which is not a power of 2 + 6432 (write _test-input-stream " x: int\n") + 6433 (write _test-input-stream " y: int\n") + 6434 (write _test-input-stream " z: int\n") + 6435 (write _test-input-stream "}\n") + 6436 (write _test-input-stream "fn foo {\n") + 6437 (write _test-input-stream " var arr/eax: (addr array t) <- copy 0\n") + 6438 (write _test-input-stream " var x/ecx: (addr t) <- length arr\n") + 6439 (write _test-input-stream "}\n") + 6440 # convert + 6441 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 6442 (flush _test-output-buffered-file) + 6443 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 6449 # check output + 6450 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/0") + 6451 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/1") + 6452 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/2") + 6453 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/3") + 6454 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/4") + 6455 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/5") + 6456 # var a + 6457 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/6") + 6458 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/7") + 6459 # var x + 6460 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/8") + 6461 # length instruction + 6462 (check-next-stream-line-equal _test-output-stream " 50/push-eax" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/9") + 6463 (check-next-stream-line-equal _test-output-stream " 52/push-edx" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/10") + 6464 (check-next-stream-line-equal _test-output-stream " 8b/-> *eax 0x00000000/r32" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/11") + 6465 (check-next-stream-line-equal _test-output-stream " 31/xor %edx 2/r32/edx" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/12") + 6466 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 0x0000000c/imm32" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/13") + 6467 (check-next-stream-line-equal _test-output-stream " f7 7/subop/idiv-eax-edx-by %ecx" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/14") + 6468 (check-next-stream-line-equal _test-output-stream " 89/<- %ecx 0/r32/eax" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/15") + 6469 (check-next-stream-line-equal _test-output-stream " 5a/pop-to-edx" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/16") + 6470 (check-next-stream-line-equal _test-output-stream " 58/pop-to-eax" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/17") + 6471 # reclaim x + 6472 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/18") + 6473 # reclaim a + 6474 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/19") + 6475 # + 6476 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/20") + 6477 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/21") + 6478 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/22") + 6479 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/23") + 6480 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/24") + 6481 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/25") + 6482 # . epilogue + 6483 89/<- %esp 5/r32/ebp + 6484 5d/pop-to-ebp + 6485 c3/return + 6486 + 6487 test-convert-length-of-array-of-user-defined-types-to-edx: + 6488 # . prologue + 6489 55/push-ebp + 6490 89/<- %ebp 4/r32/esp + 6491 # setup + 6492 (clear-stream _test-input-stream) + 6493 (clear-stream $_test-input-buffered-file->buffer) + 6494 (clear-stream _test-output-stream) + 6495 (clear-stream $_test-output-buffered-file->buffer) + 6496 # + 6497 (write _test-input-stream "type t {\n") # size = 12, which is not a power of 2 + 6498 (write _test-input-stream " x: int\n") + 6499 (write _test-input-stream " y: int\n") + 6500 (write _test-input-stream " z: int\n") + 6501 (write _test-input-stream "}\n") + 6502 (write _test-input-stream "fn foo {\n") + 6503 (write _test-input-stream " var arr/eax: (addr array t) <- copy 0\n") + 6504 (write _test-input-stream " var x/edx: (addr t) <- length arr\n") + 6505 (write _test-input-stream "}\n") + 6506 # convert + 6507 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 6508 (flush _test-output-buffered-file) + 6509 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 6515 # check output + 6516 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-length-of-array-of-user-defined-types-to-edx/0") + 6517 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-length-of-array-of-user-defined-types-to-edx/1") + 6518 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-length-of-array-of-user-defined-types-to-edx/2") + 6519 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-length-of-array-of-user-defined-types-to-edx/3") + 6520 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-length-of-array-of-user-defined-types-to-edx/4") + 6521 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-length-of-array-of-user-defined-types-to-edx/5") + 6522 # var a + 6523 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-length-of-array-of-user-defined-types-to-edx/6") + 6524 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-length-of-array-of-user-defined-types-to-edx/7") + 6525 # var x + 6526 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %edx" "F - test-convert-length-of-array-of-user-defined-types-to-edx/8") + 6527 # length instruction + 6528 (check-next-stream-line-equal _test-output-stream " 50/push-eax" "F - test-convert-length-of-array-of-user-defined-types-to-edx/9") + 6529 (check-next-stream-line-equal _test-output-stream " 51/push-ecx" "F - test-convert-length-of-array-of-user-defined-types-to-edx/10") + 6530 (check-next-stream-line-equal _test-output-stream " 8b/-> *eax 0x00000000/r32" "F - test-convert-length-of-array-of-user-defined-types-to-edx/11") + 6531 (check-next-stream-line-equal _test-output-stream " 31/xor %edx 2/r32/edx" "F - test-convert-length-of-array-of-user-defined-types-to-edx/12") + 6532 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 0x0000000c/imm32" "F - test-convert-length-of-array-of-user-defined-types-to-edx/13") + 6533 (check-next-stream-line-equal _test-output-stream " f7 7/subop/idiv-eax-edx-by %ecx" "F - test-convert-length-of-array-of-user-defined-types-to-edx/14") + 6534 (check-next-stream-line-equal _test-output-stream " 89/<- %edx 0/r32/eax" "F - test-convert-length-of-array-of-user-defined-types-to-edx/15") + 6535 (check-next-stream-line-equal _test-output-stream " 59/pop-to-ecx" "F - test-convert-length-of-array-of-user-defined-types-to-edx/16") + 6536 (check-next-stream-line-equal _test-output-stream " 58/pop-to-eax" "F - test-convert-length-of-array-of-user-defined-types-to-edx/17") + 6537 # reclaim x + 6538 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %edx" "F - test-convert-length-of-array-of-user-defined-types-to-edx/18") + 6539 # reclaim a + 6540 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-length-of-array-of-user-defined-types-to-edx/19") + 6541 # + 6542 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-length-of-array-of-user-defined-types-to-edx/20") + 6543 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-length-of-array-of-user-defined-types-to-edx/21") + 6544 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-length-of-array-of-user-defined-types-to-edx/22") + 6545 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-length-of-array-of-user-defined-types-to-edx/23") + 6546 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-length-of-array-of-user-defined-types-to-edx/24") + 6547 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-length-of-array-of-user-defined-types-to-edx/25") + 6548 # . epilogue + 6549 89/<- %esp 5/r32/ebp + 6550 5d/pop-to-ebp + 6551 c3/return + 6552 + 6553 test-convert-length-of-array-of-user-defined-types: + 6554 # . prologue + 6555 55/push-ebp + 6556 89/<- %ebp 4/r32/esp + 6557 # setup + 6558 (clear-stream _test-input-stream) + 6559 (clear-stream $_test-input-buffered-file->buffer) + 6560 (clear-stream _test-output-stream) + 6561 (clear-stream $_test-output-buffered-file->buffer) + 6562 # + 6563 (write _test-input-stream "type t {\n") # each t is 8 bytes, which is a power of 2 + 6564 (write _test-input-stream " x: int\n") + 6565 (write _test-input-stream " y: int\n") + 6566 (write _test-input-stream " z: int\n") + 6567 (write _test-input-stream "}\n") + 6568 (write _test-input-stream "fn foo {\n") + 6569 (write _test-input-stream " var arr/eax: (addr array t) <- copy 0\n") + 6570 (write _test-input-stream " var x/ebx: (addr t) <- length arr\n") + 6571 (write _test-input-stream "}\n") + 6572 # convert + 6573 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 6574 (flush _test-output-buffered-file) + 6575 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 6581 # check output + 6582 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-length-of-array-of-user-defined-types/0") + 6583 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-length-of-array-of-user-defined-types/1") + 6584 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-length-of-array-of-user-defined-types/2") + 6585 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-length-of-array-of-user-defined-types/3") + 6586 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-length-of-array-of-user-defined-types/4") + 6587 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-length-of-array-of-user-defined-types/5") + 6588 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-length-of-array-of-user-defined-types/6") + 6589 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-length-of-array-of-user-defined-types/7") + 6590 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ebx" "F - test-convert-length-of-array-of-user-defined-types/8") + 6591 (check-next-stream-line-equal _test-output-stream " 50/push-eax" "F - test-convert-length-of-array-of-user-defined-types/9") + 6592 (check-next-stream-line-equal _test-output-stream " 51/push-ecx" "F - test-convert-length-of-array-of-user-defined-types/10") + 6593 (check-next-stream-line-equal _test-output-stream " 52/push-edx" "F - test-convert-length-of-array-of-user-defined-types/11") + 6594 (check-next-stream-line-equal _test-output-stream " 8b/-> *eax 0x00000000/r32" "F - test-convert-length-of-array-of-user-defined-types/12") + 6595 (check-next-stream-line-equal _test-output-stream " 31/xor %edx 2/r32/edx" "F - test-convert-length-of-array-of-user-defined-types/13") + 6596 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 0x0000000c/imm32" "F - test-convert-length-of-array-of-user-defined-types/14") + 6597 (check-next-stream-line-equal _test-output-stream " f7 7/subop/idiv-eax-edx-by %ecx" "F - test-convert-length-of-array-of-user-defined-types/15") + 6598 (check-next-stream-line-equal _test-output-stream " 89/<- %ebx 0/r32/eax" "F - test-convert-length-of-array-of-user-defined-types/16") + 6599 (check-next-stream-line-equal _test-output-stream " 5a/pop-to-edx" "F - test-convert-length-of-array-of-user-defined-types/17") + 6600 (check-next-stream-line-equal _test-output-stream " 59/pop-to-ecx" "F - test-convert-length-of-array-of-user-defined-types/18") + 6601 (check-next-stream-line-equal _test-output-stream " 58/pop-to-eax" "F - test-convert-length-of-array-of-user-defined-types/19") + 6602 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ebx" "F - test-convert-length-of-array-of-user-defined-types/20") + 6603 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-length-of-array-of-user-defined-types/21") + 6604 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-length-of-array-of-user-defined-types/22") + 6605 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-length-of-array-of-user-defined-types/23") + 6606 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-length-of-array-of-user-defined-types/24") + 6607 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-length-of-array-of-user-defined-types/25") + 6608 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-length-of-array-of-user-defined-types/26") + 6609 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-length-of-array-of-user-defined-types/27") + 6610 # . epilogue + 6611 89/<- %esp 5/r32/ebp + 6612 5d/pop-to-ebp + 6613 c3/return 6614 - 6615 # Global state added to each var record when parsing a function - 6616 Next-block-index: # (addr int) - 6617 1/imm32 - 6618 - 6619 Curr-block-depth: # (addr int) - 6620 1/imm32 - 6621 - 6622 == code - 6623 - 6624 parse-mu: # in: (addr buffered-file), err: (addr buffered-file), ed: (addr exit-descriptor) - 6625 # pseudocode - 6626 # var curr-function: (addr handle function) = Program->functions - 6627 # var curr-signature: (addr handle function) = Program->signatures - 6628 # var curr-type: (addr handle typeinfo) = Program->types - 6629 # var line: (stream byte 512) - 6630 # var word-slice: slice - 6631 # while true # line loop - 6632 # clear-stream(line) - 6633 # read-line-buffered(in, line) - 6634 # if (line->write == 0) break # end of file - 6635 # word-slice = next-mu-token(line) - 6636 # if slice-empty?(word-slice) # end of line - 6637 # continue - 6638 # else if slice-starts-with?(word-slice, "#") # comment - 6639 # continue # end of line - 6640 # else if slice-equal?(word-slice, "fn") - 6641 # var new-function: (handle function) = allocate(function) - 6642 # var vars: (stack live-var 256) - 6643 # populate-mu-function-header(line, new-function, vars) - 6644 # populate-mu-function-body(in, new-function, vars) - 6645 # assert(vars->top == 0) - 6646 # *curr-function = new-function - 6647 # curr-function = &new-function->next - 6648 # else if slice-equal?(word-slice, "sig") - 6649 # var new-function: (handle function) = allocate(function) - 6650 # populate-mu-function-signature(line, new-function) - 6651 # *curr-signature = new-function - 6652 # curr-signature = &new-function->next - 6653 # else if slice-equal?(word-slice, "type") - 6654 # word-slice = next-mu-token(line) - 6655 # type-id = pos-or-insert-slice(Type-id, word-slice) - 6656 # var new-type: (handle typeinfo) = find-or-create-typeinfo(type-id) - 6657 # assert(next-word(line) == "{") - 6658 # populate-mu-type(in, new-type) - 6659 # else - 6660 # abort() - 6661 # - 6662 # . prologue - 6663 55/push-ebp - 6664 89/<- %ebp 4/r32/esp - 6665 # var curr-signature: (addr handle function) at *(ebp-4) - 6666 68/push _Program-signatures/imm32 - 6667 # . save registers - 6668 50/push-eax - 6669 51/push-ecx - 6670 52/push-edx - 6671 53/push-ebx - 6672 56/push-esi - 6673 57/push-edi - 6674 # var line/ecx: (stream byte 512) - 6675 81 5/subop/subtract %esp 0x200/imm32 - 6676 68/push 0x200/imm32/size - 6677 68/push 0/imm32/read - 6678 68/push 0/imm32/write - 6679 89/<- %ecx 4/r32/esp - 6680 # var word-slice/edx: slice - 6681 68/push 0/imm32/end - 6682 68/push 0/imm32/start - 6683 89/<- %edx 4/r32/esp - 6684 # var curr-function/edi: (addr handle function) - 6685 bf/copy-to-edi _Program-functions/imm32 - 6686 # var vars/ebx: (stack live-var 256) - 6687 81 5/subop/subtract %esp 0xc00/imm32 - 6688 68/push 0xc00/imm32/size - 6689 68/push 0/imm32/top - 6690 89/<- %ebx 4/r32/esp - 6691 { - 6692 $parse-mu:line-loop: - 6693 (clear-stream %ecx) - 6694 (read-line-buffered *(ebp+8) %ecx) - 6695 # if (line->write == 0) break - 6696 81 7/subop/compare *ecx 0/imm32 - 6697 0f 84/jump-if-= break/disp32 - 6698 +-- 6 lines: #? # dump line ------------------------------------------------------------------------------------------------------------------------------------------------------ - 6704 (next-mu-token %ecx %edx) - 6705 # if slice-empty?(word-slice) continue - 6706 (slice-empty? %edx) # => eax - 6707 3d/compare-eax-and 0/imm32/false - 6708 0f 85/jump-if-!= loop/disp32 - 6709 # if (*word-slice->start == "#") continue - 6710 # . eax = *word-slice->start - 6711 8b/-> *edx 0/r32/eax - 6712 8a/copy-byte *eax 0/r32/AL - 6713 81 4/subop/and %eax 0xff/imm32 - 6714 # . if (eax == '#') continue - 6715 3d/compare-eax-and 0x23/imm32/hash - 6716 0f 84/jump-if-= loop/disp32 - 6717 # if (slice-equal?(word-slice, "fn")) parse a function - 6718 { - 6719 $parse-mu:fn: - 6720 (slice-equal? %edx "fn") # => eax - 6721 3d/compare-eax-and 0/imm32/false - 6722 0f 84/jump-if-= break/disp32 - 6723 # var new-function/esi: (handle function) - 6724 68/push 0/imm32 - 6725 68/push 0/imm32 - 6726 89/<- %esi 4/r32/esp - 6727 # populate-mu-function(line, in, vars, new-function) - 6728 (allocate Heap *Function-size %esi) - 6729 # var new-function-addr/eax: (addr function) - 6730 (lookup *esi *(esi+4)) # => eax - 6731 # initialize vars - 6732 (clear-stack %ebx) - 6733 # - 6734 (populate-mu-function-header %ecx %eax %ebx *(ebp+0xc) *(ebp+0x10)) - 6735 (populate-mu-function-body *(ebp+8) %eax %ebx *(ebp+0xc) *(ebp+0x10)) - 6736 # *curr-function = new-function - 6737 8b/-> *esi 0/r32/eax - 6738 89/<- *edi 0/r32/eax - 6739 8b/-> *(esi+4) 0/r32/eax - 6740 89/<- *(edi+4) 0/r32/eax - 6741 # curr-function = &new-function->next - 6742 # . var tmp/eax: (addr function) = lookup(new-function) - 6743 (lookup *esi *(esi+4)) # => eax - 6744 # . curr-function = &tmp->next - 6745 8d/copy-address *(eax+0x20) 7/r32/edi # Function-next - 6746 # reclaim new-function - 6747 81 0/subop/add %esp 8/imm32 - 6748 # - 6749 e9/jump $parse-mu:line-loop/disp32 - 6750 } - 6751 # if (slice-equal?(word-slice, "sig")) parse a function signature - 6752 # Function signatures are for providing types to SubX functions. - 6753 { - 6754 $parse-mu:sig: - 6755 (slice-equal? %edx "sig") # => eax - 6756 3d/compare-eax-and 0/imm32/false - 6757 0f 84/jump-if-= break/disp32 - 6758 # edi = curr-function - 6759 57/push-edi - 6760 8b/-> *(ebp-4) 7/r32/edi - 6761 # var new-function/esi: (handle function) - 6762 68/push 0/imm32 - 6763 68/push 0/imm32 - 6764 89/<- %esi 4/r32/esp - 6765 # populate-mu-function(line, in, vars, new-function) - 6766 (allocate Heap *Function-size %esi) - 6767 # var new-function-addr/eax: (addr function) - 6768 (lookup *esi *(esi+4)) # => eax - 6769 # - 6770 (populate-mu-function-signature %ecx %eax *(ebp+0xc) *(ebp+0x10)) - 6771 # *curr-signature = new-function - 6772 8b/-> *esi 0/r32/eax - 6773 89/<- *edi 0/r32/eax - 6774 8b/-> *(esi+4) 0/r32/eax - 6775 89/<- *(edi+4) 0/r32/eax - 6776 # curr-signature = &new-function->next - 6777 # . var tmp/eax: (addr function) = lookup(new-function) - 6778 (lookup *esi *(esi+4)) # => eax - 6779 # . curr-function = &tmp->next - 6780 8d/copy-address *(eax+0x20) 7/r32/edi # Function-next - 6781 # reclaim new-function - 6782 81 0/subop/add %esp 8/imm32 - 6783 # save curr-function - 6784 89/<- *(ebp-4) 7/r32/edi - 6785 # restore edi - 6786 5f/pop-to-edi - 6787 # - 6788 e9/jump $parse-mu:line-loop/disp32 - 6789 } - 6790 # if (slice-equal?(word-slice, "type")) parse a type (struct/record) definition - 6791 { - 6792 $parse-mu:type: - 6793 (slice-equal? %edx "type") # => eax - 6794 3d/compare-eax-and 0/imm32 - 6795 0f 84/jump-if-= break/disp32 - 6796 (next-mu-token %ecx %edx) - 6797 # var type-id/eax: int - 6798 (pos-or-insert-slice Type-id %edx) # => eax - 6799 # spill - 6800 51/push-ecx - 6801 # var new-type/ecx: (handle typeinfo) - 6802 68/push 0/imm32 - 6803 68/push 0/imm32 - 6804 89/<- %ecx 4/r32/esp - 6805 (find-or-create-typeinfo %eax %ecx) - 6806 # - 6807 (lookup *ecx *(ecx+4)) # => eax - 6808 # TODO: ensure that 'line' has nothing else but '{' - 6809 #? (dump-typeinfos "=== aaa\n") - 6810 (populate-mu-type *(ebp+8) %eax *(ebp+0xc) *(ebp+0x10)) # => eax - 6811 #? (dump-typeinfos "=== zzz\n") - 6812 # reclaim new-type - 6813 81 0/subop/add %esp 8/imm32 - 6814 # restore - 6815 59/pop-to-ecx - 6816 e9/jump $parse-mu:line-loop/disp32 - 6817 } - 6818 # otherwise abort - 6819 e9/jump $parse-mu:error1/disp32 - 6820 } # end line loop - 6821 $parse-mu:end: - 6822 # . reclaim locals - 6823 81 0/subop/add %esp 0x20c/imm32 # line - 6824 81 0/subop/add %esp 0xc08/imm32 # vars - 6825 81 0/subop/add %esp 8/imm32 - 6826 # . restore registers - 6827 5f/pop-to-edi - 6828 5e/pop-to-esi - 6829 5b/pop-to-ebx - 6830 5a/pop-to-edx - 6831 59/pop-to-ecx - 6832 58/pop-to-eax - 6833 # . reclaim local - 6834 81 0/subop/add %esp 4/imm32 - 6835 # . epilogue - 6836 89/<- %esp 5/r32/ebp + 6615 test-index-with-non-array-atom-base-type: + 6616 # . prologue + 6617 55/push-ebp + 6618 89/<- %ebp 4/r32/esp + 6619 # setup + 6620 (clear-stream _test-input-stream) + 6621 (clear-stream $_test-input-buffered-file->buffer) + 6622 (clear-stream _test-output-stream) + 6623 (clear-stream $_test-output-buffered-file->buffer) + 6624 (clear-stream _test-error-stream) + 6625 (clear-stream $_test-error-buffered-file->buffer) + 6626 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 6627 68/push 0/imm32 + 6628 68/push 0/imm32 + 6629 89/<- %edx 4/r32/esp + 6630 (tailor-exit-descriptor %edx 0x10) + 6631 # + 6632 (write _test-input-stream "fn foo {\n") + 6633 (write _test-input-stream " var a: int\n") + 6634 (write _test-input-stream " var c/ecx: (addr int) <- index a, 0\n") + 6635 (write _test-input-stream "}\n") + 6636 # convert + 6637 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 6638 # registers except esp clobbered at this point + 6639 # restore ed + 6640 89/<- %edx 4/r32/esp + 6641 (flush _test-output-buffered-file) + 6642 (flush _test-error-buffered-file) + 6643 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 6649 # check output + 6650 (check-stream-equal _test-output-stream "" "F - test-index-with-non-array-atom-base-type: output should be empty") + 6651 (check-next-stream-line-equal _test-error-stream "fn foo: stmt index: var 'a' is not an array" "F - test-index-with-non-array-atom-base-type: error message") + 6652 # check that stop(1) was called + 6653 (check-ints-equal *(edx+4) 2 "F - test-index-with-non-array-atom-base-type: exit status") + 6654 # don't restore from ebp + 6655 81 0/subop/add %esp 8/imm32 + 6656 # . epilogue + 6657 5d/pop-to-ebp + 6658 c3/return + 6659 + 6660 test-index-with-non-array-compound-base-type: + 6661 # . prologue + 6662 55/push-ebp + 6663 89/<- %ebp 4/r32/esp + 6664 # setup + 6665 (clear-stream _test-input-stream) + 6666 (clear-stream $_test-input-buffered-file->buffer) + 6667 (clear-stream _test-output-stream) + 6668 (clear-stream $_test-output-buffered-file->buffer) + 6669 (clear-stream _test-error-stream) + 6670 (clear-stream $_test-error-buffered-file->buffer) + 6671 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 6672 68/push 0/imm32 + 6673 68/push 0/imm32 + 6674 89/<- %edx 4/r32/esp + 6675 (tailor-exit-descriptor %edx 0x10) + 6676 # + 6677 (write _test-input-stream "fn foo {\n") + 6678 (write _test-input-stream " var a: (handle int)\n") + 6679 (write _test-input-stream " var c/ecx: (addr int) <- index a, 0\n") + 6680 (write _test-input-stream "}\n") + 6681 # convert + 6682 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 6683 # registers except esp clobbered at this point + 6684 # restore ed + 6685 89/<- %edx 4/r32/esp + 6686 (flush _test-output-buffered-file) + 6687 (flush _test-error-buffered-file) + 6688 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 6694 # check output + 6695 (check-stream-equal _test-output-stream "" "F - test-index-with-non-array-compound-base-type: output should be empty") + 6696 (check-next-stream-line-equal _test-error-stream "fn foo: stmt index: var 'a' is not an array" "F - test-index-with-non-array-compound-base-type: error message") + 6697 # check that stop(1) was called + 6698 (check-ints-equal *(edx+4) 2 "F - test-index-with-non-array-compound-base-type: exit status") + 6699 # don't restore from ebp + 6700 81 0/subop/add %esp 8/imm32 + 6701 # . epilogue + 6702 5d/pop-to-ebp + 6703 c3/return + 6704 + 6705 test-index-with-non-array-compound-base-type-2: + 6706 # . prologue + 6707 55/push-ebp + 6708 89/<- %ebp 4/r32/esp + 6709 # setup + 6710 (clear-stream _test-input-stream) + 6711 (clear-stream $_test-input-buffered-file->buffer) + 6712 (clear-stream _test-output-stream) + 6713 (clear-stream $_test-output-buffered-file->buffer) + 6714 (clear-stream _test-error-stream) + 6715 (clear-stream $_test-error-buffered-file->buffer) + 6716 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 6717 68/push 0/imm32 + 6718 68/push 0/imm32 + 6719 89/<- %edx 4/r32/esp + 6720 (tailor-exit-descriptor %edx 0x10) + 6721 # + 6722 (write _test-input-stream "fn foo {\n") + 6723 (write _test-input-stream " var a: (addr int)\n") + 6724 (write _test-input-stream " var c/ecx: (addr int) <- index a, 0\n") + 6725 (write _test-input-stream "}\n") + 6726 # convert + 6727 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 6728 # registers except esp clobbered at this point + 6729 # restore ed + 6730 89/<- %edx 4/r32/esp + 6731 (flush _test-output-buffered-file) + 6732 (flush _test-error-buffered-file) + 6733 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 6739 # check output + 6740 (check-stream-equal _test-output-stream "" "F - test-index-with-non-array-compound-base-type-2: output should be empty") + 6741 (check-next-stream-line-equal _test-error-stream "fn foo: stmt index: var 'a' is not an array" "F - test-index-with-non-array-compound-base-type-2: error message") + 6742 # check that stop(1) was called + 6743 (check-ints-equal *(edx+4) 2 "F - test-index-with-non-array-compound-base-type-2: exit status") + 6744 # don't restore from ebp + 6745 81 0/subop/add %esp 8/imm32 + 6746 # . epilogue + 6747 5d/pop-to-ebp + 6748 c3/return + 6749 + 6750 test-index-with-array-atom-base-type: + 6751 # . prologue + 6752 55/push-ebp + 6753 89/<- %ebp 4/r32/esp + 6754 # setup + 6755 (clear-stream _test-input-stream) + 6756 (clear-stream $_test-input-buffered-file->buffer) + 6757 (clear-stream _test-output-stream) + 6758 (clear-stream $_test-output-buffered-file->buffer) + 6759 (clear-stream _test-error-stream) + 6760 (clear-stream $_test-error-buffered-file->buffer) + 6761 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 6762 68/push 0/imm32 + 6763 68/push 0/imm32 + 6764 89/<- %edx 4/r32/esp + 6765 (tailor-exit-descriptor %edx 0x10) + 6766 # + 6767 (write _test-input-stream "fn foo {\n") + 6768 (write _test-input-stream " var a: array\n") + 6769 (write _test-input-stream " var c/ecx: (addr int) <- index a, 0\n") + 6770 (write _test-input-stream "}\n") + 6771 # convert + 6772 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 6773 # registers except esp clobbered at this point + 6774 # restore ed + 6775 89/<- %edx 4/r32/esp + 6776 (flush _test-output-buffered-file) + 6777 (flush _test-error-buffered-file) + 6778 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 6784 # check output + 6785 (check-stream-equal _test-output-stream "" "F - test-index-with-array-atom-base-type: output should be empty") + 6786 (check-next-stream-line-equal _test-error-stream "fn foo: stmt index: array 'a' must specify the type of its elements" "F - test-index-with-array-atom-base-type: error message") + 6787 # check that stop(1) was called + 6788 (check-ints-equal *(edx+4) 2 "F - test-index-with-array-atom-base-type: exit status") + 6789 # don't restore from ebp + 6790 81 0/subop/add %esp 8/imm32 + 6791 # . epilogue + 6792 5d/pop-to-ebp + 6793 c3/return + 6794 + 6795 test-index-with-addr-base-on-stack: + 6796 # . prologue + 6797 55/push-ebp + 6798 89/<- %ebp 4/r32/esp + 6799 # setup + 6800 (clear-stream _test-input-stream) + 6801 (clear-stream $_test-input-buffered-file->buffer) + 6802 (clear-stream _test-output-stream) + 6803 (clear-stream $_test-output-buffered-file->buffer) + 6804 (clear-stream _test-error-stream) + 6805 (clear-stream $_test-error-buffered-file->buffer) + 6806 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 6807 68/push 0/imm32 + 6808 68/push 0/imm32 + 6809 89/<- %edx 4/r32/esp + 6810 (tailor-exit-descriptor %edx 0x10) + 6811 # + 6812 (write _test-input-stream "fn foo {\n") + 6813 (write _test-input-stream " var a: (addr array int)\n") + 6814 (write _test-input-stream " var c/ecx: (addr int) <- index a, 0\n") + 6815 (write _test-input-stream "}\n") + 6816 # convert + 6817 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 6818 # registers except esp clobbered at this point + 6819 # restore ed + 6820 89/<- %edx 4/r32/esp + 6821 (flush _test-output-buffered-file) + 6822 (flush _test-error-buffered-file) + 6823 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 6829 # check output + 6830 (check-stream-equal _test-output-stream "" "F - test-index-with-addr-base-on-stack: output should be empty") + 6831 (check-next-stream-line-equal _test-error-stream "fn foo: stmt index: var 'a' is an addr to an array, and so must live in a register" "F - test-index-with-addr-base-on-stack: error message") + 6832 # check that stop(1) was called + 6833 (check-ints-equal *(edx+4) 2 "F - test-index-with-addr-base-on-stack: exit status") + 6834 # don't restore from ebp + 6835 81 0/subop/add %esp 8/imm32 + 6836 # . epilogue 6837 5d/pop-to-ebp 6838 c3/return 6839 - 6840 $parse-mu:error1: - 6841 # error("unexpected top-level command: " word-slice "\n") - 6842 (write-buffered *(ebp+0xc) "unexpected top-level command: ") - 6843 (write-slice-buffered *(ebp+0xc) %edx) - 6844 (write-buffered *(ebp+0xc) "\n") - 6845 (flush *(ebp+0xc)) - 6846 (stop *(ebp+0x10) 1) - 6847 # never gets here - 6848 - 6849 $parse-mu:error2: - 6850 # error(vars->top " vars not reclaimed after fn '" new-function->name "'\n") - 6851 (write-int32-hex-buffered *(ebp+0xc) *ebx) - 6852 (write-buffered *(ebp+0xc) " vars not reclaimed after fn '") - 6853 (write-slice-buffered *(ebp+0xc) *eax) # Function-name - 6854 (write-buffered *(ebp+0xc) "'\n") - 6855 (flush *(ebp+0xc)) - 6856 (stop *(ebp+0x10) 1) - 6857 # never gets here - 6858 - 6859 # scenarios considered: - 6860 # ✗ fn foo # no block - 6861 # ✓ fn foo { - 6862 # ✗ fn foo { { - 6863 # ✗ fn foo { } - 6864 # ✗ fn foo { } { - 6865 # ✗ fn foo x { - 6866 # ✗ fn foo x: { - 6867 # ✓ fn foo x: int { - 6868 # ✓ fn foo x: int { - 6869 # ✓ fn foo x: int -> y/eax: int { - 6870 # TODO: - 6871 # disallow outputs of type `(... addr ...)` - 6872 # disallow inputs of type `(... addr ... addr ...)` - 6873 populate-mu-function-header: # first-line: (addr stream byte), out: (addr function), vars: (addr stack live-var), err: (addr buffered-file), ed: (addr exit-descriptor) - 6874 # pseudocode: - 6875 # var word-slice: slice - 6876 # next-mu-token(first-line, word-slice) - 6877 # assert(word-slice not in '{' '}' '->') - 6878 # out->name = slice-to-string(word-slice) - 6879 # ## inouts - 6880 # while true - 6881 # word-slice = next-mu-token(first-line) - 6882 # if (word-slice == '{') goto done - 6883 # if (word-slice == '->') break - 6884 # assert(word-slice != '}') - 6885 # var v: (handle var) = parse-var-with-type(word-slice, first-line) - 6886 # assert(v->register == null) - 6887 # # v->block-depth is implicitly 0 - 6888 # out->inouts = append(v, out->inouts) - 6889 # push(vars, {v, false}) - 6890 # ## outputs - 6891 # while true - 6892 # word-slice = next-mu-token(first-line) - 6893 # if (word-slice == '{') break - 6894 # assert(word-slice not in '}' '->') - 6895 # var v: (handle var) = parse-var-with-type(word-slice, first-line) - 6896 # assert(v->register != null) - 6897 # out->outputs = append(v, out->outputs) - 6898 # done: - 6899 # - 6900 # . prologue - 6901 55/push-ebp - 6902 89/<- %ebp 4/r32/esp - 6903 # . save registers - 6904 50/push-eax - 6905 51/push-ecx - 6906 52/push-edx - 6907 53/push-ebx - 6908 57/push-edi - 6909 # edi = out - 6910 8b/-> *(ebp+0xc) 7/r32/edi - 6911 # var word-slice/ecx: slice - 6912 68/push 0/imm32/end - 6913 68/push 0/imm32/start - 6914 89/<- %ecx 4/r32/esp - 6915 # var v/ebx: (handle var) - 6916 68/push 0/imm32 - 6917 68/push 0/imm32 - 6918 89/<- %ebx 4/r32/esp - 6919 # read function name - 6920 (next-mu-token *(ebp+8) %ecx) - 6921 # error checking - 6922 # if (word-slice == '{') abort - 6923 (slice-equal? %ecx "{") # => eax - 6924 3d/compare-eax-and 0/imm32/false - 6925 0f 85/jump-if-!= $populate-mu-function-header:error1/disp32 - 6926 # if (word-slice == '->') abort - 6927 (slice-equal? %ecx "->") # => eax - 6928 3d/compare-eax-and 0/imm32/false - 6929 0f 85/jump-if-!= $populate-mu-function-header:error1/disp32 - 6930 # if (word-slice == '}') abort - 6931 (slice-equal? %ecx "}") # => eax - 6932 3d/compare-eax-and 0/imm32/false - 6933 0f 85/jump-if-!= $populate-mu-function-header:error1/disp32 - 6934 # save function name - 6935 (slice-to-string Heap %ecx %edi) # Function-name - 6936 # save function inouts - 6937 { - 6938 $populate-mu-function-header:check-for-inout: - 6939 (next-mu-token *(ebp+8) %ecx) - 6940 # if (word-slice == '{') goto done - 6941 (slice-equal? %ecx "{") # => eax - 6942 3d/compare-eax-and 0/imm32/false - 6943 0f 85/jump-if-!= $populate-mu-function-header:done/disp32 - 6944 # if (word-slice == '->') break - 6945 (slice-equal? %ecx "->") # => eax - 6946 3d/compare-eax-and 0/imm32/false - 6947 0f 85/jump-if-!= break/disp32 - 6948 # if (word-slice == '}') abort - 6949 (slice-equal? %ecx "}") # => eax - 6950 3d/compare-eax-and 0/imm32/false - 6951 0f 85/jump-if-!= $populate-mu-function-header:error1/disp32 - 6952 # v = parse-var-with-type(word-slice, first-line) - 6953 (parse-var-with-type %ecx *(ebp+8) %ebx *(ebp+0x14) *(ebp+0x18)) - 6954 # assert(v->register == null) - 6955 # . eax: (addr var) = lookup(v) - 6956 (lookup *ebx *(ebx+4)) # => eax - 6957 81 7/subop/compare *(eax+0x18) 0/imm32 # Var-register - 6958 0f 85/jump-if-!= $populate-mu-function-header:error2/disp32 - 6959 # v->block-depth is implicitly 0 - 6960 # - 6961 # out->inouts = append(v, out->inouts) - 6962 8d/copy-address *(edi+8) 0/r32/eax # Function-inouts - 6963 (append-list Heap *ebx *(ebx+4) *(edi+8) *(edi+0xc) %eax) # Function-inouts, Function-inouts - 6964 # push(vars, {v, false}) - 6965 (push *(ebp+0x10) *ebx) - 6966 (push *(ebp+0x10) *(ebx+4)) - 6967 (push *(ebp+0x10) 0) # false - 6968 # - 6969 e9/jump loop/disp32 - 6970 } - 6971 # save function outputs - 6972 { - 6973 $populate-mu-function-header:check-for-out: - 6974 (next-mu-token *(ebp+8) %ecx) - 6975 # if (word-slice == '{') break - 6976 (slice-equal? %ecx "{") # => eax - 6977 3d/compare-eax-and 0/imm32/false - 6978 0f 85/jump-if-!= break/disp32 - 6979 # if (word-slice == '->') abort - 6980 (slice-equal? %ecx "->") # => eax - 6981 3d/compare-eax-and 0/imm32/false - 6982 0f 85/jump-if-!= $populate-mu-function-header:error1/disp32 - 6983 # if (word-slice == '}') abort - 6984 (slice-equal? %ecx "}") # => eax - 6985 3d/compare-eax-and 0/imm32/false - 6986 0f 85/jump-if-!= $populate-mu-function-header:error1/disp32 - 6987 # v = parse-var-with-type(word-slice, first-line) - 6988 (parse-var-with-type %ecx *(ebp+8) %ebx *(ebp+0x14) *(ebp+0x18)) - 6989 # assert(var->register != null) - 6990 # . eax: (addr var) = lookup(v) - 6991 (lookup *ebx *(ebx+4)) # => eax - 6992 81 7/subop/compare *(eax+0x18) 0/imm32 # Var-register - 6993 0f 84/jump-if-= $populate-mu-function-header:error3/disp32 - 6994 # out->outputs = append(v, out->outputs) - 6995 8d/copy-address *(edi+0x10) 0/r32/eax # Function-outputs - 6996 (append-list Heap *ebx *(ebx+4) *(edi+0x10) *(edi+0x14) %eax) # Function-outputs, Function-outputs - 6997 # - 6998 e9/jump loop/disp32 - 6999 } - 7000 $populate-mu-function-header:done: - 7001 (check-no-tokens-left *(ebp+8)) - 7002 $populate-mu-function-header:end: - 7003 # . reclaim locals - 7004 81 0/subop/add %esp 0x10/imm32 - 7005 # . restore registers - 7006 5f/pop-to-edi - 7007 5b/pop-to-ebx - 7008 5a/pop-to-edx - 7009 59/pop-to-ecx - 7010 58/pop-to-eax - 7011 # . epilogue - 7012 89/<- %esp 5/r32/ebp - 7013 5d/pop-to-ebp - 7014 c3/return - 7015 - 7016 $populate-mu-function-header:error1: - 7017 # error("function header not in form 'fn <name> {'") - 7018 (write-buffered *(ebp+0x14) "function header not in form 'fn <name> [inouts] [-> outputs] {' -- '") - 7019 (flush *(ebp+0x14)) - 7020 (rewind-stream *(ebp+8)) - 7021 (write-stream-data *(ebp+0x14) *(ebp+8)) - 7022 (write-buffered *(ebp+0x14) "'\n") - 7023 (flush *(ebp+0x14)) - 7024 (stop *(ebp+0x18) 1) - 7025 # never gets here - 7026 - 7027 $populate-mu-function-header:error2: - 7028 # error("fn " fn ": function inout '" var "' cannot be in a register") - 7029 (write-buffered *(ebp+0x14) "fn ") - 7030 50/push-eax - 7031 (lookup *edi *(edi+4)) # Function-name Function-name => eax - 7032 (write-buffered *(ebp+0x14) %eax) - 7033 58/pop-to-eax - 7034 (write-buffered *(ebp+0x14) ": function inout '") - 7035 (lookup *eax *(eax+4)) # Var-name Var-name => eax - 7036 (write-buffered *(ebp+0x10) %eax) - 7037 (write-buffered *(ebp+0x14) "' cannot be in a register") - 7038 (flush *(ebp+0x14)) - 7039 (stop *(ebp+0x18) 1) - 7040 # never gets here - 7041 - 7042 $populate-mu-function-header:error3: - 7043 # error("fn " fn ": function output '" var "' must be in a register") - 7044 (write-buffered *(ebp+0x14) "fn ") - 7045 50/push-eax - 7046 (lookup *edi *(edi+4)) # Function-name Function-name => eax - 7047 (write-buffered *(ebp+0x14) %eax) - 7048 58/pop-to-eax - 7049 (write-buffered *(ebp+0x14) ": function output '") - 7050 (lookup *ebx *(ebx+4)) # => eax - 7051 (lookup *eax *(eax+4)) # Var-name Var-name => eax - 7052 (write-buffered *(ebp+0x14) %eax) - 7053 (write-buffered *(ebp+0x14) "' must be in a register, in instruction '") - 7054 (rewind-stream *(ebp+8)) - 7055 (write-stream-data *(ebp+0x14) *(ebp+8)) - 7056 (write-buffered *(ebp+0x14) "'\n") - 7057 (flush *(ebp+0x14)) - 7058 (stop *(ebp+0x18) 1) - 7059 # never gets here - 7060 - 7061 # scenarios considered: - 7062 # ✓ fn foo - 7063 # ✗ fn foo { - 7064 # ✓ fn foo x - 7065 # ✓ fn foo x: int - 7066 # ✓ fn foo x: int -> y/eax: int - 7067 # TODO: - 7068 # disallow outputs of type `(... addr ...)` - 7069 # disallow inputs of type `(... addr ... addr ...)` - 7070 populate-mu-function-signature: # first-line: (addr stream byte), out: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) - 7071 # pseudocode: - 7072 # var word-slice: slice - 7073 # next-mu-token(first-line, word-slice) - 7074 # assert(word-slice not in '{' '}' '->') - 7075 # out->name = slice-to-string(word-slice) - 7076 # ## inouts - 7077 # while true - 7078 # word-slice = next-mu-token(first-line) - 7079 # if slice-empty?(word-slice) break - 7080 # if (word-slice == '->') break - 7081 # assert(word-slice not in '{' '}') - 7082 # var v: (handle var) = parse-var-with-type(word-slice, first-line) - 7083 # assert(v->register == null) - 7084 # # v->block-depth is implicitly 0 - 7085 # out->inouts = append(v, out->inouts) - 7086 # ## outputs - 7087 # while true - 7088 # word-slice = next-mu-token(first-line) - 7089 # if slice-empty?(word-slice) break - 7090 # assert(word-slice not in '{' '}' '->') - 7091 # var v: (handle var) = parse-var-with-type(word-slice, first-line) - 7092 # assert(v->register != null) - 7093 # out->outputs = append(v, out->outputs) - 7094 # - 7095 # . prologue - 7096 55/push-ebp - 7097 89/<- %ebp 4/r32/esp - 7098 # . save registers - 7099 50/push-eax - 7100 51/push-ecx - 7101 52/push-edx - 7102 53/push-ebx - 7103 57/push-edi - 7104 # edi = out - 7105 8b/-> *(ebp+0xc) 7/r32/edi - 7106 # var word-slice/ecx: slice - 7107 68/push 0/imm32/end - 7108 68/push 0/imm32/start - 7109 89/<- %ecx 4/r32/esp - 7110 # var v/ebx: (handle var) - 7111 68/push 0/imm32 - 7112 68/push 0/imm32 - 7113 89/<- %ebx 4/r32/esp - 7114 # read function name - 7115 (next-mu-token *(ebp+8) %ecx) - 7116 # error checking - 7117 # if (word-slice == '{') abort - 7118 (slice-equal? %ecx "{") # => eax - 7119 3d/compare-eax-and 0/imm32/false - 7120 0f 85/jump-if-!= $populate-mu-function-signature:error1/disp32 - 7121 # if (word-slice == '->') abort - 7122 (slice-equal? %ecx "->") # => eax - 7123 3d/compare-eax-and 0/imm32/false - 7124 0f 85/jump-if-!= $populate-mu-function-signature:error1/disp32 - 7125 # if (word-slice == '}') abort - 7126 (slice-equal? %ecx "}") # => eax - 7127 3d/compare-eax-and 0/imm32/false - 7128 0f 85/jump-if-!= $populate-mu-function-signature:error1/disp32 - 7129 # save function name - 7130 (slice-to-string Heap %ecx %edi) # Function-name - 7131 # save function inouts - 7132 { - 7133 $populate-mu-function-signature:check-for-inout: - 7134 (next-mu-token *(ebp+8) %ecx) - 7135 (slice-empty? %ecx) # => eax - 7136 3d/compare-eax-and 0/imm32/false - 7137 0f 85/jump-if-!= break/disp32 - 7138 # if (word-slice == '->') break - 7139 (slice-equal? %ecx "->") # => eax - 7140 3d/compare-eax-and 0/imm32/false - 7141 0f 85/jump-if-!= break/disp32 - 7142 # if (word-slice == '{') abort - 7143 (slice-equal? %ecx "{") # => eax - 7144 3d/compare-eax-and 0/imm32/false - 7145 0f 85/jump-if-!= $populate-mu-function-signature:error1/disp32 - 7146 # if (word-slice == '}') abort - 7147 (slice-equal? %ecx "}") # => eax - 7148 3d/compare-eax-and 0/imm32/false - 7149 0f 85/jump-if-!= $populate-mu-function-signature:error1/disp32 - 7150 # v = parse-var-with-type(word-slice, first-line) - 7151 (parse-var-with-type %ecx *(ebp+8) %ebx *(ebp+0x10) *(ebp+0x14)) - 7152 # assert(v->register == null) - 7153 # . eax: (addr var) = lookup(v) - 7154 (lookup *ebx *(ebx+4)) # => eax - 7155 81 7/subop/compare *(eax+0x18) 0/imm32 # Var-register - 7156 0f 85/jump-if-!= $populate-mu-function-signature:error2/disp32 - 7157 # v->block-depth is implicitly 0 - 7158 # - 7159 # out->inouts = append(v, out->inouts) - 7160 8d/copy-address *(edi+8) 0/r32/eax # Function-inouts - 7161 (append-list Heap *ebx *(ebx+4) *(edi+8) *(edi+0xc) %eax) # Function-inouts, Function-inouts - 7162 # - 7163 e9/jump loop/disp32 - 7164 } - 7165 # save function outputs - 7166 { - 7167 $populate-mu-function-signature:check-for-out: - 7168 (next-mu-token *(ebp+8) %ecx) - 7169 (slice-empty? %ecx) # => eax - 7170 3d/compare-eax-and 0/imm32/false - 7171 0f 85/jump-if-!= break/disp32 - 7172 # if (word-slice == '{') abort - 7173 (slice-equal? %ecx "{") # => eax - 7174 3d/compare-eax-and 0/imm32/false - 7175 0f 85/jump-if-!= $populate-mu-function-signature:error1/disp32 - 7176 # if (word-slice == '->') abort - 7177 (slice-equal? %ecx "->") # => eax - 7178 3d/compare-eax-and 0/imm32/false - 7179 0f 85/jump-if-!= $populate-mu-function-signature:error1/disp32 - 7180 # if (word-slice == '}') abort - 7181 (slice-equal? %ecx "}") # => eax - 7182 3d/compare-eax-and 0/imm32/false - 7183 0f 85/jump-if-!= $populate-mu-function-signature:error1/disp32 - 7184 # v = parse-var-with-type(word-slice, first-line) - 7185 (parse-var-with-type %ecx *(ebp+8) %ebx *(ebp+0x10) *(ebp+0x14)) - 7186 # assert(var->register != null) - 7187 # . eax: (addr var) = lookup(v) - 7188 (lookup *ebx *(ebx+4)) # => eax - 7189 81 7/subop/compare *(eax+0x18) 0/imm32 # Var-register - 7190 0f 84/jump-if-= $populate-mu-function-signature:error3/disp32 - 7191 # out->outputs = append(v, out->outputs) - 7192 8d/copy-address *(edi+0x10) 0/r32/eax # Function-outputs - 7193 (append-list Heap *ebx *(ebx+4) *(edi+0x10) *(edi+0x14) %eax) # Function-outputs, Function-outputs - 7194 # - 7195 e9/jump loop/disp32 - 7196 } - 7197 $populate-mu-function-signature:done: - 7198 (check-no-tokens-left *(ebp+8)) - 7199 $populate-mu-function-signature:end: - 7200 # . reclaim locals - 7201 81 0/subop/add %esp 0x10/imm32 - 7202 # . restore registers - 7203 5f/pop-to-edi - 7204 5b/pop-to-ebx - 7205 5a/pop-to-edx - 7206 59/pop-to-ecx - 7207 58/pop-to-eax - 7208 # . epilogue - 7209 89/<- %esp 5/r32/ebp - 7210 5d/pop-to-ebp - 7211 c3/return - 7212 - 7213 $populate-mu-function-signature:error1: - 7214 # error("function signature not in form 'fn <name> {'") - 7215 (write-buffered *(ebp+0x10) "function signature not in form 'fn <name> [inouts] [-> outputs] {' -- '") - 7216 (flush *(ebp+0x10)) - 7217 (rewind-stream *(ebp+8)) - 7218 (write-stream-data *(ebp+0x10) *(ebp+8)) - 7219 (write-buffered *(ebp+0x10) "'\n") - 7220 (flush *(ebp+0x10)) - 7221 (stop *(ebp+0x14) 1) - 7222 # never gets here - 7223 - 7224 $populate-mu-function-signature:error2: - 7225 # error("fn " fn ": function inout '" var "' cannot be in a register") - 7226 (write-buffered *(ebp+0x10) "fn ") - 7227 50/push-eax - 7228 (lookup *edi *(edi+4)) # Function-name Function-name => eax - 7229 (write-buffered *(ebp+0x10) %eax) - 7230 58/pop-to-eax - 7231 (write-buffered *(ebp+0x10) ": function inout '") - 7232 (lookup *eax *(eax+4)) # Var-name Var-name => eax - 7233 (write-buffered *(ebp+0x10) %eax) - 7234 (write-buffered *(ebp+0x10) "' cannot be in a register") - 7235 (flush *(ebp+0x10)) - 7236 (stop *(ebp+0x14) 1) - 7237 # never gets here - 7238 - 7239 $populate-mu-function-signature:error3: - 7240 # error("fn " fn ": function output '" var "' must be in a register") - 7241 (write-buffered *(ebp+0x10) "fn ") - 7242 50/push-eax - 7243 (lookup *edi *(edi+4)) # Function-name Function-name => eax - 7244 (write-buffered *(ebp+0x10) %eax) - 7245 58/pop-to-eax - 7246 (write-buffered *(ebp+0x10) ": function output '") - 7247 (lookup *ebx *(ebx+4)) # => eax - 7248 (lookup *eax *(eax+4)) # Var-name Var-name => eax - 7249 (write-buffered *(ebp+0x10) %eax) - 7250 (write-buffered *(ebp+0x10) "' must be in a register, in instruction '") - 7251 (rewind-stream *(ebp+8)) - 7252 (write-stream-data *(ebp+0x10) *(ebp+8)) - 7253 (write-buffered *(ebp+0x10) "'\n") - 7254 (flush *(ebp+0x10)) - 7255 (stop *(ebp+0x14) 1) - 7256 # never gets here - 7257 - 7258 test-function-header-with-arg: - 7259 # . prologue - 7260 55/push-ebp - 7261 89/<- %ebp 4/r32/esp - 7262 # setup - 7263 (clear-stream _test-input-stream) - 7264 (write _test-input-stream "foo n: int {\n") - 7265 # var result/ecx: function - 7266 2b/subtract *Function-size 4/r32/esp - 7267 89/<- %ecx 4/r32/esp - 7268 (zero-out %ecx *Function-size) - 7269 # var vars/ebx: (stack live-var 16) - 7270 81 5/subop/subtract %esp 0xc0/imm32 - 7271 68/push 0xc0/imm32/size - 7272 68/push 0/imm32/top - 7273 89/<- %ebx 4/r32/esp + 6840 test-index-with-array-base-in-register: + 6841 # . prologue + 6842 55/push-ebp + 6843 89/<- %ebp 4/r32/esp + 6844 # setup + 6845 (clear-stream _test-input-stream) + 6846 (clear-stream $_test-input-buffered-file->buffer) + 6847 (clear-stream _test-output-stream) + 6848 (clear-stream $_test-output-buffered-file->buffer) + 6849 (clear-stream _test-error-stream) + 6850 (clear-stream $_test-error-buffered-file->buffer) + 6851 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 6852 68/push 0/imm32 + 6853 68/push 0/imm32 + 6854 89/<- %edx 4/r32/esp + 6855 (tailor-exit-descriptor %edx 0x10) + 6856 # + 6857 (write _test-input-stream "fn foo {\n") + 6858 (write _test-input-stream " var a/eax: (array int 3) <- copy 0\n") + 6859 (write _test-input-stream " var c/ecx: (addr int) <- index a, 0\n") + 6860 (write _test-input-stream "}\n") + 6861 # convert + 6862 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 6863 # registers except esp clobbered at this point + 6864 # restore ed + 6865 89/<- %edx 4/r32/esp + 6866 (flush _test-output-buffered-file) + 6867 (flush _test-error-buffered-file) + 6868 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 6874 # check output + 6875 (check-stream-equal _test-output-stream "" "F - test-index-with-array-base-in-register: output should be empty") + 6876 (check-next-stream-line-equal _test-error-stream "fn foo: stmt index: var 'a' is an array, and so must live on the stack" "F - test-index-with-array-base-in-register: error message") + 6877 # check that stop(1) was called + 6878 (check-ints-equal *(edx+4) 2 "F - test-index-with-array-base-in-register: exit status") + 6879 # don't restore from ebp + 6880 81 0/subop/add %esp 8/imm32 + 6881 # . epilogue + 6882 5d/pop-to-ebp + 6883 c3/return + 6884 + 6885 test-index-with-wrong-index-type: + 6886 # . prologue + 6887 55/push-ebp + 6888 89/<- %ebp 4/r32/esp + 6889 # setup + 6890 (clear-stream _test-input-stream) + 6891 (clear-stream $_test-input-buffered-file->buffer) + 6892 (clear-stream _test-output-stream) + 6893 (clear-stream $_test-output-buffered-file->buffer) + 6894 (clear-stream _test-error-stream) + 6895 (clear-stream $_test-error-buffered-file->buffer) + 6896 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 6897 68/push 0/imm32 + 6898 68/push 0/imm32 + 6899 89/<- %edx 4/r32/esp + 6900 (tailor-exit-descriptor %edx 0x10) + 6901 # + 6902 (write _test-input-stream "fn foo {\n") + 6903 (write _test-input-stream " var a/eax: (addr array int) <- copy 0\n") + 6904 (write _test-input-stream " var b: boolean\n") + 6905 (write _test-input-stream " var c/ecx: (addr int) <- index a, b\n") + 6906 (write _test-input-stream "}\n") + 6907 # convert + 6908 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 6909 # registers except esp clobbered at this point + 6910 # restore ed + 6911 89/<- %edx 4/r32/esp + 6912 (flush _test-output-buffered-file) + 6913 (flush _test-error-buffered-file) + 6914 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 6920 # check output + 6921 (check-stream-equal _test-output-stream "" "F - test-index-with-wrong-index-type: output should be empty") + 6922 (check-next-stream-line-equal _test-error-stream "fn foo: stmt index: second argument 'b' must be an int or offset" "F - test-index-with-wrong-index-type: error message") + 6923 # check that stop(1) was called + 6924 (check-ints-equal *(edx+4) 2 "F - test-index-with-wrong-index-type: exit status") + 6925 # don't restore from ebp + 6926 81 0/subop/add %esp 8/imm32 + 6927 # . epilogue + 6928 5d/pop-to-ebp + 6929 c3/return + 6930 + 6931 test-index-with-offset-atom-index-type: + 6932 # . prologue + 6933 55/push-ebp + 6934 89/<- %ebp 4/r32/esp + 6935 # setup + 6936 (clear-stream _test-input-stream) + 6937 (clear-stream $_test-input-buffered-file->buffer) + 6938 (clear-stream _test-output-stream) + 6939 (clear-stream $_test-output-buffered-file->buffer) + 6940 (clear-stream _test-error-stream) + 6941 (clear-stream $_test-error-buffered-file->buffer) + 6942 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 6943 68/push 0/imm32 + 6944 68/push 0/imm32 + 6945 89/<- %edx 4/r32/esp + 6946 (tailor-exit-descriptor %edx 0x10) + 6947 # + 6948 (write _test-input-stream "fn foo {\n") + 6949 (write _test-input-stream " var a/eax: (addr array int) <- copy 0\n") + 6950 (write _test-input-stream " var b: offset\n") + 6951 (write _test-input-stream " var c/ecx: (addr int) <- index a, b\n") + 6952 (write _test-input-stream "}\n") + 6953 # convert + 6954 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 6955 # registers except esp clobbered at this point + 6956 # restore ed + 6957 89/<- %edx 4/r32/esp + 6958 (flush _test-output-buffered-file) + 6959 (flush _test-error-buffered-file) + 6960 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 6966 # check output + 6967 (check-stream-equal _test-output-stream "" "F - test-index-with-offset-atom-index-type: output should be empty") + 6968 (check-next-stream-line-equal _test-error-stream "fn foo: stmt index: offset 'b' must specify the type of array elements" "F - test-index-with-offset-atom-index-type: error message") + 6969 # check that stop(1) was called + 6970 (check-ints-equal *(edx+4) 2 "F - test-index-with-offset-atom-index-type: exit status") + 6971 # don't restore from ebp + 6972 81 0/subop/add %esp 8/imm32 + 6973 # . epilogue + 6974 5d/pop-to-ebp + 6975 c3/return + 6976 + 6977 test-index-with-offset-on-stack: + 6978 # . prologue + 6979 55/push-ebp + 6980 89/<- %ebp 4/r32/esp + 6981 # setup + 6982 (clear-stream _test-input-stream) + 6983 (clear-stream $_test-input-buffered-file->buffer) + 6984 (clear-stream _test-output-stream) + 6985 (clear-stream $_test-output-buffered-file->buffer) + 6986 (clear-stream _test-error-stream) + 6987 (clear-stream $_test-error-buffered-file->buffer) + 6988 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 6989 68/push 0/imm32 + 6990 68/push 0/imm32 + 6991 89/<- %edx 4/r32/esp + 6992 (tailor-exit-descriptor %edx 0x10) + 6993 # + 6994 (write _test-input-stream "fn foo {\n") + 6995 (write _test-input-stream " var a/eax: (addr array int) <- copy 0\n") + 6996 (write _test-input-stream " var b: int\n") + 6997 (write _test-input-stream " var c/ecx: (addr int) <- index a, b\n") + 6998 (write _test-input-stream "}\n") + 6999 # convert + 7000 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 7001 # registers except esp clobbered at this point + 7002 # restore ed + 7003 89/<- %edx 4/r32/esp + 7004 (flush _test-output-buffered-file) + 7005 (flush _test-error-buffered-file) + 7006 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 7012 # check output + 7013 (check-stream-equal _test-output-stream "" "F - test-index-with-offset-on-stack: output should be empty") + 7014 (check-next-stream-line-equal _test-error-stream "fn foo: stmt index: second argument 'b' must be in a register" "F - test-index-with-offset-on-stack: error message") + 7015 # check that stop(1) was called + 7016 (check-ints-equal *(edx+4) 2 "F - test-index-with-offset-on-stack: exit status") + 7017 # don't restore from ebp + 7018 81 0/subop/add %esp 8/imm32 + 7019 # . epilogue + 7020 5d/pop-to-ebp + 7021 c3/return + 7022 + 7023 test-index-needs-offset-type: + 7024 # . prologue + 7025 55/push-ebp + 7026 89/<- %ebp 4/r32/esp + 7027 # setup + 7028 (clear-stream _test-input-stream) + 7029 (clear-stream $_test-input-buffered-file->buffer) + 7030 (clear-stream _test-output-stream) + 7031 (clear-stream $_test-output-buffered-file->buffer) + 7032 (clear-stream _test-error-stream) + 7033 (clear-stream $_test-error-buffered-file->buffer) + 7034 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 7035 68/push 0/imm32 + 7036 68/push 0/imm32 + 7037 89/<- %edx 4/r32/esp + 7038 (tailor-exit-descriptor %edx 0x10) + 7039 # + 7040 (write _test-input-stream "fn foo {\n") + 7041 (write _test-input-stream " var a/eax: (addr array t) <- copy 0\n") + 7042 (write _test-input-stream " var b/ebx: int <- copy 0\n") + 7043 (write _test-input-stream " var c/ecx: (addr int) <- index a, b\n") + 7044 (write _test-input-stream "}\n") + 7045 (write _test-input-stream "type t {\n") # size 12 is not a power of two + 7046 (write _test-input-stream " x: int\n") + 7047 (write _test-input-stream " y: int\n") + 7048 (write _test-input-stream " z: int\n") + 7049 (write _test-input-stream "}\n") + 7050 # convert + 7051 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 7052 # registers except esp clobbered at this point + 7053 # restore ed + 7054 89/<- %edx 4/r32/esp + 7055 (flush _test-output-buffered-file) + 7056 (flush _test-error-buffered-file) + 7057 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 7063 # check output + 7064 (check-stream-equal _test-output-stream "" "F - test-index-needs-offset-type: output should be empty") + 7065 (check-next-stream-line-equal _test-error-stream "fn foo: stmt index: cannot take an int for array 'a'; create an offset instead. See mu_summary for details." "F - test-index-needs-offset-type: error message") + 7066 # check that stop(1) was called + 7067 (check-ints-equal *(edx+4) 2 "F - test-index-needs-offset-type: exit status") + 7068 # don't restore from ebp + 7069 81 0/subop/add %esp 8/imm32 + 7070 # . epilogue + 7071 5d/pop-to-ebp + 7072 c3/return + 7073 + 7074 test-index-with-output-not-address: + 7075 # . prologue + 7076 55/push-ebp + 7077 89/<- %ebp 4/r32/esp + 7078 # setup + 7079 (clear-stream _test-input-stream) + 7080 (clear-stream $_test-input-buffered-file->buffer) + 7081 (clear-stream _test-output-stream) + 7082 (clear-stream $_test-output-buffered-file->buffer) + 7083 (clear-stream _test-error-stream) + 7084 (clear-stream $_test-error-buffered-file->buffer) + 7085 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 7086 68/push 0/imm32 + 7087 68/push 0/imm32 + 7088 89/<- %edx 4/r32/esp + 7089 (tailor-exit-descriptor %edx 0x10) + 7090 # + 7091 (write _test-input-stream "fn foo {\n") + 7092 (write _test-input-stream " var a/ebx: (addr array boolean) <- copy 0\n") + 7093 (write _test-input-stream " var o/edi: int <- index a, 0\n") + 7094 (write _test-input-stream "}\n") + 7095 # convert + 7096 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 7097 # registers except esp clobbered at this point + 7098 # restore ed + 7099 89/<- %edx 4/r32/esp + 7100 (flush _test-output-buffered-file) + 7101 (flush _test-error-buffered-file) + 7102 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 7108 # check output + 7109 (check-stream-equal _test-output-stream "" "F - test-index-with-output-not-address: output should be empty") + 7110 (check-next-stream-line-equal _test-error-stream "fn foo: stmt index: output 'o' must be an address" "F - test-index-with-output-not-address: error message") + 7111 # check that stop(1) was called + 7112 (check-ints-equal *(edx+4) 2 "F - test-index-with-output-not-address: exit status") + 7113 # don't restore from ebp + 7114 81 0/subop/add %esp 8/imm32 + 7115 # . epilogue + 7116 5d/pop-to-ebp + 7117 c3/return + 7118 + 7119 test-index-with-output-not-address-2: + 7120 # . prologue + 7121 55/push-ebp + 7122 89/<- %ebp 4/r32/esp + 7123 # setup + 7124 (clear-stream _test-input-stream) + 7125 (clear-stream $_test-input-buffered-file->buffer) + 7126 (clear-stream _test-output-stream) + 7127 (clear-stream $_test-output-buffered-file->buffer) + 7128 (clear-stream _test-error-stream) + 7129 (clear-stream $_test-error-buffered-file->buffer) + 7130 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 7131 68/push 0/imm32 + 7132 68/push 0/imm32 + 7133 89/<- %edx 4/r32/esp + 7134 (tailor-exit-descriptor %edx 0x10) + 7135 # + 7136 (write _test-input-stream "fn foo {\n") + 7137 (write _test-input-stream " var a/ebx: (addr array boolean) <- copy 0\n") + 7138 (write _test-input-stream " var o/edi: (int) <- index a, 0\n") + 7139 (write _test-input-stream "}\n") + 7140 # convert + 7141 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 7142 # registers except esp clobbered at this point + 7143 # restore ed + 7144 89/<- %edx 4/r32/esp + 7145 (flush _test-output-buffered-file) + 7146 (flush _test-error-buffered-file) + 7147 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 7153 # check output + 7154 (check-stream-equal _test-output-stream "" "F - test-index-with-output-not-address-2: output should be empty") + 7155 (check-next-stream-line-equal _test-error-stream "fn foo: stmt index: output 'o' must be an address" "F - test-index-with-output-not-address-2: error message") + 7156 # check that stop(1) was called + 7157 (check-ints-equal *(edx+4) 2 "F - test-index-with-output-not-address-2: exit status") + 7158 # don't restore from ebp + 7159 81 0/subop/add %esp 8/imm32 + 7160 # . epilogue + 7161 5d/pop-to-ebp + 7162 c3/return + 7163 + 7164 test-index-with-wrong-output-type: + 7165 # . prologue + 7166 55/push-ebp + 7167 89/<- %ebp 4/r32/esp + 7168 # setup + 7169 (clear-stream _test-input-stream) + 7170 (clear-stream $_test-input-buffered-file->buffer) + 7171 (clear-stream _test-output-stream) + 7172 (clear-stream $_test-output-buffered-file->buffer) + 7173 (clear-stream _test-error-stream) + 7174 (clear-stream $_test-error-buffered-file->buffer) + 7175 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 7176 68/push 0/imm32 + 7177 68/push 0/imm32 + 7178 89/<- %edx 4/r32/esp + 7179 (tailor-exit-descriptor %edx 0x10) + 7180 # + 7181 (write _test-input-stream "fn foo {\n") + 7182 (write _test-input-stream " var a/ebx: (addr array boolean) <- copy 0\n") + 7183 (write _test-input-stream " var o/edi: (addr int) <- index a, 0\n") + 7184 (write _test-input-stream "}\n") + 7185 # convert + 7186 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 7187 # registers except esp clobbered at this point + 7188 # restore ed + 7189 89/<- %edx 4/r32/esp + 7190 (flush _test-output-buffered-file) + 7191 (flush _test-error-buffered-file) + 7192 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 7198 # check output + 7199 (check-stream-equal _test-output-stream "" "F - test-index-with-wrong-output-type: output should be empty") + 7200 (check-next-stream-line-equal _test-error-stream "fn foo: stmt index: output 'o' does not have the right type" "F - test-index-with-wrong-output-type: error message") + 7201 # check that stop(1) was called + 7202 (check-ints-equal *(edx+4) 2 "F - test-index-with-wrong-output-type: exit status") + 7203 # don't restore from ebp + 7204 81 0/subop/add %esp 8/imm32 + 7205 # . epilogue + 7206 5d/pop-to-ebp + 7207 c3/return + 7208 + 7209 test-index-with-wrong-output-compound-type: + 7210 # . prologue + 7211 55/push-ebp + 7212 89/<- %ebp 4/r32/esp + 7213 # setup + 7214 (clear-stream _test-input-stream) + 7215 (clear-stream $_test-input-buffered-file->buffer) + 7216 (clear-stream _test-output-stream) + 7217 (clear-stream $_test-output-buffered-file->buffer) + 7218 (clear-stream _test-error-stream) + 7219 (clear-stream $_test-error-buffered-file->buffer) + 7220 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 7221 68/push 0/imm32 + 7222 68/push 0/imm32 + 7223 89/<- %edx 4/r32/esp + 7224 (tailor-exit-descriptor %edx 0x10) + 7225 # + 7226 (write _test-input-stream "fn foo {\n") + 7227 (write _test-input-stream " var a/ebx: (addr array handle boolean) <- copy 0\n") + 7228 (write _test-input-stream " var o/edi: (addr handle int) <- index a, 0\n") + 7229 (write _test-input-stream "}\n") + 7230 # convert + 7231 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 7232 # registers except esp clobbered at this point + 7233 # restore ed + 7234 89/<- %edx 4/r32/esp + 7235 (flush _test-output-buffered-file) + 7236 (flush _test-error-buffered-file) + 7237 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 7243 # check output + 7244 (check-stream-equal _test-output-stream "" "F - test-index-with-wrong-output-compound-type: output should be empty") + 7245 (check-next-stream-line-equal _test-error-stream "fn foo: stmt index: output 'o' does not have the right type" "F - test-index-with-wrong-output-compound-type: error message") + 7246 # check that stop(1) was called + 7247 (check-ints-equal *(edx+4) 2 "F - test-index-with-wrong-output-compound-type: exit status") + 7248 # don't restore from ebp + 7249 81 0/subop/add %esp 8/imm32 + 7250 # . epilogue + 7251 5d/pop-to-ebp + 7252 c3/return + 7253 + 7254 test-index-with-no-inouts: + 7255 # . prologue + 7256 55/push-ebp + 7257 89/<- %ebp 4/r32/esp + 7258 # setup + 7259 (clear-stream _test-input-stream) + 7260 (clear-stream $_test-input-buffered-file->buffer) + 7261 (clear-stream _test-output-stream) + 7262 (clear-stream $_test-output-buffered-file->buffer) + 7263 (clear-stream _test-error-stream) + 7264 (clear-stream $_test-error-buffered-file->buffer) + 7265 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 7266 68/push 0/imm32 + 7267 68/push 0/imm32 + 7268 89/<- %edx 4/r32/esp + 7269 (tailor-exit-descriptor %edx 0x10) + 7270 # + 7271 (write _test-input-stream "fn foo {\n") + 7272 (write _test-input-stream " var c/ecx: (addr int) <- index\n") + 7273 (write _test-input-stream "}\n") 7274 # convert - 7275 (populate-mu-function-header _test-input-stream %ecx %ebx Stderr 0) - 7276 # check result->name - 7277 (lookup *ecx *(ecx+4)) # Function-name Function-name => eax - 7278 (check-strings-equal %eax "foo" "F - test-function-header-with-arg/name") - 7279 # var v/edx: (addr var) = result->inouts->value - 7280 (lookup *(ecx+8) *(ecx+0xc)) # Function-inouts Function-inouts => eax - 7281 (lookup *eax *(eax+4)) # List-value List-value => eax - 7282 89/<- %edx 0/r32/eax - 7283 # check v->name - 7284 (lookup *edx *(edx+4)) # Var-name Var-name => eax - 7285 (check-strings-equal %eax "n" "F - test-function-header-with-arg/inout:0") - 7286 # check v->type - 7287 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax - 7288 (check-ints-equal *eax 1 "F - test-function-header-with-arg/inout:0/type:0") # Type-tree-is-atom - 7289 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-arg/inout:0/type:1") # Type-tree-value - 7290 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-arg/inout:0/type:2") # Type-tree-right - 7291 # . epilogue - 7292 89/<- %esp 5/r32/ebp - 7293 5d/pop-to-ebp - 7294 c3/return - 7295 - 7296 test-function-header-with-multiple-args: - 7297 # . prologue - 7298 55/push-ebp - 7299 89/<- %ebp 4/r32/esp - 7300 # setup - 7301 (clear-stream _test-input-stream) - 7302 (write _test-input-stream "foo a: int, b: int c: int {\n") - 7303 # result/ecx: function - 7304 2b/subtract *Function-size 4/r32/esp - 7305 89/<- %ecx 4/r32/esp - 7306 (zero-out %ecx *Function-size) - 7307 # var vars/ebx: (stack live-var 16) - 7308 81 5/subop/subtract %esp 0xc0/imm32 - 7309 68/push 0xc0/imm32/size - 7310 68/push 0/imm32/top - 7311 89/<- %ebx 4/r32/esp - 7312 # convert - 7313 (populate-mu-function-header _test-input-stream %ecx %ebx Stderr 0) - 7314 # check result->name - 7315 (lookup *ecx *(ecx+4)) # Function-name Function-name => eax - 7316 (check-strings-equal %eax "foo" "F - test-function-header-with-multiple-args/name") - 7317 # var inouts/edx: (addr list var) = lookup(result->inouts) - 7318 (lookup *(ecx+8) *(ecx+0xc)) # Function-inouts Function-inouts => eax - 7319 89/<- %edx 0/r32/eax - 7320 $test-function-header-with-multiple-args:inout0: - 7321 # var v/ebx: (addr var) = lookup(inouts->value) - 7322 (lookup *edx *(edx+4)) # List-value List-value => eax - 7323 89/<- %ebx 0/r32/eax - 7324 # check v->name - 7325 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax - 7326 (check-strings-equal %eax "a" "F - test-function-header-with-multiple-args/inout:0") # Var-name - 7327 # check v->type - 7328 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax - 7329 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args/inout:0/type:0") # Type-tree-is-atom - 7330 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args/inout:0/type:1") # Type-tree-value - 7331 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-multiple-args/inout:0/type:2") # Type-tree-right - 7332 $test-function-header-with-multiple-args:inout1: - 7333 # inouts = lookup(inouts->next) - 7334 (lookup *(edx+8) *(edx+0xc)) # List-next List-next => eax - 7335 89/<- %edx 0/r32/eax - 7336 # v = lookup(inouts->value) - 7337 (lookup *edx *(edx+4)) # List-value List-value => eax - 7338 89/<- %ebx 0/r32/eax - 7339 # check v->name - 7340 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax - 7341 (check-strings-equal %eax "b" "F - test-function-header-with-multiple-args/inout:1") # Var-name - 7342 # check v->type - 7343 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax - 7344 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args/inout:1/type:0") # Type-tree-is-atom - 7345 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args/inout:1/type:1") # Type-tree-value - 7346 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-multiple-args/inout:1/type:2") # Type-tree-right - 7347 $test-function-header-with-multiple-args:inout2: - 7348 # inouts = lookup(inouts->next) - 7349 (lookup *(edx+8) *(edx+0xc)) # List-next List-next => eax - 7350 89/<- %edx 0/r32/eax - 7351 # v = lookup(inouts->value) - 7352 (lookup *edx *(edx+4)) # List-value List-value => eax - 7353 89/<- %ebx 0/r32/eax - 7354 # check v->name - 7355 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax - 7356 (check-strings-equal %eax "c" "F - test-function-header-with-multiple-args/inout:2") # Var-name - 7357 # check v->type - 7358 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax - 7359 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args/inout:2/type:0") # Type-tree-is-atom - 7360 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args/inout:2/type:1") # Type-tree-value - 7361 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-multiple-args/inout:2/type:2") # Type-tree-right - 7362 # . epilogue - 7363 89/<- %esp 5/r32/ebp - 7364 5d/pop-to-ebp - 7365 c3/return - 7366 - 7367 test-function-header-with-multiple-args-and-outputs: - 7368 # . prologue - 7369 55/push-ebp - 7370 89/<- %ebp 4/r32/esp - 7371 # setup - 7372 (clear-stream _test-input-stream) - 7373 (write _test-input-stream "foo a: int, b: int, c: int -> x/ecx: int y/edx: int {\n") - 7374 # result/ecx: function - 7375 2b/subtract *Function-size 4/r32/esp - 7376 89/<- %ecx 4/r32/esp - 7377 (zero-out %ecx *Function-size) - 7378 # var vars/ebx: (stack live-var 16) - 7379 81 5/subop/subtract %esp 0xc0/imm32 - 7380 68/push 0xc0/imm32/size - 7381 68/push 0/imm32/top - 7382 89/<- %ebx 4/r32/esp - 7383 # convert - 7384 (populate-mu-function-header _test-input-stream %ecx %ebx Stderr 0) - 7385 # check result->name - 7386 (lookup *ecx *(ecx+4)) # Function-name Function-name => eax - 7387 (check-strings-equal %eax "foo" "F - test-function-header-with-multiple-args-and-outputs/name") - 7388 # var inouts/edx: (addr list var) = lookup(result->inouts) - 7389 (lookup *(ecx+8) *(ecx+0xc)) # Function-inouts Function-inouts => eax - 7390 89/<- %edx 0/r32/eax - 7391 $test-function-header-with-multiple-args-and-outputs:inout0: - 7392 # var v/ebx: (addr var) = lookup(inouts->value) - 7393 (lookup *edx *(edx+4)) # List-value List-value => eax - 7394 89/<- %ebx 0/r32/eax - 7395 # check v->name - 7396 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax - 7397 (check-strings-equal %eax "a" "F - test-function-header-with-multiple-args-and-outputs/inout:0") - 7398 # check v->type - 7399 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax - 7400 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args-and-outputs/inout:0/type:0") # Type-tree-is-atom - 7401 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args-and-outputs/inout:0/type:1") # Type-tree-value - 7402 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-multiple-args-and-outputs/inout:0/type:2") # Type-tree-right - 7403 $test-function-header-with-multiple-args-and-outputs:inout1: - 7404 # inouts = lookup(inouts->next) - 7405 (lookup *(edx+8) *(edx+0xc)) # List-next List-next => eax - 7406 89/<- %edx 0/r32/eax - 7407 # v = lookup(inouts->value) - 7408 (lookup *edx *(edx+4)) # List-value List-value => eax - 7409 89/<- %ebx 0/r32/eax - 7410 # check v->name - 7411 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax - 7412 (check-strings-equal %eax "b" "F - test-function-header-with-multiple-args-and-outputs/inout:1") - 7413 # check v->type - 7414 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax - 7415 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args-and-outputs/inout:1/type:0") # Type-tree-is-atom - 7416 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args-and-outputs/inout:1/type:1") # Type-tree-value - 7417 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-multiple-args-and-outputs/inout:1/type:2") # Type-tree-right - 7418 $test-function-header-with-multiple-args-and-outputs:inout2: - 7419 # inouts = lookup(inouts->next) - 7420 (lookup *(edx+8) *(edx+0xc)) # List-next List-next => eax - 7421 89/<- %edx 0/r32/eax - 7422 # v = lookup(inouts->value) - 7423 (lookup *edx *(edx+4)) # List-value List-value => eax - 7424 89/<- %ebx 0/r32/eax - 7425 # check v->name - 7426 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax - 7427 (check-strings-equal %eax "c" "F - test-function-header-with-multiple-args-and-outputs/inout:2") - 7428 # check v->type - 7429 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax - 7430 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args-and-outputs/inout:2/type:0") # Type-tree-is-atom - 7431 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args-and-outputs/inout:2/type:1") # Type-tree-value - 7432 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-multiple-args-and-outputs/inout:2/type:2") # Type-tree-right - 7433 $test-function-header-with-multiple-args-and-outputs:out0: - 7434 # var outputs/edx: (addr list var) = lookup(result->outputs) - 7435 (lookup *(ecx+0x10) *(ecx+0x14)) # Function-outputs Function-outputs => eax - 7436 89/<- %edx 0/r32/eax - 7437 # v = lookup(outputs->value) - 7438 (lookup *edx *(edx+4)) # List-value List-value => eax - 7439 89/<- %ebx 0/r32/eax - 7440 # check v->name - 7441 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax - 7442 (check-strings-equal %eax "x" "F - test-function-header-with-multiple-args-and-outputs/output:0") - 7443 # check v->register - 7444 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register Var-register => eax - 7445 (check-strings-equal %eax "ecx" "F - test-function-header-with-multiple-args-and-outputs/output:0/register") - 7446 # check v->type - 7447 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax - 7448 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args-and-outputs/output:0/type:0") # Type-tree-is-atom - 7449 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args-and-outputs/output:0/type:1") # Type-tree-value - 7450 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-multiple-args-and-outputs/output:0/type:2") # Type-tree-right - 7451 $test-function-header-with-multiple-args-and-outputs:out1: - 7452 # outputs = lookup(outputs->next) - 7453 (lookup *(edx+8) *(edx+0xc)) # List-next List-next => eax - 7454 89/<- %edx 0/r32/eax - 7455 # v = lookup(inouts->value) - 7456 (lookup *edx *(edx+4)) # List-value List-value => eax - 7457 89/<- %ebx 0/r32/eax - 7458 # check v->name - 7459 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax - 7460 (check-strings-equal %eax "y" "F - test-function-header-with-multiple-args-and-outputs/output:1") - 7461 # check v->register - 7462 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register Var-register => eax - 7463 (check-strings-equal %eax "edx" "F - test-function-header-with-multiple-args-and-outputs/output:1/register") - 7464 # check v->type - 7465 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax - 7466 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args-and-outputs/output:1/type:0") # Type-tree-is-atom - 7467 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args-and-outputs/output:1/type:1") # Type-tree-value - 7468 (check-ints-equal *(eax+0c) 0 "F - test-function-header-with-multiple-args-and-outputs/output:1/type:2") # Type-tree-right - 7469 # . epilogue - 7470 89/<- %esp 5/r32/ebp - 7471 5d/pop-to-ebp - 7472 c3/return - 7473 - 7474 # format for variables with types - 7475 # x: int - 7476 # x: int, - 7477 # x/eax: int - 7478 # x/eax: int, - 7479 # ignores at most one trailing comma - 7480 # WARNING: modifies name - 7481 parse-var-with-type: # name: (addr slice), first-line: (addr stream byte), out: (addr handle var), err: (addr buffered-file), ed: (addr exit-descriptor) - 7482 # pseudocode: - 7483 # var s: slice - 7484 # if (!slice-ends-with(name, ":")) - 7485 # abort - 7486 # --name->end to skip ':' - 7487 # next-token-from-slice(name->start, name->end, '/', s) - 7488 # new-var-from-slice(s, out) - 7489 # ## register - 7490 # next-token-from-slice(s->end, name->end, '/', s) - 7491 # if (!slice-empty?(s)) - 7492 # out->register = slice-to-string(s) - 7493 # ## type - 7494 # var type: (handle type-tree) = parse-type(first-line) - 7495 # out->type = type - 7496 # - 7497 # . prologue - 7498 55/push-ebp - 7499 89/<- %ebp 4/r32/esp - 7500 # . save registers - 7501 50/push-eax - 7502 51/push-ecx - 7503 52/push-edx - 7504 53/push-ebx - 7505 56/push-esi - 7506 57/push-edi - 7507 # esi = name - 7508 8b/-> *(ebp+8) 6/r32/esi - 7509 # if (!slice-ends-with?(name, ":")) abort - 7510 8b/-> *(esi+4) 1/r32/ecx # Slice-end - 7511 49/decrement-ecx - 7512 8a/copy-byte *ecx 1/r32/CL - 7513 81 4/subop/and %ecx 0xff/imm32 - 7514 81 7/subop/compare %ecx 0x3a/imm32/colon - 7515 0f 85/jump-if-!= $parse-var-with-type:abort/disp32 - 7516 # --name->end to skip ':' - 7517 ff 1/subop/decrement *(esi+4) - 7518 # var s/ecx: slice - 7519 68/push 0/imm32/end - 7520 68/push 0/imm32/start - 7521 89/<- %ecx 4/r32/esp - 7522 $parse-var-with-type:parse-name: - 7523 (next-token-from-slice *esi *(esi+4) 0x2f %ecx) # Slice-start, Slice-end, '/' - 7524 $parse-var-with-type:create-var: - 7525 # new-var-from-slice(s, out) - 7526 (new-var-from-slice Heap %ecx *(ebp+0x10)) - 7527 # save out->register - 7528 $parse-var-with-type:save-register: - 7529 # . var out-addr/edi: (addr var) = lookup(*out) - 7530 8b/-> *(ebp+0x10) 7/r32/edi - 7531 (lookup *edi *(edi+4)) # => eax - 7532 89/<- %edi 0/r32/eax - 7533 # . s = next-token(...) - 7534 (next-token-from-slice *(ecx+4) *(esi+4) 0x2f %ecx) # s->end, name->end, '/' - 7535 # . if (!slice-empty?(s)) out->register = slice-to-string(s) - 7536 { - 7537 $parse-var-with-type:write-register: - 7538 (slice-empty? %ecx) # => eax - 7539 3d/compare-eax-and 0/imm32/false - 7540 75/jump-if-!= break/disp8 - 7541 # out->register = slice-to-string(s) - 7542 8d/copy-address *(edi+0x18) 0/r32/eax # Var-register - 7543 (slice-to-string Heap %ecx %eax) - 7544 } - 7545 $parse-var-with-type:save-type: - 7546 8d/copy-address *(edi+8) 0/r32/eax # Var-type - 7547 (parse-type Heap *(ebp+0xc) %eax *(ebp+0x14) *(ebp+0x18)) - 7548 $parse-var-with-type:end: - 7549 # . reclaim locals - 7550 81 0/subop/add %esp 8/imm32 - 7551 # . restore registers - 7552 5f/pop-to-edi - 7553 5e/pop-to-esi - 7554 5b/pop-to-ebx - 7555 5a/pop-to-edx - 7556 59/pop-to-ecx - 7557 58/pop-to-eax - 7558 # . epilogue - 7559 89/<- %esp 5/r32/ebp - 7560 5d/pop-to-ebp - 7561 c3/return - 7562 - 7563 $parse-var-with-type:abort: - 7564 # error("var should have form 'name: type' in '" line "'\n") - 7565 (write-buffered *(ebp+0x14) "var should have form 'name: type' in '") - 7566 (flush *(ebp+0x14)) - 7567 (rewind-stream *(ebp+0xc)) - 7568 (write-stream-data *(ebp+0x14) *(ebp+0xc)) - 7569 (write-buffered *(ebp+0x14) "'\n") - 7570 (flush *(ebp+0x14)) - 7571 (stop *(ebp+0x18) 1) - 7572 # never gets here - 7573 - 7574 parse-type: # ad: (addr allocation-descriptor), in: (addr stream byte), out: (addr handle type-tree), err: (addr buffered-file), ed: (addr exit-descriptor) - 7575 # pseudocode: - 7576 # var s: slice = next-mu-token(in) - 7577 # assert s != "" - 7578 # assert s != "->" - 7579 # assert s != "{" - 7580 # assert s != "}" - 7581 # if s == ")" - 7582 # return - 7583 # out = allocate(Type-tree) - 7584 # if s != "(" - 7585 # HACK: if s is an int, parse and return it - 7586 # out->is-atom? = true - 7587 # if (s[0] == "_") - 7588 # out->value = type-parameter - 7589 # out->parameter-name = slice-to-string(ad, s) - 7590 # else - 7591 # out->value = pos-or-insert-slice(Type-id, s) - 7592 # return - 7593 # out->left = parse-type(ad, in) - 7594 # out->right = parse-type-tree(ad, in) - 7595 # - 7596 # . prologue - 7597 55/push-ebp - 7598 89/<- %ebp 4/r32/esp - 7599 # . save registers - 7600 50/push-eax - 7601 51/push-ecx - 7602 52/push-edx - 7603 # clear out - 7604 (zero-out *(ebp+0x10) *Handle-size) - 7605 # var s/ecx: slice - 7606 68/push 0/imm32 - 7607 68/push 0/imm32 - 7608 89/<- %ecx 4/r32/esp - 7609 # s = next-mu-token(in) - 7610 (next-mu-token *(ebp+0xc) %ecx) - 7611 #? (write-buffered Stderr "tok: ") - 7612 #? (write-slice-buffered Stderr %ecx) - 7613 #? (write-buffered Stderr "$\n") - 7614 #? (flush Stderr) - 7615 # assert s != "" - 7616 (slice-equal? %ecx "") # => eax - 7617 3d/compare-eax-and 0/imm32/false - 7618 0f 85/jump-if-!= $parse-type:abort/disp32 - 7619 # assert s != "{" - 7620 (slice-equal? %ecx "{") # => eax - 7621 3d/compare-eax-and 0/imm32/false - 7622 0f 85/jump-if-!= $parse-type:abort/disp32 - 7623 # assert s != "}" - 7624 (slice-equal? %ecx "}") # => eax - 7625 3d/compare-eax-and 0/imm32/false - 7626 0f 85/jump-if-!= $parse-type:abort/disp32 - 7627 # assert s != "->" - 7628 (slice-equal? %ecx "->") # => eax - 7629 3d/compare-eax-and 0/imm32/false - 7630 0f 85/jump-if-!= $parse-type:abort/disp32 - 7631 # if (s == ")") return - 7632 (slice-equal? %ecx ")") # => eax - 7633 3d/compare-eax-and 0/imm32/false - 7634 0f 85/jump-if-!= $parse-type:end/disp32 - 7635 # out = new tree - 7636 (allocate *(ebp+8) *Type-tree-size *(ebp+0x10)) - 7637 # var out-addr/edx: (addr type-tree) = lookup(*out) - 7638 8b/-> *(ebp+0x10) 2/r32/edx - 7639 (lookup *edx *(edx+4)) # => eax - 7640 89/<- %edx 0/r32/eax - 7641 { - 7642 # if (s != "(") break - 7643 (slice-equal? %ecx "(") # => eax - 7644 3d/compare-eax-and 0/imm32/false - 7645 0f 85/jump-if-!= break/disp32 - 7646 # if s is a number, store it in the type's size field - 7647 { - 7648 $parse-type:check-for-int: - 7649 # var tmp/eax: byte = *s->slice - 7650 8b/-> *ecx 0/r32/eax - 7651 8a/copy-byte *eax 0/r32/AL - 7652 81 4/subop/and %eax 0xff/imm32 - 7653 # TODO: raise an error on `var x: (array int a)` - 7654 (is-decimal-digit? %eax) # => eax - 7655 3d/compare-eax-and 0/imm32/false - 7656 74/jump-if-= break/disp8 - 7657 # - 7658 (is-hex-int? %ecx) # => eax - 7659 3d/compare-eax-and 0/imm32/false - 7660 74/jump-if-= break/disp8 - 7661 $parse-type:int: - 7662 (check-mu-hex-int %ecx *(ebp+0x14) *(ebp+0x18)) - 7663 (parse-hex-int-from-slice %ecx) # => eax - 7664 c7 0/subop/copy *(edx+4) 9/imm32/type-id-array-capacity # Type-tree-value - 7665 89/<- *(edx+8) 0/r32/eax # Type-tree-value-size - 7666 e9/jump $parse-type:end/disp32 - 7667 } - 7668 $parse-type:atom: - 7669 # out->is-atom? = true - 7670 c7 0/subop/copy *edx 1/imm32/true # Type-tree-is-atom - 7671 { - 7672 $parse-type:check-for-type-parameter: - 7673 # var tmp/eax: byte = *s->slice - 7674 8b/-> *ecx 0/r32/eax - 7675 8a/copy-byte *eax 0/r32/AL - 7676 81 4/subop/and %eax 0xff/imm32 - 7677 # if (tmp != '_') break - 7678 3d/compare-eax-and 0x5f/imm32/_ - 7679 75/jump-if-!= break/disp8 - 7680 $parse-type:type-parameter: - 7681 # out->value = type-parameter - 7682 c7 0/subop/copy *(edx+4) 0xa/imm32/type-parameter # Type-tree-value - 7683 # out->parameter-name = slice-to-string(ad, s) - 7684 8d/copy-address *(edx+8) 0/r32/eax # Type-tree-parameter-name - 7685 (slice-to-string *(ebp+8) %ecx %eax) - 7686 e9/jump $parse-type:end/disp32 - 7687 } - 7688 $parse-type:non-type-parameter: - 7689 # out->value = pos-or-insert-slice(Type-id, s) - 7690 (pos-or-insert-slice Type-id %ecx) # => eax - 7691 89/<- *(edx+4) 0/r32/eax # Type-tree-value - 7692 e9/jump $parse-type:end/disp32 - 7693 } - 7694 $parse-type:non-atom: - 7695 # otherwise s == "(" - 7696 # out->left = parse-type(ad, in) - 7697 8d/copy-address *(edx+4) 0/r32/eax # Type-tree-left - 7698 (parse-type *(ebp+8) *(ebp+0xc) %eax *(ebp+0x14) *(ebp+0x18)) - 7699 # out->right = parse-type-tree(ad, in) - 7700 8d/copy-address *(edx+0xc) 0/r32/eax # Type-tree-right - 7701 (parse-type-tree *(ebp+8) *(ebp+0xc) %eax *(ebp+0x14) *(ebp+0x18)) - 7702 $parse-type:end: - 7703 # . reclaim locals - 7704 81 0/subop/add %esp 8/imm32 - 7705 # . restore registers - 7706 5a/pop-to-edx - 7707 59/pop-to-ecx - 7708 58/pop-to-eax - 7709 # . epilogue - 7710 89/<- %esp 5/r32/ebp - 7711 5d/pop-to-ebp - 7712 c3/return - 7713 - 7714 $parse-type:abort: - 7715 # error("unexpected token when parsing type: '" s "'\n") - 7716 (write-buffered *(ebp+0x14) "unexpected token when parsing type: '") - 7717 (write-slice-buffered *(ebp+0x14) %ecx) - 7718 (write-buffered *(ebp+0x14) "'\n") - 7719 (flush *(ebp+0x14)) - 7720 (stop *(ebp+0x18) 1) - 7721 # never gets here - 7722 - 7723 parse-type-tree: # ad: (addr allocation-descriptor), in: (addr stream byte), out: (addr handle type-tree), err: (addr buffered-file), ed: (addr exit-descriptor) - 7724 # pseudocode: - 7725 # var tmp: (handle type-tree) = parse-type(ad, in) - 7726 # if tmp == 0 - 7727 # return 0 - 7728 # out = allocate(Type-tree) - 7729 # out->left = tmp - 7730 # out->right = parse-type-tree(ad, in) - 7731 # - 7732 # . prologue - 7733 55/push-ebp - 7734 89/<- %ebp 4/r32/esp - 7735 # . save registers - 7736 50/push-eax - 7737 51/push-ecx - 7738 52/push-edx - 7739 # - 7740 (zero-out *(ebp+0x10) *Handle-size) - 7741 # var tmp/ecx: (handle type-tree) - 7742 68/push 0/imm32 - 7743 68/push 0/imm32 - 7744 89/<- %ecx 4/r32/esp - 7745 # tmp = parse-type(ad, in) - 7746 (parse-type *(ebp+8) *(ebp+0xc) %ecx *(ebp+0x14) *(ebp+0x18)) - 7747 # if (tmp == 0) return - 7748 81 7/subop/compare *ecx 0/imm32 - 7749 74/jump-if-= $parse-type-tree:end/disp8 - 7750 # out = new tree - 7751 (allocate *(ebp+8) *Type-tree-size *(ebp+0x10)) - 7752 # var out-addr/edx: (addr tree) = lookup(*out) - 7753 8b/-> *(ebp+0x10) 2/r32/edx - 7754 (lookup *edx *(edx+4)) # => eax - 7755 89/<- %edx 0/r32/eax - 7756 # out->left = tmp - 7757 8b/-> *ecx 0/r32/eax - 7758 89/<- *(edx+4) 0/r32/eax # Type-tree-left - 7759 8b/-> *(ecx+4) 0/r32/eax - 7760 89/<- *(edx+8) 0/r32/eax # Type-tree-left - 7761 # out->right = parse-type-tree(ad, in) - 7762 8d/copy-address *(edx+0xc) 0/r32/eax # Type-tree-right - 7763 (parse-type-tree *(ebp+8) *(ebp+0xc) %eax *(ebp+0x14) *(ebp+0x18)) - 7764 $parse-type-tree:end: - 7765 # . reclaim locals - 7766 81 0/subop/add %esp 8/imm32 - 7767 # . restore registers - 7768 5a/pop-to-edx - 7769 59/pop-to-ecx - 7770 58/pop-to-eax - 7771 # . epilogue - 7772 89/<- %esp 5/r32/ebp - 7773 5d/pop-to-ebp - 7774 c3/return - 7775 - 7776 next-mu-token: # in: (addr stream byte), out: (addr slice) - 7777 # pseudocode: - 7778 # start: - 7779 # skip-chars-matching-whitespace(in) - 7780 # if in->read >= in->write # end of in - 7781 # out = {0, 0} - 7782 # return - 7783 # out->start = &in->data[in->read] - 7784 # var curr-byte/eax: byte = in->data[in->read] - 7785 # if curr->byte == ',' # comment token - 7786 # ++in->read - 7787 # goto start - 7788 # if curr-byte == '#' # comment - 7789 # goto done # treat as eof - 7790 # if curr-byte == '"' # string literal - 7791 # skip-string(in) - 7792 # goto done # no metadata - 7793 # if curr-byte == '(' - 7794 # ++in->read - 7795 # goto done - 7796 # if curr-byte == ')' - 7797 # ++in->read - 7798 # goto done - 7799 # # read a word - 7800 # while true - 7801 # if in->read >= in->write - 7802 # break - 7803 # curr-byte = in->data[in->read] - 7804 # if curr-byte == ' ' - 7805 # break - 7806 # if curr-byte == '\r' - 7807 # break - 7808 # if curr-byte == '\n' - 7809 # break - 7810 # if curr-byte == '(' - 7811 # break - 7812 # if curr-byte == ')' - 7813 # break - 7814 # if curr-byte == ',' - 7815 # break - 7816 # ++in->read - 7817 # done: - 7818 # out->end = &in->data[in->read] - 7819 # - 7820 # . prologue - 7821 55/push-ebp - 7822 89/<- %ebp 4/r32/esp - 7823 # . save registers - 7824 50/push-eax - 7825 51/push-ecx - 7826 56/push-esi - 7827 57/push-edi - 7828 # esi = in - 7829 8b/-> *(ebp+8) 6/r32/esi - 7830 # edi = out - 7831 8b/-> *(ebp+0xc) 7/r32/edi - 7832 $next-mu-token:start: - 7833 (skip-chars-matching-whitespace %esi) - 7834 $next-mu-token:check0: - 7835 # if (in->read >= in->write) return out = {0, 0} - 7836 # . ecx = in->read - 7837 8b/-> *(esi+4) 1/r32/ecx - 7838 # . if (ecx >= in->write) return out = {0, 0} - 7839 3b/compare<- *esi 1/r32/ecx - 7840 c7 0/subop/copy *edi 0/imm32 - 7841 c7 0/subop/copy *(edi+4) 0/imm32 - 7842 0f 8d/jump-if->= $next-mu-token:end/disp32 - 7843 # out->start = &in->data[in->read] - 7844 8d/copy-address *(esi+ecx+0xc) 0/r32/eax - 7845 89/<- *edi 0/r32/eax - 7846 # var curr-byte/eax: byte = in->data[in->read] - 7847 31/xor-with %eax 0/r32/eax - 7848 8a/copy-byte *(esi+ecx+0xc) 0/r32/AL - 7849 { - 7850 $next-mu-token:check-for-comma: - 7851 # if (curr-byte != ',') break - 7852 3d/compare-eax-and 0x2c/imm32/comma - 7853 75/jump-if-!= break/disp8 - 7854 # ++in->read - 7855 ff 0/subop/increment *(esi+4) - 7856 # restart - 7857 e9/jump $next-mu-token:start/disp32 - 7858 } - 7859 { - 7860 $next-mu-token:check-for-comment: - 7861 # if (curr-byte != '#') break - 7862 3d/compare-eax-and 0x23/imm32/pound - 7863 75/jump-if-!= break/disp8 - 7864 # return eof - 7865 e9/jump $next-mu-token:done/disp32 - 7866 } - 7867 { - 7868 $next-mu-token:check-for-string-literal: - 7869 # if (curr-byte != '"') break - 7870 3d/compare-eax-and 0x22/imm32/dquote - 7871 75/jump-if-!= break/disp8 - 7872 (skip-string %esi) - 7873 # return - 7874 e9/jump $next-mu-token:done/disp32 - 7875 } - 7876 { - 7877 $next-mu-token:check-for-open-paren: - 7878 # if (curr-byte != '(') break - 7879 3d/compare-eax-and 0x28/imm32/open-paren - 7880 75/jump-if-!= break/disp8 - 7881 # ++in->read - 7882 ff 0/subop/increment *(esi+4) - 7883 # return - 7884 e9/jump $next-mu-token:done/disp32 - 7885 } - 7886 { - 7887 $next-mu-token:check-for-close-paren: - 7888 # if (curr-byte != ')') break - 7889 3d/compare-eax-and 0x29/imm32/close-paren - 7890 75/jump-if-!= break/disp8 - 7891 # ++in->read - 7892 ff 0/subop/increment *(esi+4) - 7893 # return - 7894 e9/jump $next-mu-token:done/disp32 - 7895 } - 7896 { - 7897 $next-mu-token:regular-word-without-metadata: - 7898 # if (in->read >= in->write) break - 7899 # . ecx = in->read - 7900 8b/-> *(esi+4) 1/r32/ecx - 7901 # . if (ecx >= in->write) break - 7902 3b/compare<- *esi 1/r32/ecx - 7903 7d/jump-if->= break/disp8 - 7904 # var c/eax: byte = in->data[in->read] - 7905 31/xor-with %eax 0/r32/eax - 7906 8a/copy-byte *(esi+ecx+0xc) 0/r32/AL - 7907 # if (c == ' ') break - 7908 3d/compare-eax-and 0x20/imm32/space - 7909 74/jump-if-= break/disp8 - 7910 # if (c == '\r') break - 7911 3d/compare-eax-and 0xd/imm32/carriage-return - 7912 74/jump-if-= break/disp8 - 7913 # if (c == '\n') break - 7914 3d/compare-eax-and 0xa/imm32/newline - 7915 74/jump-if-= break/disp8 - 7916 # if (c == '(') break - 7917 3d/compare-eax-and 0x28/imm32/open-paren - 7918 0f 84/jump-if-= break/disp32 - 7919 # if (c == ')') break - 7920 3d/compare-eax-and 0x29/imm32/close-paren - 7921 0f 84/jump-if-= break/disp32 - 7922 # if (c == ',') break - 7923 3d/compare-eax-and 0x2c/imm32/comma - 7924 0f 84/jump-if-= break/disp32 - 7925 # ++in->read - 7926 ff 0/subop/increment *(esi+4) - 7927 # - 7928 e9/jump loop/disp32 - 7929 } - 7930 $next-mu-token:done: - 7931 # out->end = &in->data[in->read] - 7932 8b/-> *(esi+4) 1/r32/ecx - 7933 8d/copy-address *(esi+ecx+0xc) 0/r32/eax - 7934 89/<- *(edi+4) 0/r32/eax - 7935 $next-mu-token:end: - 7936 # . restore registers - 7937 5f/pop-to-edi - 7938 5e/pop-to-esi - 7939 59/pop-to-ecx - 7940 58/pop-to-eax - 7941 # . epilogue - 7942 89/<- %esp 5/r32/ebp - 7943 5d/pop-to-ebp - 7944 c3/return - 7945 - 7946 pos-or-insert-slice: # arr: (addr stream (addr array byte)), s: (addr slice) -> index/eax: int - 7947 # . prologue - 7948 55/push-ebp - 7949 89/<- %ebp 4/r32/esp - 7950 # if (pos-slice(arr, s) != -1) return it - 7951 (pos-slice *(ebp+8) *(ebp+0xc)) # => eax - 7952 3d/compare-eax-and -1/imm32 - 7953 75/jump-if-!= $pos-or-insert-slice:end/disp8 - 7954 $pos-or-insert-slice:insert: - 7955 # var s2/eax: (handle array byte) - 7956 68/push 0/imm32 - 7957 68/push 0/imm32 - 7958 89/<- %eax 4/r32/esp - 7959 (slice-to-string Heap *(ebp+0xc) %eax) - 7960 # throw away alloc-id - 7961 (lookup *eax *(eax+4)) # => eax - 7962 (write-int *(ebp+8) %eax) - 7963 (pos-slice *(ebp+8) *(ebp+0xc)) # => eax - 7964 $pos-or-insert-slice:end: - 7965 # . reclaim locals - 7966 81 0/subop/add %esp 8/imm32 - 7967 # . epilogue - 7968 89/<- %esp 5/r32/ebp - 7969 5d/pop-to-ebp - 7970 c3/return - 7971 - 7972 # return the index in an array of strings matching 's', -1 if not found - 7973 # index is denominated in elements, not bytes - 7974 pos-slice: # arr: (addr stream (addr array byte)), s: (addr slice) -> index/eax: int - 7975 # . prologue - 7976 55/push-ebp - 7977 89/<- %ebp 4/r32/esp - 7978 # . save registers - 7979 51/push-ecx - 7980 52/push-edx - 7981 53/push-ebx - 7982 56/push-esi - 7983 #? (write-buffered Stderr "pos-slice: ") - 7984 #? (write-slice-buffered Stderr *(ebp+0xc)) - 7985 #? (write-buffered Stderr "\n") - 7986 #? (flush Stderr) - 7987 # esi = arr - 7988 8b/-> *(ebp+8) 6/r32/esi - 7989 # var index/ecx: int = 0 - 7990 b9/copy-to-ecx 0/imm32 - 7991 # var curr/edx: (addr (addr array byte)) = arr->data - 7992 8d/copy-address *(esi+0xc) 2/r32/edx - 7993 # var max/ebx: (addr (addr array byte)) = &arr->data[arr->write] - 7994 8b/-> *esi 3/r32/ebx - 7995 8d/copy-address *(esi+ebx+0xc) 3/r32/ebx - 7996 { - 7997 #? (write-buffered Stderr " ") - 7998 #? (write-int32-hex-buffered Stderr %ecx) - 7999 #? (write-buffered Stderr "\n") - 8000 #? (flush Stderr) - 8001 # if (curr >= max) return -1 - 8002 39/compare %edx 3/r32/ebx - 8003 b8/copy-to-eax -1/imm32 - 8004 73/jump-if-addr>= $pos-slice:end/disp8 - 8005 # if (slice-equal?(s, *curr)) break - 8006 (slice-equal? *(ebp+0xc) *edx) # => eax + 7275 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 7276 # registers except esp clobbered at this point + 7277 # restore ed + 7278 89/<- %edx 4/r32/esp + 7279 (flush _test-output-buffered-file) + 7280 (flush _test-error-buffered-file) + 7281 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 7287 # check output + 7288 (check-stream-equal _test-output-stream "" "F - test-index-with-no-inouts: output should be empty") + 7289 (check-next-stream-line-equal _test-error-stream "fn foo: stmt index: too few inouts (2 required)" "F - test-index-with-no-inouts: error message") + 7290 # check that stop(1) was called + 7291 (check-ints-equal *(edx+4) 2 "F - test-index-with-no-inouts: exit status") + 7292 # don't restore from ebp + 7293 81 0/subop/add %esp 8/imm32 + 7294 # . epilogue + 7295 5d/pop-to-ebp + 7296 c3/return + 7297 + 7298 test-index-with-too-few-inouts: + 7299 # . prologue + 7300 55/push-ebp + 7301 89/<- %ebp 4/r32/esp + 7302 # setup + 7303 (clear-stream _test-input-stream) + 7304 (clear-stream $_test-input-buffered-file->buffer) + 7305 (clear-stream _test-output-stream) + 7306 (clear-stream $_test-output-buffered-file->buffer) + 7307 (clear-stream _test-error-stream) + 7308 (clear-stream $_test-error-buffered-file->buffer) + 7309 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 7310 68/push 0/imm32 + 7311 68/push 0/imm32 + 7312 89/<- %edx 4/r32/esp + 7313 (tailor-exit-descriptor %edx 0x10) + 7314 # + 7315 (write _test-input-stream "fn foo {\n") + 7316 (write _test-input-stream " var a: (array int 3)\n") + 7317 (write _test-input-stream " var c/ecx: (addr int) <- index a\n") + 7318 (write _test-input-stream "}\n") + 7319 # convert + 7320 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 7321 # registers except esp clobbered at this point + 7322 # restore ed + 7323 89/<- %edx 4/r32/esp + 7324 (flush _test-output-buffered-file) + 7325 (flush _test-error-buffered-file) + 7326 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 7332 # check output + 7333 (check-stream-equal _test-output-stream "" "F - test-index-with-too-few-inouts: output should be empty") + 7334 (check-next-stream-line-equal _test-error-stream "fn foo: stmt index: too few inouts (2 required)" "F - test-index-with-too-few-inouts: error message") + 7335 # check that stop(1) was called + 7336 (check-ints-equal *(edx+4) 2 "F - test-index-with-too-few-inouts: exit status") + 7337 # don't restore from ebp + 7338 81 0/subop/add %esp 8/imm32 + 7339 # . epilogue + 7340 5d/pop-to-ebp + 7341 c3/return + 7342 + 7343 test-index-with-too-many-inouts: + 7344 # . prologue + 7345 55/push-ebp + 7346 89/<- %ebp 4/r32/esp + 7347 # setup + 7348 (clear-stream _test-input-stream) + 7349 (clear-stream $_test-input-buffered-file->buffer) + 7350 (clear-stream _test-output-stream) + 7351 (clear-stream $_test-output-buffered-file->buffer) + 7352 (clear-stream _test-error-stream) + 7353 (clear-stream $_test-error-buffered-file->buffer) + 7354 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 7355 68/push 0/imm32 + 7356 68/push 0/imm32 + 7357 89/<- %edx 4/r32/esp + 7358 (tailor-exit-descriptor %edx 0x10) + 7359 # + 7360 (write _test-input-stream "fn foo {\n") + 7361 (write _test-input-stream " var a: (array int 3)\n") + 7362 (write _test-input-stream " var c/ecx: (addr int) <- index a, 0, 0\n") + 7363 (write _test-input-stream "}\n") + 7364 # convert + 7365 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 7366 # registers except esp clobbered at this point + 7367 # restore ed + 7368 89/<- %edx 4/r32/esp + 7369 (flush _test-output-buffered-file) + 7370 (flush _test-error-buffered-file) + 7371 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 7377 # check output + 7378 (check-stream-equal _test-output-stream "" "F - test-index-with-too-many-inouts: output should be empty") + 7379 (check-next-stream-line-equal _test-error-stream "fn foo: stmt index: too many inouts (2 required)" "F - test-index-with-too-many-inouts: error message") + 7380 # check that stop(1) was called + 7381 (check-ints-equal *(edx+4) 2 "F - test-index-with-too-many-inouts: exit status") + 7382 # don't restore from ebp + 7383 81 0/subop/add %esp 8/imm32 + 7384 # . epilogue + 7385 5d/pop-to-ebp + 7386 c3/return + 7387 + 7388 test-index-with-no-output: + 7389 # . prologue + 7390 55/push-ebp + 7391 89/<- %ebp 4/r32/esp + 7392 # setup + 7393 (clear-stream _test-input-stream) + 7394 (clear-stream $_test-input-buffered-file->buffer) + 7395 (clear-stream _test-output-stream) + 7396 (clear-stream $_test-output-buffered-file->buffer) + 7397 (clear-stream _test-error-stream) + 7398 (clear-stream $_test-error-buffered-file->buffer) + 7399 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 7400 68/push 0/imm32 + 7401 68/push 0/imm32 + 7402 89/<- %edx 4/r32/esp + 7403 (tailor-exit-descriptor %edx 0x10) + 7404 # + 7405 (write _test-input-stream "fn foo {\n") + 7406 (write _test-input-stream " var a: (array int 3)\n") + 7407 (write _test-input-stream " index a, 0\n") + 7408 (write _test-input-stream "}\n") + 7409 # convert + 7410 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 7411 # registers except esp clobbered at this point + 7412 # restore ed + 7413 89/<- %edx 4/r32/esp + 7414 (flush _test-output-buffered-file) + 7415 (flush _test-error-buffered-file) + 7416 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 7422 # check output + 7423 (check-stream-equal _test-output-stream "" "F - test-index-with-no-output: output should be empty") + 7424 (check-next-stream-line-equal _test-error-stream "fn foo: stmt index: must have an output" "F - test-index-with-no-output: error message") + 7425 # check that stop(1) was called + 7426 (check-ints-equal *(edx+4) 2 "F - test-index-with-no-output: exit status") + 7427 # don't restore from ebp + 7428 81 0/subop/add %esp 8/imm32 + 7429 # . epilogue + 7430 5d/pop-to-ebp + 7431 c3/return + 7432 + 7433 test-index-with-too-many-outputs: + 7434 # . prologue + 7435 55/push-ebp + 7436 89/<- %ebp 4/r32/esp + 7437 # setup + 7438 (clear-stream _test-input-stream) + 7439 (clear-stream $_test-input-buffered-file->buffer) + 7440 (clear-stream _test-output-stream) + 7441 (clear-stream $_test-output-buffered-file->buffer) + 7442 (clear-stream _test-error-stream) + 7443 (clear-stream $_test-error-buffered-file->buffer) + 7444 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 7445 68/push 0/imm32 + 7446 68/push 0/imm32 + 7447 89/<- %edx 4/r32/esp + 7448 (tailor-exit-descriptor %edx 0x10) + 7449 # + 7450 (write _test-input-stream "fn foo {\n") + 7451 (write _test-input-stream " var a: (array int 3)\n") + 7452 (write _test-input-stream " var b/eax: (addr int) <- copy 0\n") + 7453 (write _test-input-stream " var c/ecx: (addr int) <- copy 0\n") + 7454 (write _test-input-stream " b, c <- index a, 0\n") + 7455 (write _test-input-stream "}\n") + 7456 # convert + 7457 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 7458 # registers except esp clobbered at this point + 7459 # restore ed + 7460 89/<- %edx 4/r32/esp + 7461 (flush _test-output-buffered-file) + 7462 (flush _test-error-buffered-file) + 7463 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 7469 # check output + 7470 (check-stream-equal _test-output-stream "" "F - test-index-with-too-many-outputs: output should be empty") + 7471 (check-next-stream-line-equal _test-error-stream "fn foo: stmt index: too many outputs (1 required)" "F - test-index-with-too-many-outputs: error message") + 7472 # check that stop(1) was called + 7473 (check-ints-equal *(edx+4) 2 "F - test-index-with-too-many-outputs: exit status") + 7474 # don't restore from ebp + 7475 81 0/subop/add %esp 8/imm32 + 7476 # . epilogue + 7477 5d/pop-to-ebp + 7478 c3/return + 7479 + 7480 ####################################################### + 7481 # Parsing + 7482 ####################################################### + 7483 + 7484 == data + 7485 + 7486 # Global state added to each var record when parsing a function + 7487 Next-block-index: # (addr int) + 7488 1/imm32 + 7489 + 7490 Curr-block-depth: # (addr int) + 7491 1/imm32 + 7492 + 7493 == code + 7494 + 7495 parse-mu: # in: (addr buffered-file), err: (addr buffered-file), ed: (addr exit-descriptor) + 7496 # pseudocode + 7497 # var curr-function: (addr handle function) = Program->functions + 7498 # var curr-signature: (addr handle function) = Program->signatures + 7499 # var curr-type: (addr handle typeinfo) = Program->types + 7500 # var line: (stream byte 512) + 7501 # var word-slice: slice + 7502 # while true # line loop + 7503 # clear-stream(line) + 7504 # read-line-buffered(in, line) + 7505 # if (line->write == 0) break # end of file + 7506 # word-slice = next-mu-token(line) + 7507 # if slice-empty?(word-slice) # end of line + 7508 # continue + 7509 # else if slice-starts-with?(word-slice, "#") # comment + 7510 # continue # end of line + 7511 # else if slice-equal?(word-slice, "fn") + 7512 # var new-function: (handle function) = allocate(function) + 7513 # var vars: (stack live-var 256) + 7514 # populate-mu-function-header(line, new-function, vars) + 7515 # populate-mu-function-body(in, new-function, vars) + 7516 # assert(vars->top == 0) + 7517 # *curr-function = new-function + 7518 # curr-function = &new-function->next + 7519 # else if slice-equal?(word-slice, "sig") + 7520 # var new-function: (handle function) = allocate(function) + 7521 # populate-mu-function-signature(line, new-function) + 7522 # *curr-signature = new-function + 7523 # curr-signature = &new-function->next + 7524 # else if slice-equal?(word-slice, "type") + 7525 # word-slice = next-mu-token(line) + 7526 # type-id = pos-or-insert-slice(Type-id, word-slice) + 7527 # var new-type: (handle typeinfo) = find-or-create-typeinfo(type-id) + 7528 # assert(next-word(line) == "{") + 7529 # populate-mu-type(in, new-type) + 7530 # else + 7531 # abort() + 7532 # + 7533 # . prologue + 7534 55/push-ebp + 7535 89/<- %ebp 4/r32/esp + 7536 # var curr-signature: (addr handle function) at *(ebp-4) + 7537 68/push _Program-signatures/imm32 + 7538 # . save registers + 7539 50/push-eax + 7540 51/push-ecx + 7541 52/push-edx + 7542 53/push-ebx + 7543 56/push-esi + 7544 57/push-edi + 7545 # var line/ecx: (stream byte 512) + 7546 81 5/subop/subtract %esp 0x200/imm32 + 7547 68/push 0x200/imm32/size + 7548 68/push 0/imm32/read + 7549 68/push 0/imm32/write + 7550 89/<- %ecx 4/r32/esp + 7551 # var word-slice/edx: slice + 7552 68/push 0/imm32/end + 7553 68/push 0/imm32/start + 7554 89/<- %edx 4/r32/esp + 7555 # var curr-function/edi: (addr handle function) + 7556 bf/copy-to-edi _Program-functions/imm32 + 7557 # var vars/ebx: (stack live-var 256) + 7558 81 5/subop/subtract %esp 0xc00/imm32 + 7559 68/push 0xc00/imm32/size + 7560 68/push 0/imm32/top + 7561 89/<- %ebx 4/r32/esp + 7562 { + 7563 $parse-mu:line-loop: + 7564 (clear-stream %ecx) + 7565 (read-line-buffered *(ebp+8) %ecx) + 7566 # if (line->write == 0) break + 7567 81 7/subop/compare *ecx 0/imm32 + 7568 0f 84/jump-if-= break/disp32 + 7569 +-- 6 lines: #? # dump line ------------------------------------------------------------------------------------------------------------------------------------------------------ + 7575 (next-mu-token %ecx %edx) + 7576 # if slice-empty?(word-slice) continue + 7577 (slice-empty? %edx) # => eax + 7578 3d/compare-eax-and 0/imm32/false + 7579 0f 85/jump-if-!= loop/disp32 + 7580 # if (*word-slice->start == "#") continue + 7581 # . eax = *word-slice->start + 7582 8b/-> *edx 0/r32/eax + 7583 8a/copy-byte *eax 0/r32/AL + 7584 81 4/subop/and %eax 0xff/imm32 + 7585 # . if (eax == '#') continue + 7586 3d/compare-eax-and 0x23/imm32/hash + 7587 0f 84/jump-if-= loop/disp32 + 7588 # if (slice-equal?(word-slice, "fn")) parse a function + 7589 { + 7590 $parse-mu:fn: + 7591 (slice-equal? %edx "fn") # => eax + 7592 3d/compare-eax-and 0/imm32/false + 7593 0f 84/jump-if-= break/disp32 + 7594 # var new-function/esi: (handle function) + 7595 68/push 0/imm32 + 7596 68/push 0/imm32 + 7597 89/<- %esi 4/r32/esp + 7598 # populate-mu-function(line, in, vars, new-function) + 7599 (allocate Heap *Function-size %esi) + 7600 # var new-function-addr/eax: (addr function) + 7601 (lookup *esi *(esi+4)) # => eax + 7602 # initialize vars + 7603 (clear-stack %ebx) + 7604 # + 7605 (populate-mu-function-header %ecx %eax %ebx *(ebp+0xc) *(ebp+0x10)) + 7606 (populate-mu-function-body *(ebp+8) %eax %ebx *(ebp+0xc) *(ebp+0x10)) + 7607 # *curr-function = new-function + 7608 8b/-> *esi 0/r32/eax + 7609 89/<- *edi 0/r32/eax + 7610 8b/-> *(esi+4) 0/r32/eax + 7611 89/<- *(edi+4) 0/r32/eax + 7612 # curr-function = &new-function->next + 7613 # . var tmp/eax: (addr function) = lookup(new-function) + 7614 (lookup *esi *(esi+4)) # => eax + 7615 # . curr-function = &tmp->next + 7616 8d/copy-address *(eax+0x20) 7/r32/edi # Function-next + 7617 # reclaim new-function + 7618 81 0/subop/add %esp 8/imm32 + 7619 # + 7620 e9/jump $parse-mu:line-loop/disp32 + 7621 } + 7622 # if (slice-equal?(word-slice, "sig")) parse a function signature + 7623 # Function signatures are for providing types to SubX functions. + 7624 { + 7625 $parse-mu:sig: + 7626 (slice-equal? %edx "sig") # => eax + 7627 3d/compare-eax-and 0/imm32/false + 7628 0f 84/jump-if-= break/disp32 + 7629 # edi = curr-function + 7630 57/push-edi + 7631 8b/-> *(ebp-4) 7/r32/edi + 7632 # var new-function/esi: (handle function) + 7633 68/push 0/imm32 + 7634 68/push 0/imm32 + 7635 89/<- %esi 4/r32/esp + 7636 # populate-mu-function(line, in, vars, new-function) + 7637 (allocate Heap *Function-size %esi) + 7638 # var new-function-addr/eax: (addr function) + 7639 (lookup *esi *(esi+4)) # => eax + 7640 # + 7641 (populate-mu-function-signature %ecx %eax *(ebp+0xc) *(ebp+0x10)) + 7642 # *curr-signature = new-function + 7643 8b/-> *esi 0/r32/eax + 7644 89/<- *edi 0/r32/eax + 7645 8b/-> *(esi+4) 0/r32/eax + 7646 89/<- *(edi+4) 0/r32/eax + 7647 # curr-signature = &new-function->next + 7648 # . var tmp/eax: (addr function) = lookup(new-function) + 7649 (lookup *esi *(esi+4)) # => eax + 7650 # . curr-function = &tmp->next + 7651 8d/copy-address *(eax+0x20) 7/r32/edi # Function-next + 7652 # reclaim new-function + 7653 81 0/subop/add %esp 8/imm32 + 7654 # save curr-function + 7655 89/<- *(ebp-4) 7/r32/edi + 7656 # restore edi + 7657 5f/pop-to-edi + 7658 # + 7659 e9/jump $parse-mu:line-loop/disp32 + 7660 } + 7661 # if (slice-equal?(word-slice, "type")) parse a type (struct/record) definition + 7662 { + 7663 $parse-mu:type: + 7664 (slice-equal? %edx "type") # => eax + 7665 3d/compare-eax-and 0/imm32 + 7666 0f 84/jump-if-= break/disp32 + 7667 (next-mu-token %ecx %edx) + 7668 # var type-id/eax: int + 7669 (pos-or-insert-slice Type-id %edx) # => eax + 7670 # spill + 7671 51/push-ecx + 7672 # var new-type/ecx: (handle typeinfo) + 7673 68/push 0/imm32 + 7674 68/push 0/imm32 + 7675 89/<- %ecx 4/r32/esp + 7676 (find-or-create-typeinfo %eax %ecx) + 7677 # + 7678 (lookup *ecx *(ecx+4)) # => eax + 7679 # TODO: ensure that 'line' has nothing else but '{' + 7680 #? (dump-typeinfos "=== aaa\n") + 7681 (populate-mu-type *(ebp+8) %eax *(ebp+0xc) *(ebp+0x10)) # => eax + 7682 #? (dump-typeinfos "=== zzz\n") + 7683 # reclaim new-type + 7684 81 0/subop/add %esp 8/imm32 + 7685 # restore + 7686 59/pop-to-ecx + 7687 e9/jump $parse-mu:line-loop/disp32 + 7688 } + 7689 # otherwise abort + 7690 e9/jump $parse-mu:error1/disp32 + 7691 } # end line loop + 7692 $parse-mu:end: + 7693 # . reclaim locals + 7694 81 0/subop/add %esp 0x20c/imm32 # line + 7695 81 0/subop/add %esp 0xc08/imm32 # vars + 7696 81 0/subop/add %esp 8/imm32 + 7697 # . restore registers + 7698 5f/pop-to-edi + 7699 5e/pop-to-esi + 7700 5b/pop-to-ebx + 7701 5a/pop-to-edx + 7702 59/pop-to-ecx + 7703 58/pop-to-eax + 7704 # . reclaim local + 7705 81 0/subop/add %esp 4/imm32 + 7706 # . epilogue + 7707 89/<- %esp 5/r32/ebp + 7708 5d/pop-to-ebp + 7709 c3/return + 7710 + 7711 $parse-mu:error1: + 7712 # error("unexpected top-level command: " word-slice "\n") + 7713 (write-buffered *(ebp+0xc) "unexpected top-level command: ") + 7714 (write-slice-buffered *(ebp+0xc) %edx) + 7715 (write-buffered *(ebp+0xc) "\n") + 7716 (flush *(ebp+0xc)) + 7717 (stop *(ebp+0x10) 1) + 7718 # never gets here + 7719 + 7720 $parse-mu:error2: + 7721 # error(vars->top " vars not reclaimed after fn '" new-function->name "'\n") + 7722 (write-int32-hex-buffered *(ebp+0xc) *ebx) + 7723 (write-buffered *(ebp+0xc) " vars not reclaimed after fn '") + 7724 (write-slice-buffered *(ebp+0xc) *eax) # Function-name + 7725 (write-buffered *(ebp+0xc) "'\n") + 7726 (flush *(ebp+0xc)) + 7727 (stop *(ebp+0x10) 1) + 7728 # never gets here + 7729 + 7730 # scenarios considered: + 7731 # ✗ fn foo # no block + 7732 # ✓ fn foo { + 7733 # ✗ fn foo { { + 7734 # ✗ fn foo { } + 7735 # ✗ fn foo { } { + 7736 # ✗ fn foo x { + 7737 # ✗ fn foo x: { + 7738 # ✓ fn foo x: int { + 7739 # ✓ fn foo x: int { + 7740 # ✓ fn foo x: int -> y/eax: int { + 7741 # TODO: + 7742 # disallow outputs of type `(... addr ...)` + 7743 # disallow inputs of type `(... addr ... addr ...)` + 7744 populate-mu-function-header: # first-line: (addr stream byte), out: (addr function), vars: (addr stack live-var), err: (addr buffered-file), ed: (addr exit-descriptor) + 7745 # pseudocode: + 7746 # var word-slice: slice + 7747 # next-mu-token(first-line, word-slice) + 7748 # assert(word-slice not in '{' '}' '->') + 7749 # out->name = slice-to-string(word-slice) + 7750 # ## inouts + 7751 # while true + 7752 # word-slice = next-mu-token(first-line) + 7753 # if (word-slice == '{') goto done + 7754 # if (word-slice == '->') break + 7755 # assert(word-slice != '}') + 7756 # var v: (handle var) = parse-var-with-type(word-slice, first-line) + 7757 # assert(v->register == null) + 7758 # # v->block-depth is implicitly 0 + 7759 # out->inouts = append(v, out->inouts) + 7760 # push(vars, {v, false}) + 7761 # ## outputs + 7762 # while true + 7763 # word-slice = next-mu-token(first-line) + 7764 # if (word-slice == '{') break + 7765 # assert(word-slice not in '}' '->') + 7766 # var v: (handle var) = parse-var-with-type(word-slice, first-line) + 7767 # assert(v->register != null) + 7768 # out->outputs = append(v, out->outputs) + 7769 # done: + 7770 # + 7771 # . prologue + 7772 55/push-ebp + 7773 89/<- %ebp 4/r32/esp + 7774 # . save registers + 7775 50/push-eax + 7776 51/push-ecx + 7777 52/push-edx + 7778 53/push-ebx + 7779 57/push-edi + 7780 # edi = out + 7781 8b/-> *(ebp+0xc) 7/r32/edi + 7782 # var word-slice/ecx: slice + 7783 68/push 0/imm32/end + 7784 68/push 0/imm32/start + 7785 89/<- %ecx 4/r32/esp + 7786 # var v/ebx: (handle var) + 7787 68/push 0/imm32 + 7788 68/push 0/imm32 + 7789 89/<- %ebx 4/r32/esp + 7790 # read function name + 7791 (next-mu-token *(ebp+8) %ecx) + 7792 # error checking + 7793 # if (word-slice == '{') abort + 7794 (slice-equal? %ecx "{") # => eax + 7795 3d/compare-eax-and 0/imm32/false + 7796 0f 85/jump-if-!= $populate-mu-function-header:error1/disp32 + 7797 # if (word-slice == '->') abort + 7798 (slice-equal? %ecx "->") # => eax + 7799 3d/compare-eax-and 0/imm32/false + 7800 0f 85/jump-if-!= $populate-mu-function-header:error1/disp32 + 7801 # if (word-slice == '}') abort + 7802 (slice-equal? %ecx "}") # => eax + 7803 3d/compare-eax-and 0/imm32/false + 7804 0f 85/jump-if-!= $populate-mu-function-header:error1/disp32 + 7805 # save function name + 7806 (slice-to-string Heap %ecx %edi) # Function-name + 7807 # save function inouts + 7808 { + 7809 $populate-mu-function-header:check-for-inout: + 7810 (next-mu-token *(ebp+8) %ecx) + 7811 # if (word-slice == '{') goto done + 7812 (slice-equal? %ecx "{") # => eax + 7813 3d/compare-eax-and 0/imm32/false + 7814 0f 85/jump-if-!= $populate-mu-function-header:done/disp32 + 7815 # if (word-slice == '->') break + 7816 (slice-equal? %ecx "->") # => eax + 7817 3d/compare-eax-and 0/imm32/false + 7818 0f 85/jump-if-!= break/disp32 + 7819 # if (word-slice == '}') abort + 7820 (slice-equal? %ecx "}") # => eax + 7821 3d/compare-eax-and 0/imm32/false + 7822 0f 85/jump-if-!= $populate-mu-function-header:error1/disp32 + 7823 # v = parse-var-with-type(word-slice, first-line) + 7824 (parse-var-with-type %ecx *(ebp+8) %ebx *(ebp+0x14) *(ebp+0x18)) + 7825 # assert(v->register == null) + 7826 # . eax: (addr var) = lookup(v) + 7827 (lookup *ebx *(ebx+4)) # => eax + 7828 81 7/subop/compare *(eax+0x18) 0/imm32 # Var-register + 7829 0f 85/jump-if-!= $populate-mu-function-header:error2/disp32 + 7830 # v->block-depth is implicitly 0 + 7831 # + 7832 # out->inouts = append(v, out->inouts) + 7833 8d/copy-address *(edi+8) 0/r32/eax # Function-inouts + 7834 (append-list Heap *ebx *(ebx+4) *(edi+8) *(edi+0xc) %eax) # Function-inouts, Function-inouts + 7835 # push(vars, {v, false}) + 7836 (push *(ebp+0x10) *ebx) + 7837 (push *(ebp+0x10) *(ebx+4)) + 7838 (push *(ebp+0x10) 0) # false + 7839 # + 7840 e9/jump loop/disp32 + 7841 } + 7842 # save function outputs + 7843 { + 7844 $populate-mu-function-header:check-for-out: + 7845 (next-mu-token *(ebp+8) %ecx) + 7846 # if (word-slice == '{') break + 7847 (slice-equal? %ecx "{") # => eax + 7848 3d/compare-eax-and 0/imm32/false + 7849 0f 85/jump-if-!= break/disp32 + 7850 # if (word-slice == '->') abort + 7851 (slice-equal? %ecx "->") # => eax + 7852 3d/compare-eax-and 0/imm32/false + 7853 0f 85/jump-if-!= $populate-mu-function-header:error1/disp32 + 7854 # if (word-slice == '}') abort + 7855 (slice-equal? %ecx "}") # => eax + 7856 3d/compare-eax-and 0/imm32/false + 7857 0f 85/jump-if-!= $populate-mu-function-header:error1/disp32 + 7858 # v = parse-var-with-type(word-slice, first-line) + 7859 (parse-var-with-type %ecx *(ebp+8) %ebx *(ebp+0x14) *(ebp+0x18)) + 7860 # assert(var->register != null) + 7861 # . eax: (addr var) = lookup(v) + 7862 (lookup *ebx *(ebx+4)) # => eax + 7863 81 7/subop/compare *(eax+0x18) 0/imm32 # Var-register + 7864 0f 84/jump-if-= $populate-mu-function-header:error3/disp32 + 7865 # out->outputs = append(v, out->outputs) + 7866 8d/copy-address *(edi+0x10) 0/r32/eax # Function-outputs + 7867 (append-list Heap *ebx *(ebx+4) *(edi+0x10) *(edi+0x14) %eax) # Function-outputs, Function-outputs + 7868 # + 7869 e9/jump loop/disp32 + 7870 } + 7871 $populate-mu-function-header:done: + 7872 (check-no-tokens-left *(ebp+8)) + 7873 $populate-mu-function-header:end: + 7874 # . reclaim locals + 7875 81 0/subop/add %esp 0x10/imm32 + 7876 # . restore registers + 7877 5f/pop-to-edi + 7878 5b/pop-to-ebx + 7879 5a/pop-to-edx + 7880 59/pop-to-ecx + 7881 58/pop-to-eax + 7882 # . epilogue + 7883 89/<- %esp 5/r32/ebp + 7884 5d/pop-to-ebp + 7885 c3/return + 7886 + 7887 $populate-mu-function-header:error1: + 7888 # error("function header not in form 'fn <name> {'") + 7889 (write-buffered *(ebp+0x14) "function header not in form 'fn <name> [inouts] [-> outputs] {' -- '") + 7890 (flush *(ebp+0x14)) + 7891 (rewind-stream *(ebp+8)) + 7892 (write-stream-data *(ebp+0x14) *(ebp+8)) + 7893 (write-buffered *(ebp+0x14) "'\n") + 7894 (flush *(ebp+0x14)) + 7895 (stop *(ebp+0x18) 1) + 7896 # never gets here + 7897 + 7898 $populate-mu-function-header:error2: + 7899 # error("fn " fn ": function inout '" var "' cannot be in a register") + 7900 (write-buffered *(ebp+0x14) "fn ") + 7901 50/push-eax + 7902 (lookup *edi *(edi+4)) # Function-name Function-name => eax + 7903 (write-buffered *(ebp+0x14) %eax) + 7904 58/pop-to-eax + 7905 (write-buffered *(ebp+0x14) ": function inout '") + 7906 (lookup *eax *(eax+4)) # Var-name Var-name => eax + 7907 (write-buffered *(ebp+0x10) %eax) + 7908 (write-buffered *(ebp+0x14) "' cannot be in a register") + 7909 (flush *(ebp+0x14)) + 7910 (stop *(ebp+0x18) 1) + 7911 # never gets here + 7912 + 7913 $populate-mu-function-header:error3: + 7914 # error("fn " fn ": function output '" var "' must be in a register") + 7915 (write-buffered *(ebp+0x14) "fn ") + 7916 50/push-eax + 7917 (lookup *edi *(edi+4)) # Function-name Function-name => eax + 7918 (write-buffered *(ebp+0x14) %eax) + 7919 58/pop-to-eax + 7920 (write-buffered *(ebp+0x14) ": function output '") + 7921 (lookup *ebx *(ebx+4)) # => eax + 7922 (lookup *eax *(eax+4)) # Var-name Var-name => eax + 7923 (write-buffered *(ebp+0x14) %eax) + 7924 (write-buffered *(ebp+0x14) "' must be in a register, in instruction '") + 7925 (rewind-stream *(ebp+8)) + 7926 (write-stream-data *(ebp+0x14) *(ebp+8)) + 7927 (write-buffered *(ebp+0x14) "'\n") + 7928 (flush *(ebp+0x14)) + 7929 (stop *(ebp+0x18) 1) + 7930 # never gets here + 7931 + 7932 # scenarios considered: + 7933 # ✓ fn foo + 7934 # ✗ fn foo { + 7935 # ✓ fn foo x + 7936 # ✓ fn foo x: int + 7937 # ✓ fn foo x: int -> y/eax: int + 7938 # TODO: + 7939 # disallow outputs of type `(... addr ...)` + 7940 # disallow inputs of type `(... addr ... addr ...)` + 7941 populate-mu-function-signature: # first-line: (addr stream byte), out: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) + 7942 # pseudocode: + 7943 # var word-slice: slice + 7944 # next-mu-token(first-line, word-slice) + 7945 # assert(word-slice not in '{' '}' '->') + 7946 # out->name = slice-to-string(word-slice) + 7947 # ## inouts + 7948 # while true + 7949 # word-slice = next-mu-token(first-line) + 7950 # if slice-empty?(word-slice) break + 7951 # if (word-slice == '->') break + 7952 # assert(word-slice not in '{' '}') + 7953 # var v: (handle var) = parse-var-with-type(word-slice, first-line) + 7954 # assert(v->register == null) + 7955 # # v->block-depth is implicitly 0 + 7956 # out->inouts = append(v, out->inouts) + 7957 # ## outputs + 7958 # while true + 7959 # word-slice = next-mu-token(first-line) + 7960 # if slice-empty?(word-slice) break + 7961 # assert(word-slice not in '{' '}' '->') + 7962 # var v: (handle var) = parse-var-with-type(word-slice, first-line) + 7963 # assert(v->register != null) + 7964 # out->outputs = append(v, out->outputs) + 7965 # + 7966 # . prologue + 7967 55/push-ebp + 7968 89/<- %ebp 4/r32/esp + 7969 # . save registers + 7970 50/push-eax + 7971 51/push-ecx + 7972 52/push-edx + 7973 53/push-ebx + 7974 57/push-edi + 7975 # edi = out + 7976 8b/-> *(ebp+0xc) 7/r32/edi + 7977 # var word-slice/ecx: slice + 7978 68/push 0/imm32/end + 7979 68/push 0/imm32/start + 7980 89/<- %ecx 4/r32/esp + 7981 # var v/ebx: (handle var) + 7982 68/push 0/imm32 + 7983 68/push 0/imm32 + 7984 89/<- %ebx 4/r32/esp + 7985 # read function name + 7986 (next-mu-token *(ebp+8) %ecx) + 7987 # error checking + 7988 # if (word-slice == '{') abort + 7989 (slice-equal? %ecx "{") # => eax + 7990 3d/compare-eax-and 0/imm32/false + 7991 0f 85/jump-if-!= $populate-mu-function-signature:error1/disp32 + 7992 # if (word-slice == '->') abort + 7993 (slice-equal? %ecx "->") # => eax + 7994 3d/compare-eax-and 0/imm32/false + 7995 0f 85/jump-if-!= $populate-mu-function-signature:error1/disp32 + 7996 # if (word-slice == '}') abort + 7997 (slice-equal? %ecx "}") # => eax + 7998 3d/compare-eax-and 0/imm32/false + 7999 0f 85/jump-if-!= $populate-mu-function-signature:error1/disp32 + 8000 # save function name + 8001 (slice-to-string Heap %ecx %edi) # Function-name + 8002 # save function inouts + 8003 { + 8004 $populate-mu-function-signature:check-for-inout: + 8005 (next-mu-token *(ebp+8) %ecx) + 8006 (slice-empty? %ecx) # => eax 8007 3d/compare-eax-and 0/imm32/false - 8008 75/jump-if-!= break/disp8 - 8009 # ++index - 8010 41/increment-ecx - 8011 # curr += 4 - 8012 81 0/subop/add %edx 4/imm32 - 8013 # - 8014 eb/jump loop/disp8 - 8015 } - 8016 # return index - 8017 89/<- %eax 1/r32/ecx - 8018 $pos-slice:end: - 8019 #? (write-buffered Stderr "=> ") - 8020 #? (write-int32-hex-buffered Stderr %eax) - 8021 #? (write-buffered Stderr "\n") - 8022 # . restore registers - 8023 5e/pop-to-esi - 8024 5b/pop-to-ebx - 8025 5a/pop-to-edx - 8026 59/pop-to-ecx - 8027 # . epilogue - 8028 89/<- %esp 5/r32/ebp - 8029 5d/pop-to-ebp - 8030 c3/return - 8031 - 8032 test-parse-var-with-type: - 8033 # . prologue - 8034 55/push-ebp - 8035 89/<- %ebp 4/r32/esp - 8036 # (eax..ecx) = "x:" - 8037 b8/copy-to-eax "x:"/imm32 - 8038 8b/-> *eax 1/r32/ecx - 8039 8d/copy-address *(eax+ecx+4) 1/r32/ecx - 8040 05/add-to-eax 4/imm32 - 8041 # var slice/ecx: slice = {eax, ecx} - 8042 51/push-ecx - 8043 50/push-eax - 8044 89/<- %ecx 4/r32/esp - 8045 # _test-input-stream contains "int" - 8046 (clear-stream _test-input-stream) - 8047 (write _test-input-stream "int") - 8048 # var v/edx: (handle var) - 8049 68/push 0/imm32 - 8050 68/push 0/imm32 - 8051 89/<- %edx 4/r32/esp - 8052 # - 8053 (parse-var-with-type %ecx _test-input-stream %edx Stderr 0) - 8054 # var v-addr/edx: (addr var) = lookup(v) - 8055 (lookup *edx *(edx+4)) # => eax - 8056 89/<- %edx 0/r32/eax - 8057 # check v-addr->name - 8058 (lookup *edx *(edx+4)) # Var-name Var-name => eax - 8059 (check-strings-equal %eax "x" "F - test-parse-var-with-type/name") - 8060 # check v-addr->type - 8061 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax - 8062 (check-ints-equal *eax 1 "F - test-parse-var-with-type/type:0") # Type-tree-is-atom - 8063 (check-ints-equal *(eax+4) 1 "F - test-parse-var-with-type/type:1") # Type-tree-value - 8064 (check-ints-equal *(eax+0xc) 0 "F - test-parse-var-with-type/type:2") # Type-tree-right - 8065 # . epilogue - 8066 89/<- %esp 5/r32/ebp - 8067 5d/pop-to-ebp - 8068 c3/return - 8069 - 8070 test-parse-var-with-type-and-register: - 8071 # . prologue - 8072 55/push-ebp - 8073 89/<- %ebp 4/r32/esp - 8074 # (eax..ecx) = "x/eax:" - 8075 b8/copy-to-eax "x/eax:"/imm32 - 8076 8b/-> *eax 1/r32/ecx - 8077 8d/copy-address *(eax+ecx+4) 1/r32/ecx - 8078 05/add-to-eax 4/imm32 - 8079 # var slice/ecx: slice = {eax, ecx} - 8080 51/push-ecx - 8081 50/push-eax - 8082 89/<- %ecx 4/r32/esp - 8083 # _test-input-stream contains "int" - 8084 (clear-stream _test-input-stream) - 8085 (write _test-input-stream "int") - 8086 # var v/edx: (handle var) - 8087 68/push 0/imm32 - 8088 68/push 0/imm32 - 8089 89/<- %edx 4/r32/esp - 8090 # - 8091 (parse-var-with-type %ecx _test-input-stream %edx Stderr 0) - 8092 # var v-addr/edx: (addr var) = lookup(v) - 8093 (lookup *edx *(edx+4)) # => eax - 8094 89/<- %edx 0/r32/eax - 8095 # check v-addr->name - 8096 (lookup *edx *(edx+4)) # Var-name Var-name => eax - 8097 (check-strings-equal %eax "x" "F - test-parse-var-with-type-and-register/name") - 8098 # check v-addr->register - 8099 (lookup *(edx+0x18) *(edx+0x1c)) # Var-register Var-register => eax - 8100 (check-strings-equal %eax "eax" "F - test-parse-var-with-type-and-register/register") - 8101 # check v-addr->type - 8102 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax - 8103 (check-ints-equal *eax 1 "F - test-parse-var-with-type-and-register/type:0") # Type-tree-is-atom - 8104 (check-ints-equal *(eax+4) 1 "F - test-parse-var-with-type-and-register/type:1") # Type-tree-left - 8105 (check-ints-equal *(eax+0xc) 0 "F - test-parse-var-with-type-and-register/type:2") # Type-tree-right - 8106 # . epilogue - 8107 89/<- %esp 5/r32/ebp - 8108 5d/pop-to-ebp - 8109 c3/return - 8110 - 8111 test-parse-var-with-trailing-characters: - 8112 # . prologue - 8113 55/push-ebp - 8114 89/<- %ebp 4/r32/esp - 8115 # (eax..ecx) = "x:" - 8116 b8/copy-to-eax "x:"/imm32 - 8117 8b/-> *eax 1/r32/ecx - 8118 8d/copy-address *(eax+ecx+4) 1/r32/ecx - 8119 05/add-to-eax 4/imm32 - 8120 # var slice/ecx: slice = {eax, ecx} - 8121 51/push-ecx - 8122 50/push-eax - 8123 89/<- %ecx 4/r32/esp - 8124 # _test-input-stream contains "int," - 8125 (clear-stream _test-input-stream) - 8126 (write _test-input-stream "int,") - 8127 # var v/edx: (handle var) - 8128 68/push 0/imm32 - 8129 68/push 0/imm32 - 8130 89/<- %edx 4/r32/esp - 8131 # - 8132 (parse-var-with-type %ecx _test-input-stream %edx Stderr 0) - 8133 # var v-addr/edx: (addr var) = lookup(v) - 8134 (lookup *edx *(edx+4)) # => eax - 8135 89/<- %edx 0/r32/eax - 8136 # check v-addr->name - 8137 (lookup *edx *(edx+4)) # Var-name Var-name => eax - 8138 (check-strings-equal %eax "x" "F - test-parse-var-with-trailing-characters/name") - 8139 # check v-addr->register - 8140 (check-ints-equal *(edx+0x18) 0 "F - test-parse-var-with-trailing-characters/register") # Var-register - 8141 # check v-addr->type - 8142 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax - 8143 (check-ints-equal *eax 1 "F - test-parse-var-with-trailing-characters/type:0") # Type-tree-is-atom - 8144 (check-ints-equal *(eax+4) 1 "F - test-parse-var-with-trailing-characters/type:1") # Type-tree-left - 8145 (check-ints-equal *(eax+0xc) 0 "F - test-parse-var-with-trailing-characters/type:1") # Type-tree-right - 8146 # . epilogue - 8147 89/<- %esp 5/r32/ebp - 8148 5d/pop-to-ebp - 8149 c3/return - 8150 - 8151 test-parse-var-with-register-and-trailing-characters: - 8152 # . prologue - 8153 55/push-ebp - 8154 89/<- %ebp 4/r32/esp - 8155 # (eax..ecx) = "x/eax:" - 8156 b8/copy-to-eax "x/eax:"/imm32 - 8157 8b/-> *eax 1/r32/ecx - 8158 8d/copy-address *(eax+ecx+4) 1/r32/ecx - 8159 05/add-to-eax 4/imm32 - 8160 # var slice/ecx: slice = {eax, ecx} - 8161 51/push-ecx - 8162 50/push-eax - 8163 89/<- %ecx 4/r32/esp - 8164 # _test-input-stream contains "int," - 8165 (clear-stream _test-input-stream) - 8166 (write _test-input-stream "int,") - 8167 # var v/edx: (handle var) - 8168 68/push 0/imm32 - 8169 68/push 0/imm32 - 8170 89/<- %edx 4/r32/esp - 8171 # - 8172 (parse-var-with-type %ecx _test-input-stream %edx Stderr 0) - 8173 # var v-addr/edx: (addr var) = lookup(v) - 8174 (lookup *edx *(edx+4)) # => eax - 8175 89/<- %edx 0/r32/eax - 8176 # check v-addr->name - 8177 (lookup *edx *(edx+4)) # Var-name Var-name => eax - 8178 (check-strings-equal %eax "x" "F - test-parse-var-with-register-and-trailing-characters/name") - 8179 # check v-addr->register - 8180 (lookup *(edx+0x18) *(edx+0x1c)) # Var-register Var-register => eax - 8181 (check-strings-equal %eax "eax" "F - test-parse-var-with-register-and-trailing-characters/register") - 8182 # check v-addr->type - 8183 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax - 8184 (check-ints-equal *eax 1 "F - test-parse-var-with-register-and-trailing-characters/type:0") # Type-tree-is-atom - 8185 (check-ints-equal *(eax+4) 1 "F - test-parse-var-with-register-and-trailing-characters/type:1") # Type-tree-left - 8186 (check-ints-equal *(eax+0xc) 0 "F - test-parse-var-with-register-and-trailing-characters/type:2") # Type-tree-right - 8187 # . epilogue - 8188 89/<- %esp 5/r32/ebp - 8189 5d/pop-to-ebp - 8190 c3/return - 8191 - 8192 test-parse-var-with-compound-type: - 8193 # . prologue - 8194 55/push-ebp - 8195 89/<- %ebp 4/r32/esp - 8196 # (eax..ecx) = "x:" - 8197 b8/copy-to-eax "x:"/imm32 - 8198 8b/-> *eax 1/r32/ecx - 8199 8d/copy-address *(eax+ecx+4) 1/r32/ecx - 8200 05/add-to-eax 4/imm32 - 8201 # var slice/ecx: slice = {eax, ecx} - 8202 51/push-ecx - 8203 50/push-eax - 8204 89/<- %ecx 4/r32/esp - 8205 # _test-input-stream contains "(addr int)" - 8206 (clear-stream _test-input-stream) - 8207 (write _test-input-stream "(addr int)") - 8208 # var v/edx: (handle var) - 8209 68/push 0/imm32 - 8210 68/push 0/imm32 - 8211 89/<- %edx 4/r32/esp - 8212 # - 8213 (parse-var-with-type %ecx _test-input-stream %edx Stderr 0) - 8214 # var v-addr/edx: (addr var) = lookup(v) - 8215 (lookup *edx *(edx+4)) # => eax - 8216 89/<- %edx 0/r32/eax - 8217 # check v-addr->name - 8218 (lookup *edx *(edx+4)) # Var-name Var-name => eax - 8219 (check-strings-equal %eax "x" "F - test-parse-var-with-compound-type/name") - 8220 # check v-addr->register - 8221 (check-ints-equal *(edx+0x18) 0 "F - test-parse-var-with-compound-type/register") # Var-register - 8222 # - check v-addr->type - 8223 # var type/edx: (addr type-tree) = var->type - 8224 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax - 8225 89/<- %edx 0/r32/eax - 8226 # type is a non-atom - 8227 (check-ints-equal *edx 0 "F - test-parse-var-with-compound-type/type:0") # Type-tree-is-atom - 8228 # type->left == atom(addr) - 8229 (lookup *(edx+4) *(edx+8)) # Type-tree-left Type-tree-left => eax - 8230 (check-ints-equal *eax 1 "F - test-parse-var-with-compound-type/type:1") # Type-tree-is-atom - 8231 (check-ints-equal *(eax+4) 2 "F - test-parse-var-with-compound-type/type:2") # Type-tree-value - 8232 # type->right->left == atom(int) - 8233 (lookup *(edx+0xc) *(edx+0x10)) # Type-tree-right Type-tree-right => eax - 8234 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax - 8235 (check-ints-equal *eax 1 "F - test-parse-var-with-compound-type/type:3") # Type-tree-is-atom - 8236 (check-ints-equal *(eax+4) 1 "F - test-parse-var-with-compound-type/type:4") # Type-tree-value - 8237 # type->right->right == null - 8238 (check-ints-equal *(eax+0xc) 0 "F - test-parse-var-with-compound-type/type:5") # Type-tree-right - 8239 # . epilogue - 8240 89/<- %esp 5/r32/ebp - 8241 5d/pop-to-ebp - 8242 c3/return - 8243 - 8244 # identifier starts with a letter or '$' or '_' - 8245 # no constraints at the moment on later letters - 8246 # all we really want to do so far is exclude '{', '}' and '->' - 8247 is-identifier?: # in: (addr slice) -> result/eax: boolean - 8248 # . prologue - 8249 55/push-ebp - 8250 89/<- %ebp 4/r32/esp - 8251 # if (slice-empty?(in)) return false - 8252 (slice-empty? *(ebp+8)) # => eax - 8253 3d/compare-eax-and 0/imm32/false - 8254 75/jump-if-!= $is-identifier?:false/disp8 - 8255 # var c/eax: byte = *in->start - 8256 8b/-> *(ebp+8) 0/r32/eax - 8257 8b/-> *eax 0/r32/eax - 8258 8a/copy-byte *eax 0/r32/AL - 8259 81 4/subop/and %eax 0xff/imm32 - 8260 # if (c == '$') return true - 8261 3d/compare-eax-and 0x24/imm32/$ - 8262 74/jump-if-= $is-identifier?:true/disp8 - 8263 # if (c == '_') return true - 8264 3d/compare-eax-and 0x5f/imm32/_ - 8265 74/jump-if-= $is-identifier?:true/disp8 - 8266 # drop case - 8267 25/and-eax-with 0x5f/imm32 - 8268 # if (c < 'A') return false - 8269 3d/compare-eax-and 0x41/imm32/A - 8270 7c/jump-if-< $is-identifier?:false/disp8 - 8271 # if (c > 'Z') return false - 8272 3d/compare-eax-and 0x5a/imm32/Z - 8273 7f/jump-if-> $is-identifier?:false/disp8 - 8274 # otherwise return true - 8275 $is-identifier?:true: - 8276 b8/copy-to-eax 1/imm32/true - 8277 eb/jump $is-identifier?:end/disp8 - 8278 $is-identifier?:false: - 8279 b8/copy-to-eax 0/imm32/false - 8280 $is-identifier?:end: - 8281 # . epilogue - 8282 89/<- %esp 5/r32/ebp - 8283 5d/pop-to-ebp - 8284 c3/return - 8285 - 8286 test-is-identifier-dollar: - 8287 # . prologue - 8288 55/push-ebp - 8289 89/<- %ebp 4/r32/esp - 8290 # (eax..ecx) = "$a" - 8291 b8/copy-to-eax "$a"/imm32 - 8292 8b/-> *eax 1/r32/ecx - 8293 8d/copy-address *(eax+ecx+4) 1/r32/ecx - 8294 05/add-to-eax 4/imm32 - 8295 # var slice/ecx: slice = {eax, ecx} - 8296 51/push-ecx - 8297 50/push-eax - 8298 89/<- %ecx 4/r32/esp - 8299 # - 8300 (is-identifier? %ecx) - 8301 (check-ints-equal %eax 1 "F - test-is-identifier-dollar") - 8302 # . epilogue - 8303 89/<- %esp 5/r32/ebp - 8304 5d/pop-to-ebp - 8305 c3/return - 8306 - 8307 test-is-identifier-underscore: - 8308 # . prologue - 8309 55/push-ebp - 8310 89/<- %ebp 4/r32/esp - 8311 # (eax..ecx) = "_a" - 8312 b8/copy-to-eax "_a"/imm32 - 8313 8b/-> *eax 1/r32/ecx - 8314 8d/copy-address *(eax+ecx+4) 1/r32/ecx - 8315 05/add-to-eax 4/imm32 - 8316 # var slice/ecx: slice = {eax, ecx} - 8317 51/push-ecx - 8318 50/push-eax - 8319 89/<- %ecx 4/r32/esp - 8320 # - 8321 (is-identifier? %ecx) - 8322 (check-ints-equal %eax 1 "F - test-is-identifier-underscore") - 8323 # . epilogue - 8324 89/<- %esp 5/r32/ebp - 8325 5d/pop-to-ebp - 8326 c3/return - 8327 - 8328 test-is-identifier-a: - 8329 # . prologue - 8330 55/push-ebp - 8331 89/<- %ebp 4/r32/esp - 8332 # (eax..ecx) = "a$" - 8333 b8/copy-to-eax "a$"/imm32 - 8334 8b/-> *eax 1/r32/ecx - 8335 8d/copy-address *(eax+ecx+4) 1/r32/ecx - 8336 05/add-to-eax 4/imm32 - 8337 # var slice/ecx: slice = {eax, ecx} - 8338 51/push-ecx - 8339 50/push-eax - 8340 89/<- %ecx 4/r32/esp - 8341 # - 8342 (is-identifier? %ecx) - 8343 (check-ints-equal %eax 1 "F - test-is-identifier-a") - 8344 # . epilogue - 8345 89/<- %esp 5/r32/ebp - 8346 5d/pop-to-ebp - 8347 c3/return - 8348 - 8349 test-is-identifier-z: - 8350 # . prologue - 8351 55/push-ebp - 8352 89/<- %ebp 4/r32/esp - 8353 # (eax..ecx) = "z$" - 8354 b8/copy-to-eax "z$"/imm32 - 8355 8b/-> *eax 1/r32/ecx - 8356 8d/copy-address *(eax+ecx+4) 1/r32/ecx - 8357 05/add-to-eax 4/imm32 - 8358 # var slice/ecx: slice = {eax, ecx} - 8359 51/push-ecx - 8360 50/push-eax - 8361 89/<- %ecx 4/r32/esp - 8362 # - 8363 (is-identifier? %ecx) - 8364 (check-ints-equal %eax 1 "F - test-is-identifier-z") - 8365 # . epilogue - 8366 89/<- %esp 5/r32/ebp - 8367 5d/pop-to-ebp - 8368 c3/return - 8369 - 8370 test-is-identifier-A: - 8371 # . prologue - 8372 55/push-ebp - 8373 89/<- %ebp 4/r32/esp - 8374 # (eax..ecx) = "A$" - 8375 b8/copy-to-eax "A$"/imm32 - 8376 8b/-> *eax 1/r32/ecx - 8377 8d/copy-address *(eax+ecx+4) 1/r32/ecx - 8378 05/add-to-eax 4/imm32 - 8379 # var slice/ecx: slice = {eax, ecx} - 8380 51/push-ecx - 8381 50/push-eax - 8382 89/<- %ecx 4/r32/esp - 8383 # - 8384 (is-identifier? %ecx) - 8385 (check-ints-equal %eax 1 "F - test-is-identifier-A") - 8386 # . epilogue - 8387 89/<- %esp 5/r32/ebp - 8388 5d/pop-to-ebp - 8389 c3/return - 8390 - 8391 test-is-identifier-Z: - 8392 # . prologue - 8393 55/push-ebp - 8394 89/<- %ebp 4/r32/esp - 8395 # (eax..ecx) = "Z$" - 8396 b8/copy-to-eax "Z$"/imm32 - 8397 8b/-> *eax 1/r32/ecx - 8398 8d/copy-address *(eax+ecx+4) 1/r32/ecx - 8399 05/add-to-eax 4/imm32 - 8400 # var slice/ecx: slice = {eax, ecx} - 8401 51/push-ecx - 8402 50/push-eax - 8403 89/<- %ecx 4/r32/esp - 8404 # - 8405 (is-identifier? %ecx) - 8406 (check-ints-equal %eax 1 "F - test-is-identifier-Z") - 8407 # . epilogue - 8408 89/<- %esp 5/r32/ebp - 8409 5d/pop-to-ebp - 8410 c3/return - 8411 - 8412 test-is-identifier-at: - 8413 # character before 'A' is invalid - 8414 # . prologue - 8415 55/push-ebp - 8416 89/<- %ebp 4/r32/esp - 8417 # (eax..ecx) = "@a" - 8418 b8/copy-to-eax "@a"/imm32 - 8419 8b/-> *eax 1/r32/ecx - 8420 8d/copy-address *(eax+ecx+4) 1/r32/ecx - 8421 05/add-to-eax 4/imm32 - 8422 # var slice/ecx: slice = {eax, ecx} - 8423 51/push-ecx - 8424 50/push-eax - 8425 89/<- %ecx 4/r32/esp - 8426 # - 8427 (is-identifier? %ecx) - 8428 (check-ints-equal %eax 0 "F - test-is-identifier-@") + 8008 0f 85/jump-if-!= break/disp32 + 8009 # if (word-slice == '->') break + 8010 (slice-equal? %ecx "->") # => eax + 8011 3d/compare-eax-and 0/imm32/false + 8012 0f 85/jump-if-!= break/disp32 + 8013 # if (word-slice == '{') abort + 8014 (slice-equal? %ecx "{") # => eax + 8015 3d/compare-eax-and 0/imm32/false + 8016 0f 85/jump-if-!= $populate-mu-function-signature:error1/disp32 + 8017 # if (word-slice == '}') abort + 8018 (slice-equal? %ecx "}") # => eax + 8019 3d/compare-eax-and 0/imm32/false + 8020 0f 85/jump-if-!= $populate-mu-function-signature:error1/disp32 + 8021 # v = parse-var-with-type(word-slice, first-line) + 8022 (parse-var-with-type %ecx *(ebp+8) %ebx *(ebp+0x10) *(ebp+0x14)) + 8023 # assert(v->register == null) + 8024 # . eax: (addr var) = lookup(v) + 8025 (lookup *ebx *(ebx+4)) # => eax + 8026 81 7/subop/compare *(eax+0x18) 0/imm32 # Var-register + 8027 0f 85/jump-if-!= $populate-mu-function-signature:error2/disp32 + 8028 # v->block-depth is implicitly 0 + 8029 # + 8030 # out->inouts = append(v, out->inouts) + 8031 8d/copy-address *(edi+8) 0/r32/eax # Function-inouts + 8032 (append-list Heap *ebx *(ebx+4) *(edi+8) *(edi+0xc) %eax) # Function-inouts, Function-inouts + 8033 # + 8034 e9/jump loop/disp32 + 8035 } + 8036 # save function outputs + 8037 { + 8038 $populate-mu-function-signature:check-for-out: + 8039 (next-mu-token *(ebp+8) %ecx) + 8040 (slice-empty? %ecx) # => eax + 8041 3d/compare-eax-and 0/imm32/false + 8042 0f 85/jump-if-!= break/disp32 + 8043 # if (word-slice == '{') abort + 8044 (slice-equal? %ecx "{") # => eax + 8045 3d/compare-eax-and 0/imm32/false + 8046 0f 85/jump-if-!= $populate-mu-function-signature:error1/disp32 + 8047 # if (word-slice == '->') abort + 8048 (slice-equal? %ecx "->") # => eax + 8049 3d/compare-eax-and 0/imm32/false + 8050 0f 85/jump-if-!= $populate-mu-function-signature:error1/disp32 + 8051 # if (word-slice == '}') abort + 8052 (slice-equal? %ecx "}") # => eax + 8053 3d/compare-eax-and 0/imm32/false + 8054 0f 85/jump-if-!= $populate-mu-function-signature:error1/disp32 + 8055 # v = parse-var-with-type(word-slice, first-line) + 8056 (parse-var-with-type %ecx *(ebp+8) %ebx *(ebp+0x10) *(ebp+0x14)) + 8057 # assert(var->register != null) + 8058 # . eax: (addr var) = lookup(v) + 8059 (lookup *ebx *(ebx+4)) # => eax + 8060 81 7/subop/compare *(eax+0x18) 0/imm32 # Var-register + 8061 0f 84/jump-if-= $populate-mu-function-signature:error3/disp32 + 8062 # out->outputs = append(v, out->outputs) + 8063 8d/copy-address *(edi+0x10) 0/r32/eax # Function-outputs + 8064 (append-list Heap *ebx *(ebx+4) *(edi+0x10) *(edi+0x14) %eax) # Function-outputs, Function-outputs + 8065 # + 8066 e9/jump loop/disp32 + 8067 } + 8068 $populate-mu-function-signature:done: + 8069 (check-no-tokens-left *(ebp+8)) + 8070 $populate-mu-function-signature:end: + 8071 # . reclaim locals + 8072 81 0/subop/add %esp 0x10/imm32 + 8073 # . restore registers + 8074 5f/pop-to-edi + 8075 5b/pop-to-ebx + 8076 5a/pop-to-edx + 8077 59/pop-to-ecx + 8078 58/pop-to-eax + 8079 # . epilogue + 8080 89/<- %esp 5/r32/ebp + 8081 5d/pop-to-ebp + 8082 c3/return + 8083 + 8084 $populate-mu-function-signature:error1: + 8085 # error("function signature not in form 'fn <name> {'") + 8086 (write-buffered *(ebp+0x10) "function signature not in form 'fn <name> [inouts] [-> outputs] {' -- '") + 8087 (flush *(ebp+0x10)) + 8088 (rewind-stream *(ebp+8)) + 8089 (write-stream-data *(ebp+0x10) *(ebp+8)) + 8090 (write-buffered *(ebp+0x10) "'\n") + 8091 (flush *(ebp+0x10)) + 8092 (stop *(ebp+0x14) 1) + 8093 # never gets here + 8094 + 8095 $populate-mu-function-signature:error2: + 8096 # error("fn " fn ": function inout '" var "' cannot be in a register") + 8097 (write-buffered *(ebp+0x10) "fn ") + 8098 50/push-eax + 8099 (lookup *edi *(edi+4)) # Function-name Function-name => eax + 8100 (write-buffered *(ebp+0x10) %eax) + 8101 58/pop-to-eax + 8102 (write-buffered *(ebp+0x10) ": function inout '") + 8103 (lookup *eax *(eax+4)) # Var-name Var-name => eax + 8104 (write-buffered *(ebp+0x10) %eax) + 8105 (write-buffered *(ebp+0x10) "' cannot be in a register") + 8106 (flush *(ebp+0x10)) + 8107 (stop *(ebp+0x14) 1) + 8108 # never gets here + 8109 + 8110 $populate-mu-function-signature:error3: + 8111 # error("fn " fn ": function output '" var "' must be in a register") + 8112 (write-buffered *(ebp+0x10) "fn ") + 8113 50/push-eax + 8114 (lookup *edi *(edi+4)) # Function-name Function-name => eax + 8115 (write-buffered *(ebp+0x10) %eax) + 8116 58/pop-to-eax + 8117 (write-buffered *(ebp+0x10) ": function output '") + 8118 (lookup *ebx *(ebx+4)) # => eax + 8119 (lookup *eax *(eax+4)) # Var-name Var-name => eax + 8120 (write-buffered *(ebp+0x10) %eax) + 8121 (write-buffered *(ebp+0x10) "' must be in a register, in instruction '") + 8122 (rewind-stream *(ebp+8)) + 8123 (write-stream-data *(ebp+0x10) *(ebp+8)) + 8124 (write-buffered *(ebp+0x10) "'\n") + 8125 (flush *(ebp+0x10)) + 8126 (stop *(ebp+0x14) 1) + 8127 # never gets here + 8128 + 8129 test-function-header-with-arg: + 8130 # . prologue + 8131 55/push-ebp + 8132 89/<- %ebp 4/r32/esp + 8133 # setup + 8134 (clear-stream _test-input-stream) + 8135 (write _test-input-stream "foo n: int {\n") + 8136 # var result/ecx: function + 8137 2b/subtract *Function-size 4/r32/esp + 8138 89/<- %ecx 4/r32/esp + 8139 (zero-out %ecx *Function-size) + 8140 # var vars/ebx: (stack live-var 16) + 8141 81 5/subop/subtract %esp 0xc0/imm32 + 8142 68/push 0xc0/imm32/size + 8143 68/push 0/imm32/top + 8144 89/<- %ebx 4/r32/esp + 8145 # convert + 8146 (populate-mu-function-header _test-input-stream %ecx %ebx Stderr 0) + 8147 # check result->name + 8148 (lookup *ecx *(ecx+4)) # Function-name Function-name => eax + 8149 (check-strings-equal %eax "foo" "F - test-function-header-with-arg/name") + 8150 # var v/edx: (addr var) = result->inouts->value + 8151 (lookup *(ecx+8) *(ecx+0xc)) # Function-inouts Function-inouts => eax + 8152 (lookup *eax *(eax+4)) # List-value List-value => eax + 8153 89/<- %edx 0/r32/eax + 8154 # check v->name + 8155 (lookup *edx *(edx+4)) # Var-name Var-name => eax + 8156 (check-strings-equal %eax "n" "F - test-function-header-with-arg/inout:0") + 8157 # check v->type + 8158 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax + 8159 (check-ints-equal *eax 1 "F - test-function-header-with-arg/inout:0/type:0") # Type-tree-is-atom + 8160 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-arg/inout:0/type:1") # Type-tree-value + 8161 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-arg/inout:0/type:2") # Type-tree-right + 8162 # . epilogue + 8163 89/<- %esp 5/r32/ebp + 8164 5d/pop-to-ebp + 8165 c3/return + 8166 + 8167 test-function-header-with-multiple-args: + 8168 # . prologue + 8169 55/push-ebp + 8170 89/<- %ebp 4/r32/esp + 8171 # setup + 8172 (clear-stream _test-input-stream) + 8173 (write _test-input-stream "foo a: int, b: int c: int {\n") + 8174 # result/ecx: function + 8175 2b/subtract *Function-size 4/r32/esp + 8176 89/<- %ecx 4/r32/esp + 8177 (zero-out %ecx *Function-size) + 8178 # var vars/ebx: (stack live-var 16) + 8179 81 5/subop/subtract %esp 0xc0/imm32 + 8180 68/push 0xc0/imm32/size + 8181 68/push 0/imm32/top + 8182 89/<- %ebx 4/r32/esp + 8183 # convert + 8184 (populate-mu-function-header _test-input-stream %ecx %ebx Stderr 0) + 8185 # check result->name + 8186 (lookup *ecx *(ecx+4)) # Function-name Function-name => eax + 8187 (check-strings-equal %eax "foo" "F - test-function-header-with-multiple-args/name") + 8188 # var inouts/edx: (addr list var) = lookup(result->inouts) + 8189 (lookup *(ecx+8) *(ecx+0xc)) # Function-inouts Function-inouts => eax + 8190 89/<- %edx 0/r32/eax + 8191 $test-function-header-with-multiple-args:inout0: + 8192 # var v/ebx: (addr var) = lookup(inouts->value) + 8193 (lookup *edx *(edx+4)) # List-value List-value => eax + 8194 89/<- %ebx 0/r32/eax + 8195 # check v->name + 8196 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax + 8197 (check-strings-equal %eax "a" "F - test-function-header-with-multiple-args/inout:0") # Var-name + 8198 # check v->type + 8199 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax + 8200 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args/inout:0/type:0") # Type-tree-is-atom + 8201 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args/inout:0/type:1") # Type-tree-value + 8202 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-multiple-args/inout:0/type:2") # Type-tree-right + 8203 $test-function-header-with-multiple-args:inout1: + 8204 # inouts = lookup(inouts->next) + 8205 (lookup *(edx+8) *(edx+0xc)) # List-next List-next => eax + 8206 89/<- %edx 0/r32/eax + 8207 # v = lookup(inouts->value) + 8208 (lookup *edx *(edx+4)) # List-value List-value => eax + 8209 89/<- %ebx 0/r32/eax + 8210 # check v->name + 8211 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax + 8212 (check-strings-equal %eax "b" "F - test-function-header-with-multiple-args/inout:1") # Var-name + 8213 # check v->type + 8214 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax + 8215 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args/inout:1/type:0") # Type-tree-is-atom + 8216 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args/inout:1/type:1") # Type-tree-value + 8217 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-multiple-args/inout:1/type:2") # Type-tree-right + 8218 $test-function-header-with-multiple-args:inout2: + 8219 # inouts = lookup(inouts->next) + 8220 (lookup *(edx+8) *(edx+0xc)) # List-next List-next => eax + 8221 89/<- %edx 0/r32/eax + 8222 # v = lookup(inouts->value) + 8223 (lookup *edx *(edx+4)) # List-value List-value => eax + 8224 89/<- %ebx 0/r32/eax + 8225 # check v->name + 8226 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax + 8227 (check-strings-equal %eax "c" "F - test-function-header-with-multiple-args/inout:2") # Var-name + 8228 # check v->type + 8229 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax + 8230 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args/inout:2/type:0") # Type-tree-is-atom + 8231 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args/inout:2/type:1") # Type-tree-value + 8232 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-multiple-args/inout:2/type:2") # Type-tree-right + 8233 # . epilogue + 8234 89/<- %esp 5/r32/ebp + 8235 5d/pop-to-ebp + 8236 c3/return + 8237 + 8238 test-function-header-with-multiple-args-and-outputs: + 8239 # . prologue + 8240 55/push-ebp + 8241 89/<- %ebp 4/r32/esp + 8242 # setup + 8243 (clear-stream _test-input-stream) + 8244 (write _test-input-stream "foo a: int, b: int, c: int -> x/ecx: int y/edx: int {\n") + 8245 # result/ecx: function + 8246 2b/subtract *Function-size 4/r32/esp + 8247 89/<- %ecx 4/r32/esp + 8248 (zero-out %ecx *Function-size) + 8249 # var vars/ebx: (stack live-var 16) + 8250 81 5/subop/subtract %esp 0xc0/imm32 + 8251 68/push 0xc0/imm32/size + 8252 68/push 0/imm32/top + 8253 89/<- %ebx 4/r32/esp + 8254 # convert + 8255 (populate-mu-function-header _test-input-stream %ecx %ebx Stderr 0) + 8256 # check result->name + 8257 (lookup *ecx *(ecx+4)) # Function-name Function-name => eax + 8258 (check-strings-equal %eax "foo" "F - test-function-header-with-multiple-args-and-outputs/name") + 8259 # var inouts/edx: (addr list var) = lookup(result->inouts) + 8260 (lookup *(ecx+8) *(ecx+0xc)) # Function-inouts Function-inouts => eax + 8261 89/<- %edx 0/r32/eax + 8262 $test-function-header-with-multiple-args-and-outputs:inout0: + 8263 # var v/ebx: (addr var) = lookup(inouts->value) + 8264 (lookup *edx *(edx+4)) # List-value List-value => eax + 8265 89/<- %ebx 0/r32/eax + 8266 # check v->name + 8267 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax + 8268 (check-strings-equal %eax "a" "F - test-function-header-with-multiple-args-and-outputs/inout:0") + 8269 # check v->type + 8270 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax + 8271 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args-and-outputs/inout:0/type:0") # Type-tree-is-atom + 8272 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args-and-outputs/inout:0/type:1") # Type-tree-value + 8273 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-multiple-args-and-outputs/inout:0/type:2") # Type-tree-right + 8274 $test-function-header-with-multiple-args-and-outputs:inout1: + 8275 # inouts = lookup(inouts->next) + 8276 (lookup *(edx+8) *(edx+0xc)) # List-next List-next => eax + 8277 89/<- %edx 0/r32/eax + 8278 # v = lookup(inouts->value) + 8279 (lookup *edx *(edx+4)) # List-value List-value => eax + 8280 89/<- %ebx 0/r32/eax + 8281 # check v->name + 8282 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax + 8283 (check-strings-equal %eax "b" "F - test-function-header-with-multiple-args-and-outputs/inout:1") + 8284 # check v->type + 8285 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax + 8286 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args-and-outputs/inout:1/type:0") # Type-tree-is-atom + 8287 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args-and-outputs/inout:1/type:1") # Type-tree-value + 8288 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-multiple-args-and-outputs/inout:1/type:2") # Type-tree-right + 8289 $test-function-header-with-multiple-args-and-outputs:inout2: + 8290 # inouts = lookup(inouts->next) + 8291 (lookup *(edx+8) *(edx+0xc)) # List-next List-next => eax + 8292 89/<- %edx 0/r32/eax + 8293 # v = lookup(inouts->value) + 8294 (lookup *edx *(edx+4)) # List-value List-value => eax + 8295 89/<- %ebx 0/r32/eax + 8296 # check v->name + 8297 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax + 8298 (check-strings-equal %eax "c" "F - test-function-header-with-multiple-args-and-outputs/inout:2") + 8299 # check v->type + 8300 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax + 8301 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args-and-outputs/inout:2/type:0") # Type-tree-is-atom + 8302 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args-and-outputs/inout:2/type:1") # Type-tree-value + 8303 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-multiple-args-and-outputs/inout:2/type:2") # Type-tree-right + 8304 $test-function-header-with-multiple-args-and-outputs:out0: + 8305 # var outputs/edx: (addr list var) = lookup(result->outputs) + 8306 (lookup *(ecx+0x10) *(ecx+0x14)) # Function-outputs Function-outputs => eax + 8307 89/<- %edx 0/r32/eax + 8308 # v = lookup(outputs->value) + 8309 (lookup *edx *(edx+4)) # List-value List-value => eax + 8310 89/<- %ebx 0/r32/eax + 8311 # check v->name + 8312 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax + 8313 (check-strings-equal %eax "x" "F - test-function-header-with-multiple-args-and-outputs/output:0") + 8314 # check v->register + 8315 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register Var-register => eax + 8316 (check-strings-equal %eax "ecx" "F - test-function-header-with-multiple-args-and-outputs/output:0/register") + 8317 # check v->type + 8318 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax + 8319 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args-and-outputs/output:0/type:0") # Type-tree-is-atom + 8320 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args-and-outputs/output:0/type:1") # Type-tree-value + 8321 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-multiple-args-and-outputs/output:0/type:2") # Type-tree-right + 8322 $test-function-header-with-multiple-args-and-outputs:out1: + 8323 # outputs = lookup(outputs->next) + 8324 (lookup *(edx+8) *(edx+0xc)) # List-next List-next => eax + 8325 89/<- %edx 0/r32/eax + 8326 # v = lookup(inouts->value) + 8327 (lookup *edx *(edx+4)) # List-value List-value => eax + 8328 89/<- %ebx 0/r32/eax + 8329 # check v->name + 8330 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax + 8331 (check-strings-equal %eax "y" "F - test-function-header-with-multiple-args-and-outputs/output:1") + 8332 # check v->register + 8333 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register Var-register => eax + 8334 (check-strings-equal %eax "edx" "F - test-function-header-with-multiple-args-and-outputs/output:1/register") + 8335 # check v->type + 8336 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax + 8337 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args-and-outputs/output:1/type:0") # Type-tree-is-atom + 8338 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args-and-outputs/output:1/type:1") # Type-tree-value + 8339 (check-ints-equal *(eax+0c) 0 "F - test-function-header-with-multiple-args-and-outputs/output:1/type:2") # Type-tree-right + 8340 # . epilogue + 8341 89/<- %esp 5/r32/ebp + 8342 5d/pop-to-ebp + 8343 c3/return + 8344 + 8345 # format for variables with types + 8346 # x: int + 8347 # x: int, + 8348 # x/eax: int + 8349 # x/eax: int, + 8350 # ignores at most one trailing comma + 8351 # WARNING: modifies name + 8352 parse-var-with-type: # name: (addr slice), first-line: (addr stream byte), out: (addr handle var), err: (addr buffered-file), ed: (addr exit-descriptor) + 8353 # pseudocode: + 8354 # var s: slice + 8355 # if (!slice-ends-with(name, ":")) + 8356 # abort + 8357 # --name->end to skip ':' + 8358 # next-token-from-slice(name->start, name->end, '/', s) + 8359 # new-var-from-slice(s, out) + 8360 # ## register + 8361 # next-token-from-slice(s->end, name->end, '/', s) + 8362 # if (!slice-empty?(s)) + 8363 # out->register = slice-to-string(s) + 8364 # ## type + 8365 # var type: (handle type-tree) = parse-type(first-line) + 8366 # out->type = type + 8367 # + 8368 # . prologue + 8369 55/push-ebp + 8370 89/<- %ebp 4/r32/esp + 8371 # . save registers + 8372 50/push-eax + 8373 51/push-ecx + 8374 52/push-edx + 8375 53/push-ebx + 8376 56/push-esi + 8377 57/push-edi + 8378 # esi = name + 8379 8b/-> *(ebp+8) 6/r32/esi + 8380 # if (!slice-ends-with?(name, ":")) abort + 8381 8b/-> *(esi+4) 1/r32/ecx # Slice-end + 8382 49/decrement-ecx + 8383 8a/copy-byte *ecx 1/r32/CL + 8384 81 4/subop/and %ecx 0xff/imm32 + 8385 81 7/subop/compare %ecx 0x3a/imm32/colon + 8386 0f 85/jump-if-!= $parse-var-with-type:abort/disp32 + 8387 # --name->end to skip ':' + 8388 ff 1/subop/decrement *(esi+4) + 8389 # var s/ecx: slice + 8390 68/push 0/imm32/end + 8391 68/push 0/imm32/start + 8392 89/<- %ecx 4/r32/esp + 8393 $parse-var-with-type:parse-name: + 8394 (next-token-from-slice *esi *(esi+4) 0x2f %ecx) # Slice-start, Slice-end, '/' + 8395 $parse-var-with-type:create-var: + 8396 # new-var-from-slice(s, out) + 8397 (new-var-from-slice Heap %ecx *(ebp+0x10)) + 8398 # save out->register + 8399 $parse-var-with-type:save-register: + 8400 # . var out-addr/edi: (addr var) = lookup(*out) + 8401 8b/-> *(ebp+0x10) 7/r32/edi + 8402 (lookup *edi *(edi+4)) # => eax + 8403 89/<- %edi 0/r32/eax + 8404 # . s = next-token(...) + 8405 (next-token-from-slice *(ecx+4) *(esi+4) 0x2f %ecx) # s->end, name->end, '/' + 8406 # . if (!slice-empty?(s)) out->register = slice-to-string(s) + 8407 { + 8408 $parse-var-with-type:write-register: + 8409 (slice-empty? %ecx) # => eax + 8410 3d/compare-eax-and 0/imm32/false + 8411 75/jump-if-!= break/disp8 + 8412 # out->register = slice-to-string(s) + 8413 8d/copy-address *(edi+0x18) 0/r32/eax # Var-register + 8414 (slice-to-string Heap %ecx %eax) + 8415 } + 8416 $parse-var-with-type:save-type: + 8417 8d/copy-address *(edi+8) 0/r32/eax # Var-type + 8418 (parse-type Heap *(ebp+0xc) %eax *(ebp+0x14) *(ebp+0x18)) + 8419 $parse-var-with-type:end: + 8420 # . reclaim locals + 8421 81 0/subop/add %esp 8/imm32 + 8422 # . restore registers + 8423 5f/pop-to-edi + 8424 5e/pop-to-esi + 8425 5b/pop-to-ebx + 8426 5a/pop-to-edx + 8427 59/pop-to-ecx + 8428 58/pop-to-eax 8429 # . epilogue 8430 89/<- %esp 5/r32/ebp 8431 5d/pop-to-ebp 8432 c3/return 8433 - 8434 test-is-identifier-square-bracket: - 8435 # character after 'Z' is invalid - 8436 # . prologue - 8437 55/push-ebp - 8438 89/<- %ebp 4/r32/esp - 8439 # (eax..ecx) = "[a" - 8440 b8/copy-to-eax "[a"/imm32 - 8441 8b/-> *eax 1/r32/ecx - 8442 8d/copy-address *(eax+ecx+4) 1/r32/ecx - 8443 05/add-to-eax 4/imm32 - 8444 # var slice/ecx: slice = {eax, ecx} - 8445 51/push-ecx - 8446 50/push-eax - 8447 89/<- %ecx 4/r32/esp - 8448 # - 8449 (is-identifier? %ecx) - 8450 (check-ints-equal %eax 0 "F - test-is-identifier-@") - 8451 # . epilogue - 8452 89/<- %esp 5/r32/ebp - 8453 5d/pop-to-ebp - 8454 c3/return - 8455 - 8456 test-is-identifier-backtick: - 8457 # character before 'a' is invalid - 8458 # . prologue - 8459 55/push-ebp - 8460 89/<- %ebp 4/r32/esp - 8461 # (eax..ecx) = "`a" - 8462 b8/copy-to-eax "`a"/imm32 - 8463 8b/-> *eax 1/r32/ecx - 8464 8d/copy-address *(eax+ecx+4) 1/r32/ecx - 8465 05/add-to-eax 4/imm32 - 8466 # var slice/ecx: slice = {eax, ecx} - 8467 51/push-ecx - 8468 50/push-eax - 8469 89/<- %ecx 4/r32/esp - 8470 # - 8471 (is-identifier? %ecx) - 8472 (check-ints-equal %eax 0 "F - test-is-identifier-backtick") - 8473 # . epilogue - 8474 89/<- %esp 5/r32/ebp - 8475 5d/pop-to-ebp - 8476 c3/return - 8477 - 8478 test-is-identifier-curly-brace-open: - 8479 # character after 'z' is invalid; also used for blocks - 8480 # . prologue - 8481 55/push-ebp - 8482 89/<- %ebp 4/r32/esp - 8483 # (eax..ecx) = "{a" - 8484 b8/copy-to-eax "{a"/imm32 - 8485 8b/-> *eax 1/r32/ecx - 8486 8d/copy-address *(eax+ecx+4) 1/r32/ecx - 8487 05/add-to-eax 4/imm32 - 8488 # var slice/ecx: slice = {eax, ecx} - 8489 51/push-ecx - 8490 50/push-eax - 8491 89/<- %ecx 4/r32/esp - 8492 # - 8493 (is-identifier? %ecx) - 8494 (check-ints-equal %eax 0 "F - test-is-identifier-curly-brace-open") - 8495 # . epilogue - 8496 89/<- %esp 5/r32/ebp - 8497 5d/pop-to-ebp - 8498 c3/return - 8499 - 8500 test-is-identifier-curly-brace-close: - 8501 # . prologue - 8502 55/push-ebp - 8503 89/<- %ebp 4/r32/esp - 8504 # (eax..ecx) = "}a" - 8505 b8/copy-to-eax "}a"/imm32 - 8506 8b/-> *eax 1/r32/ecx - 8507 8d/copy-address *(eax+ecx+4) 1/r32/ecx - 8508 05/add-to-eax 4/imm32 - 8509 # var slice/ecx: slice = {eax, ecx} - 8510 51/push-ecx - 8511 50/push-eax - 8512 89/<- %ecx 4/r32/esp - 8513 # - 8514 (is-identifier? %ecx) - 8515 (check-ints-equal %eax 0 "F - test-is-identifier-curly-brace-close") - 8516 # . epilogue - 8517 89/<- %esp 5/r32/ebp - 8518 5d/pop-to-ebp - 8519 c3/return - 8520 - 8521 test-is-identifier-hyphen: - 8522 # disallow leading '-' since '->' has special meaning - 8523 # . prologue - 8524 55/push-ebp - 8525 89/<- %ebp 4/r32/esp - 8526 # (eax..ecx) = "-a" - 8527 b8/copy-to-eax "-a"/imm32 - 8528 8b/-> *eax 1/r32/ecx - 8529 8d/copy-address *(eax+ecx+4) 1/r32/ecx - 8530 05/add-to-eax 4/imm32 - 8531 # var slice/ecx: slice = {eax, ecx} - 8532 51/push-ecx - 8533 50/push-eax - 8534 89/<- %ecx 4/r32/esp - 8535 # - 8536 (is-identifier? %ecx) - 8537 (check-ints-equal %eax 0 "F - test-is-identifier-hyphen") - 8538 # . epilogue - 8539 89/<- %esp 5/r32/ebp - 8540 5d/pop-to-ebp - 8541 c3/return - 8542 - 8543 populate-mu-function-body: # in: (addr buffered-file), out: (addr function), vars: (addr stack live-var), err: (addr buffered-file), ed: (addr exit-descriptor) - 8544 # . prologue - 8545 55/push-ebp - 8546 89/<- %ebp 4/r32/esp - 8547 # . save registers - 8548 50/push-eax - 8549 56/push-esi - 8550 57/push-edi - 8551 # esi = in - 8552 8b/-> *(ebp+8) 6/r32/esi - 8553 # edi = out - 8554 8b/-> *(ebp+0xc) 7/r32/edi - 8555 # initialize some global state - 8556 c7 0/subop/copy *Curr-block-depth 1/imm32 - 8557 # parse-mu-block(in, vars, out, out->body) - 8558 8d/copy-address *(edi+0x18) 0/r32/eax # Function-body - 8559 (parse-mu-block %esi *(ebp+0x10) %edi %eax *(ebp+0x14) *(ebp+0x18)) - 8560 $populate-mu-function-body:end: - 8561 # . restore registers - 8562 5f/pop-to-edi - 8563 5e/pop-to-esi - 8564 58/pop-to-eax - 8565 # . epilogue - 8566 89/<- %esp 5/r32/ebp - 8567 5d/pop-to-ebp - 8568 c3/return - 8569 - 8570 # parses a block, assuming that the leading '{' has already been read by the caller - 8571 parse-mu-block: # in: (addr buffered-file), vars: (addr stack live-var), fn: (addr function), out: (addr handle block), err: (addr buffered-file), ed: (addr exit-descriptor) - 8572 # pseudocode: - 8573 # var line: (stream byte 512) - 8574 # var word-slice: slice - 8575 # allocate(Heap, Stmt-size, out) - 8576 # var out-addr: (addr block) = lookup(*out) - 8577 # out-addr->tag = 0/block - 8578 # out-addr->var = some unique name - 8579 # push(vars, {out-addr->var, false}) - 8580 # while true # line loop - 8581 # clear-stream(line) - 8582 # read-line-buffered(in, line) - 8583 # if (line->write == 0) break # end of file - 8584 # word-slice = next-mu-token(line) - 8585 # if slice-empty?(word-slice) # end of line - 8586 # continue - 8587 # else if slice-starts-with?(word-slice, "#") - 8588 # continue - 8589 # else if slice-equal?(word-slice, "{") - 8590 # assert(no-tokens-in(line)) - 8591 # block = parse-mu-block(in, vars, fn) - 8592 # append-to-block(out-addr, block) - 8593 # else if slice-equal?(word-slice, "}") - 8594 # break - 8595 # else if slice-ends-with?(word-slice, ":") - 8596 # # TODO: error-check the rest of 'line' - 8597 # --word-slice->end to skip ':' - 8598 # named-block = parse-mu-named-block(word-slice, in, vars, fn) - 8599 # append-to-block(out-addr, named-block) - 8600 # else if slice-equal?(word-slice, "var") - 8601 # var-def = parse-mu-var-def(line, vars, fn) - 8602 # append-to-block(out-addr, var-def) - 8603 # else - 8604 # stmt = parse-mu-stmt(line, vars, fn) - 8605 # append-to-block(out-addr, stmt) - 8606 # pop(vars) - 8607 # - 8608 # . prologue - 8609 55/push-ebp - 8610 89/<- %ebp 4/r32/esp - 8611 # . save registers - 8612 50/push-eax - 8613 51/push-ecx - 8614 52/push-edx - 8615 53/push-ebx - 8616 57/push-edi - 8617 # var line/ecx: (stream byte 512) - 8618 81 5/subop/subtract %esp 0x200/imm32 - 8619 68/push 0x200/imm32/size - 8620 68/push 0/imm32/read - 8621 68/push 0/imm32/write - 8622 89/<- %ecx 4/r32/esp - 8623 # var word-slice/edx: slice - 8624 68/push 0/imm32/end - 8625 68/push 0/imm32/start - 8626 89/<- %edx 4/r32/esp - 8627 # allocate into out - 8628 (allocate Heap *Stmt-size *(ebp+0x14)) - 8629 # var out-addr/edi: (addr block) = lookup(*out) - 8630 8b/-> *(ebp+0x14) 7/r32/edi - 8631 (lookup *edi *(edi+4)) # => eax - 8632 89/<- %edi 0/r32/eax - 8633 # out-addr->tag is 0 (block) by default - 8634 # set out-addr->var - 8635 8d/copy-address *(edi+0xc) 0/r32/eax # Block-var - 8636 (new-block-name *(ebp+0x10) %eax) - 8637 # push(vars, out-addr->var) - 8638 (push *(ebp+0xc) *(edi+0xc)) # Block-var - 8639 (push *(ebp+0xc) *(edi+0x10)) # Block-var - 8640 (push *(ebp+0xc) 0) # false - 8641 # increment *Curr-block-depth - 8642 ff 0/subop/increment *Curr-block-depth - 8643 { - 8644 $parse-mu-block:line-loop: - 8645 # line = read-line-buffered(in) - 8646 (clear-stream %ecx) - 8647 (read-line-buffered *(ebp+8) %ecx) - 8648 #? (write-buffered Stderr "line: ") - 8649 #? (write-stream-data Stderr %ecx) - 8650 #? #? (write-buffered Stderr Newline) # line has its own newline - 8651 #? (flush Stderr) - 8652 #? (rewind-stream %ecx) - 8653 # if (line->write == 0) break - 8654 81 7/subop/compare *ecx 0/imm32 - 8655 0f 84/jump-if-= break/disp32 - 8656 #? (write-buffered Stderr "vars:\n") - 8657 #? (dump-vars *(ebp+0xc)) - 8658 # word-slice = next-mu-token(line) - 8659 (next-mu-token %ecx %edx) - 8660 #? (write-buffered Stderr "word: ") - 8661 #? (write-slice-buffered Stderr %edx) - 8662 #? (write-buffered Stderr Newline) - 8663 #? (flush Stderr) - 8664 # if slice-empty?(word-slice) continue - 8665 (slice-empty? %edx) - 8666 3d/compare-eax-and 0/imm32/false - 8667 0f 85/jump-if-!= loop/disp32 - 8668 # if (slice-starts-with?(word-slice, '#') continue - 8669 # . eax = *word-slice->start - 8670 8b/-> *edx 0/r32/eax - 8671 8a/copy-byte *eax 0/r32/AL - 8672 81 4/subop/and %eax 0xff/imm32 - 8673 # . if (eax == '#') continue - 8674 3d/compare-eax-and 0x23/imm32/hash - 8675 0f 84/jump-if-= loop/disp32 - 8676 # if slice-equal?(word-slice, "{") - 8677 { - 8678 $parse-mu-block:check-for-block: - 8679 (slice-equal? %edx "{") - 8680 3d/compare-eax-and 0/imm32/false - 8681 74/jump-if-= break/disp8 - 8682 (check-no-tokens-left %ecx) - 8683 # parse new block and append - 8684 # . var tmp/eax: (handle block) - 8685 68/push 0/imm32 - 8686 68/push 0/imm32 - 8687 89/<- %eax 4/r32/esp - 8688 # . - 8689 (parse-mu-block *(ebp+8) *(ebp+0xc) *(ebp+0x10) %eax *(ebp+0x18) *(ebp+0x1c)) - 8690 (append-to-block Heap %edi *eax *(eax+4)) - 8691 # . reclaim tmp - 8692 81 0/subop/add %esp 8/imm32 - 8693 # . - 8694 e9/jump $parse-mu-block:line-loop/disp32 - 8695 } - 8696 # if slice-equal?(word-slice, "}") break - 8697 $parse-mu-block:check-for-end: - 8698 (slice-equal? %edx "}") - 8699 3d/compare-eax-and 0/imm32/false - 8700 0f 85/jump-if-!= break/disp32 - 8701 # if slice-ends-with?(word-slice, ":") parse named block and append - 8702 { - 8703 $parse-mu-block:check-for-named-block: - 8704 # . eax = *(word-slice->end-1) - 8705 8b/-> *(edx+4) 0/r32/eax - 8706 48/decrement-eax - 8707 8a/copy-byte *eax 0/r32/AL - 8708 81 4/subop/and %eax 0xff/imm32 - 8709 # . if (eax != ':') break - 8710 3d/compare-eax-and 0x3a/imm32/colon - 8711 0f 85/jump-if-!= break/disp32 - 8712 # TODO: error-check the rest of 'line' - 8713 # - 8714 # skip ':' - 8715 ff 1/subop/decrement *(edx+4) # Slice-end - 8716 # var tmp/eax: (handle block) - 8717 68/push 0/imm32 - 8718 68/push 0/imm32 - 8719 89/<- %eax 4/r32/esp - 8720 # - 8721 (parse-mu-named-block %edx *(ebp+8) *(ebp+0xc) *(ebp+0x10) %eax *(ebp+0x18) *(ebp+0x1c)) - 8722 (append-to-block Heap %edi *eax *(eax+4)) - 8723 # reclaim tmp - 8724 81 0/subop/add %esp 8/imm32 - 8725 # - 8726 e9/jump $parse-mu-block:line-loop/disp32 - 8727 } - 8728 # if slice-equal?(word-slice, "var") - 8729 { - 8730 $parse-mu-block:check-for-var: - 8731 (slice-equal? %edx "var") - 8732 3d/compare-eax-and 0/imm32/false - 8733 74/jump-if-= break/disp8 - 8734 # var tmp/eax: (handle block) - 8735 68/push 0/imm32 - 8736 68/push 0/imm32 - 8737 89/<- %eax 4/r32/esp - 8738 # - 8739 (parse-mu-var-def %ecx *(ebp+0xc) %eax *(ebp+0x10) *(ebp+0x18) *(ebp+0x1c)) - 8740 (append-to-block Heap %edi *eax *(eax+4)) - 8741 # reclaim tmp - 8742 81 0/subop/add %esp 8/imm32 - 8743 # - 8744 e9/jump $parse-mu-block:line-loop/disp32 - 8745 } - 8746 $parse-mu-block:regular-stmt: - 8747 # otherwise - 8748 # var tmp/eax: (handle block) - 8749 68/push 0/imm32 - 8750 68/push 0/imm32 - 8751 89/<- %eax 4/r32/esp - 8752 # - 8753 (parse-mu-stmt %ecx *(ebp+0xc) *(ebp+0x10) %eax *(ebp+0x18) *(ebp+0x1c)) - 8754 (append-to-block Heap %edi *eax *(eax+4)) - 8755 # reclaim tmp - 8756 81 0/subop/add %esp 8/imm32 - 8757 # - 8758 e9/jump loop/disp32 - 8759 } # end line loop - 8760 (clean-up-blocks *(ebp+0xc) *Curr-block-depth *(ebp+0x10)) - 8761 # decrement *Curr-block-depth - 8762 ff 1/subop/decrement *Curr-block-depth - 8763 # pop(vars) - 8764 (pop *(ebp+0xc)) # => eax - 8765 (pop *(ebp+0xc)) # => eax - 8766 (pop *(ebp+0xc)) # => eax - 8767 $parse-mu-block:end: - 8768 # . reclaim locals - 8769 81 0/subop/add %esp 0x214/imm32 - 8770 # . restore registers - 8771 5f/pop-to-edi - 8772 5b/pop-to-ebx - 8773 5a/pop-to-edx - 8774 59/pop-to-ecx - 8775 58/pop-to-eax - 8776 # . epilogue - 8777 89/<- %esp 5/r32/ebp - 8778 5d/pop-to-ebp - 8779 c3/return - 8780 - 8781 $parse-mu-block:abort: - 8782 # error("'{' or '}' should be on its own line, but got '") - 8783 (write-buffered *(ebp+0x18) "'{' or '}' should be on its own line, but got '") - 8784 (rewind-stream %ecx) - 8785 (write-stream-data *(ebp+0x18) %ecx) - 8786 (write-buffered *(ebp+0x18) "'\n") - 8787 (flush *(ebp+0x18)) - 8788 (stop *(ebp+0x1c) 1) - 8789 # never gets here - 8790 - 8791 new-block-name: # fn: (addr function), out: (addr handle var) - 8792 # . prologue - 8793 55/push-ebp - 8794 89/<- %ebp 4/r32/esp - 8795 # . save registers - 8796 50/push-eax - 8797 51/push-ecx - 8798 52/push-edx - 8799 # var n/ecx: int = len(fn->name) + 10 for an int + 2 for '$:' - 8800 8b/-> *(ebp+8) 0/r32/eax - 8801 (lookup *eax *(eax+4)) # Function-name Function-name => eax - 8802 8b/-> *eax 0/r32/eax # String-size - 8803 05/add-to-eax 0xd/imm32 # 10 + 2 for '$:' - 8804 89/<- %ecx 0/r32/eax - 8805 # var name/edx: (stream byte n) - 8806 29/subtract-from %esp 1/r32/ecx - 8807 ff 6/subop/push %ecx - 8808 68/push 0/imm32/read - 8809 68/push 0/imm32/write - 8810 89/<- %edx 4/r32/esp - 8811 (clear-stream %edx) - 8812 # eax = fn->name - 8813 8b/-> *(ebp+8) 0/r32/eax - 8814 (lookup *eax *(eax+4)) # Function-name Function-name => eax - 8815 # construct result using Next-block-index (and increment it) - 8816 (write %edx "$") - 8817 (write %edx %eax) - 8818 (write %edx ":") - 8819 (write-int32-hex %edx *Next-block-index) - 8820 ff 0/subop/increment *Next-block-index - 8821 # var s/eax: slice = {name->data, name->data + name->write} (clobbering edx) - 8822 # . eax = name->write - 8823 8b/-> *edx 0/r32/eax - 8824 # . edx = name->data - 8825 8d/copy-address *(edx+0xc) 2/r32/edx - 8826 # . eax = name->write + name->data - 8827 01/add-to %eax 2/r32/edx - 8828 # . push {edx, eax} - 8829 ff 6/subop/push %eax - 8830 ff 6/subop/push %edx - 8831 89/<- %eax 4/r32/esp - 8832 # out = new literal(s) - 8833 (new-literal Heap %eax *(ebp+0xc)) - 8834 #? 8b/-> *(ebp+0xc) 0/r32/eax - 8835 #? (write-buffered Stderr "type allocid in caller after new-literal: ") - 8836 #? (write-int32-hex-buffered Stderr *(eax+8)) - 8837 #? (write-buffered Stderr " for var ") - 8838 #? (write-int32-hex-buffered Stderr %eax) - 8839 #? (write-buffered Stderr Newline) - 8840 #? (flush Stderr) - 8841 $new-block-name:end: - 8842 # . reclaim locals - 8843 81 0/subop/add %ecx 0xc/imm32 # name.{read/write/len} - 8844 81 0/subop/add %ecx 8/imm32 # slice - 8845 01/add-to %esp 1/r32/ecx - 8846 # . restore registers - 8847 5a/pop-to-edx - 8848 59/pop-to-ecx - 8849 58/pop-to-eax - 8850 # . epilogue - 8851 89/<- %esp 5/r32/ebp - 8852 5d/pop-to-ebp - 8853 c3/return - 8854 - 8855 check-no-tokens-left: # line: (addr stream byte) - 8856 # . prologue - 8857 55/push-ebp - 8858 89/<- %ebp 4/r32/esp - 8859 # . save registers - 8860 50/push-eax - 8861 51/push-ecx - 8862 # var s/ecx: slice - 8863 68/push 0/imm32/end - 8864 68/push 0/imm32/start - 8865 89/<- %ecx 4/r32/esp - 8866 # - 8867 (next-mu-token *(ebp+8) %ecx) - 8868 # if slice-empty?(s) return - 8869 (slice-empty? %ecx) - 8870 3d/compare-eax-and 0/imm32/false - 8871 75/jump-if-!= $check-no-tokens-left:end/disp8 - 8872 # if (slice-starts-with?(s, '#') return - 8873 # . eax = *s->start - 8874 8b/-> *edx 0/r32/eax - 8875 8a/copy-byte *eax 0/r32/AL - 8876 81 4/subop/and %eax 0xff/imm32 - 8877 # . if (eax == '#') continue - 8878 3d/compare-eax-and 0x23/imm32/hash - 8879 74/jump-if-= $check-no-tokens-left:end/disp8 - 8880 # abort - 8881 (write-buffered Stderr "'{' or '}' should be on its own line, but got '") - 8882 (rewind-stream %ecx) - 8883 (write-stream 2 %ecx) - 8884 (write-buffered Stderr "'\n") - 8885 (flush Stderr) - 8886 # . syscall(exit, 1) - 8887 bb/copy-to-ebx 1/imm32 - 8888 e8/call syscall_exit/disp32 - 8889 # never gets here - 8890 $check-no-tokens-left:end: - 8891 # . reclaim locals - 8892 81 0/subop/add %esp 8/imm32 + 8434 $parse-var-with-type:abort: + 8435 # error("var should have form 'name: type' in '" line "'\n") + 8436 (write-buffered *(ebp+0x14) "var should have form 'name: type' in '") + 8437 (flush *(ebp+0x14)) + 8438 (rewind-stream *(ebp+0xc)) + 8439 (write-stream-data *(ebp+0x14) *(ebp+0xc)) + 8440 (write-buffered *(ebp+0x14) "'\n") + 8441 (flush *(ebp+0x14)) + 8442 (stop *(ebp+0x18) 1) + 8443 # never gets here + 8444 + 8445 parse-type: # ad: (addr allocation-descriptor), in: (addr stream byte), out: (addr handle type-tree), err: (addr buffered-file), ed: (addr exit-descriptor) + 8446 # pseudocode: + 8447 # var s: slice = next-mu-token(in) + 8448 # assert s != "" + 8449 # assert s != "->" + 8450 # assert s != "{" + 8451 # assert s != "}" + 8452 # if s == ")" + 8453 # return + 8454 # out = allocate(Type-tree) + 8455 # if s != "(" + 8456 # HACK: if s is an int, parse and return it + 8457 # out->is-atom? = true + 8458 # if (s[0] == "_") + 8459 # out->value = type-parameter + 8460 # out->parameter-name = slice-to-string(ad, s) + 8461 # else + 8462 # out->value = pos-or-insert-slice(Type-id, s) + 8463 # return + 8464 # out->left = parse-type(ad, in) + 8465 # out->right = parse-type-tree(ad, in) + 8466 # + 8467 # . prologue + 8468 55/push-ebp + 8469 89/<- %ebp 4/r32/esp + 8470 # . save registers + 8471 50/push-eax + 8472 51/push-ecx + 8473 52/push-edx + 8474 # clear out + 8475 (zero-out *(ebp+0x10) *Handle-size) + 8476 # var s/ecx: slice + 8477 68/push 0/imm32 + 8478 68/push 0/imm32 + 8479 89/<- %ecx 4/r32/esp + 8480 # s = next-mu-token(in) + 8481 (next-mu-token *(ebp+0xc) %ecx) + 8482 #? (write-buffered Stderr "tok: ") + 8483 #? (write-slice-buffered Stderr %ecx) + 8484 #? (write-buffered Stderr "$\n") + 8485 #? (flush Stderr) + 8486 # assert s != "" + 8487 (slice-equal? %ecx "") # => eax + 8488 3d/compare-eax-and 0/imm32/false + 8489 0f 85/jump-if-!= $parse-type:abort/disp32 + 8490 # assert s != "{" + 8491 (slice-equal? %ecx "{") # => eax + 8492 3d/compare-eax-and 0/imm32/false + 8493 0f 85/jump-if-!= $parse-type:abort/disp32 + 8494 # assert s != "}" + 8495 (slice-equal? %ecx "}") # => eax + 8496 3d/compare-eax-and 0/imm32/false + 8497 0f 85/jump-if-!= $parse-type:abort/disp32 + 8498 # assert s != "->" + 8499 (slice-equal? %ecx "->") # => eax + 8500 3d/compare-eax-and 0/imm32/false + 8501 0f 85/jump-if-!= $parse-type:abort/disp32 + 8502 # if (s == ")") return + 8503 (slice-equal? %ecx ")") # => eax + 8504 3d/compare-eax-and 0/imm32/false + 8505 0f 85/jump-if-!= $parse-type:end/disp32 + 8506 # out = new tree + 8507 (allocate *(ebp+8) *Type-tree-size *(ebp+0x10)) + 8508 # var out-addr/edx: (addr type-tree) = lookup(*out) + 8509 8b/-> *(ebp+0x10) 2/r32/edx + 8510 (lookup *edx *(edx+4)) # => eax + 8511 89/<- %edx 0/r32/eax + 8512 { + 8513 # if (s != "(") break + 8514 (slice-equal? %ecx "(") # => eax + 8515 3d/compare-eax-and 0/imm32/false + 8516 0f 85/jump-if-!= break/disp32 + 8517 # if s is a number, store it in the type's size field + 8518 { + 8519 $parse-type:check-for-int: + 8520 # var tmp/eax: byte = *s->slice + 8521 8b/-> *ecx 0/r32/eax + 8522 8a/copy-byte *eax 0/r32/AL + 8523 81 4/subop/and %eax 0xff/imm32 + 8524 # TODO: raise an error on `var x: (array int a)` + 8525 (is-decimal-digit? %eax) # => eax + 8526 3d/compare-eax-and 0/imm32/false + 8527 74/jump-if-= break/disp8 + 8528 # + 8529 (is-hex-int? %ecx) # => eax + 8530 3d/compare-eax-and 0/imm32/false + 8531 74/jump-if-= break/disp8 + 8532 $parse-type:int: + 8533 (check-mu-hex-int %ecx *(ebp+0x14) *(ebp+0x18)) + 8534 (parse-hex-int-from-slice %ecx) # => eax + 8535 c7 0/subop/copy *(edx+4) 9/imm32/type-id-array-capacity # Type-tree-value + 8536 89/<- *(edx+8) 0/r32/eax # Type-tree-value-size + 8537 e9/jump $parse-type:end/disp32 + 8538 } + 8539 $parse-type:atom: + 8540 # out->is-atom? = true + 8541 c7 0/subop/copy *edx 1/imm32/true # Type-tree-is-atom + 8542 { + 8543 $parse-type:check-for-type-parameter: + 8544 # var tmp/eax: byte = *s->slice + 8545 8b/-> *ecx 0/r32/eax + 8546 8a/copy-byte *eax 0/r32/AL + 8547 81 4/subop/and %eax 0xff/imm32 + 8548 # if (tmp != '_') break + 8549 3d/compare-eax-and 0x5f/imm32/_ + 8550 75/jump-if-!= break/disp8 + 8551 $parse-type:type-parameter: + 8552 # out->value = type-parameter + 8553 c7 0/subop/copy *(edx+4) 0xa/imm32/type-parameter # Type-tree-value + 8554 # out->parameter-name = slice-to-string(ad, s) + 8555 8d/copy-address *(edx+8) 0/r32/eax # Type-tree-parameter-name + 8556 (slice-to-string *(ebp+8) %ecx %eax) + 8557 e9/jump $parse-type:end/disp32 + 8558 } + 8559 $parse-type:non-type-parameter: + 8560 # out->value = pos-or-insert-slice(Type-id, s) + 8561 (pos-or-insert-slice Type-id %ecx) # => eax + 8562 89/<- *(edx+4) 0/r32/eax # Type-tree-value + 8563 e9/jump $parse-type:end/disp32 + 8564 } + 8565 $parse-type:non-atom: + 8566 # otherwise s == "(" + 8567 # out->left = parse-type(ad, in) + 8568 8d/copy-address *(edx+4) 0/r32/eax # Type-tree-left + 8569 (parse-type *(ebp+8) *(ebp+0xc) %eax *(ebp+0x14) *(ebp+0x18)) + 8570 # out->right = parse-type-tree(ad, in) + 8571 8d/copy-address *(edx+0xc) 0/r32/eax # Type-tree-right + 8572 (parse-type-tree *(ebp+8) *(ebp+0xc) %eax *(ebp+0x14) *(ebp+0x18)) + 8573 $parse-type:end: + 8574 # . reclaim locals + 8575 81 0/subop/add %esp 8/imm32 + 8576 # . restore registers + 8577 5a/pop-to-edx + 8578 59/pop-to-ecx + 8579 58/pop-to-eax + 8580 # . epilogue + 8581 89/<- %esp 5/r32/ebp + 8582 5d/pop-to-ebp + 8583 c3/return + 8584 + 8585 $parse-type:abort: + 8586 # error("unexpected token when parsing type: '" s "'\n") + 8587 (write-buffered *(ebp+0x14) "unexpected token when parsing type: '") + 8588 (write-slice-buffered *(ebp+0x14) %ecx) + 8589 (write-buffered *(ebp+0x14) "'\n") + 8590 (flush *(ebp+0x14)) + 8591 (stop *(ebp+0x18) 1) + 8592 # never gets here + 8593 + 8594 parse-type-tree: # ad: (addr allocation-descriptor), in: (addr stream byte), out: (addr handle type-tree), err: (addr buffered-file), ed: (addr exit-descriptor) + 8595 # pseudocode: + 8596 # var tmp: (handle type-tree) = parse-type(ad, in) + 8597 # if tmp == 0 + 8598 # return 0 + 8599 # out = allocate(Type-tree) + 8600 # out->left = tmp + 8601 # out->right = parse-type-tree(ad, in) + 8602 # + 8603 # . prologue + 8604 55/push-ebp + 8605 89/<- %ebp 4/r32/esp + 8606 # . save registers + 8607 50/push-eax + 8608 51/push-ecx + 8609 52/push-edx + 8610 # + 8611 (zero-out *(ebp+0x10) *Handle-size) + 8612 # var tmp/ecx: (handle type-tree) + 8613 68/push 0/imm32 + 8614 68/push 0/imm32 + 8615 89/<- %ecx 4/r32/esp + 8616 # tmp = parse-type(ad, in) + 8617 (parse-type *(ebp+8) *(ebp+0xc) %ecx *(ebp+0x14) *(ebp+0x18)) + 8618 # if (tmp == 0) return + 8619 81 7/subop/compare *ecx 0/imm32 + 8620 74/jump-if-= $parse-type-tree:end/disp8 + 8621 # out = new tree + 8622 (allocate *(ebp+8) *Type-tree-size *(ebp+0x10)) + 8623 # var out-addr/edx: (addr tree) = lookup(*out) + 8624 8b/-> *(ebp+0x10) 2/r32/edx + 8625 (lookup *edx *(edx+4)) # => eax + 8626 89/<- %edx 0/r32/eax + 8627 # out->left = tmp + 8628 8b/-> *ecx 0/r32/eax + 8629 89/<- *(edx+4) 0/r32/eax # Type-tree-left + 8630 8b/-> *(ecx+4) 0/r32/eax + 8631 89/<- *(edx+8) 0/r32/eax # Type-tree-left + 8632 # out->right = parse-type-tree(ad, in) + 8633 8d/copy-address *(edx+0xc) 0/r32/eax # Type-tree-right + 8634 (parse-type-tree *(ebp+8) *(ebp+0xc) %eax *(ebp+0x14) *(ebp+0x18)) + 8635 $parse-type-tree:end: + 8636 # . reclaim locals + 8637 81 0/subop/add %esp 8/imm32 + 8638 # . restore registers + 8639 5a/pop-to-edx + 8640 59/pop-to-ecx + 8641 58/pop-to-eax + 8642 # . epilogue + 8643 89/<- %esp 5/r32/ebp + 8644 5d/pop-to-ebp + 8645 c3/return + 8646 + 8647 next-mu-token: # in: (addr stream byte), out: (addr slice) + 8648 # pseudocode: + 8649 # start: + 8650 # skip-chars-matching-whitespace(in) + 8651 # if in->read >= in->write # end of in + 8652 # out = {0, 0} + 8653 # return + 8654 # out->start = &in->data[in->read] + 8655 # var curr-byte/eax: byte = in->data[in->read] + 8656 # if curr->byte == ',' # comment token + 8657 # ++in->read + 8658 # goto start + 8659 # if curr-byte == '#' # comment + 8660 # goto done # treat as eof + 8661 # if curr-byte == '"' # string literal + 8662 # skip-string(in) + 8663 # goto done # no metadata + 8664 # if curr-byte == '(' + 8665 # ++in->read + 8666 # goto done + 8667 # if curr-byte == ')' + 8668 # ++in->read + 8669 # goto done + 8670 # # read a word + 8671 # while true + 8672 # if in->read >= in->write + 8673 # break + 8674 # curr-byte = in->data[in->read] + 8675 # if curr-byte == ' ' + 8676 # break + 8677 # if curr-byte == '\r' + 8678 # break + 8679 # if curr-byte == '\n' + 8680 # break + 8681 # if curr-byte == '(' + 8682 # break + 8683 # if curr-byte == ')' + 8684 # break + 8685 # if curr-byte == ',' + 8686 # break + 8687 # ++in->read + 8688 # done: + 8689 # out->end = &in->data[in->read] + 8690 # + 8691 # . prologue + 8692 55/push-ebp + 8693 89/<- %ebp 4/r32/esp + 8694 # . save registers + 8695 50/push-eax + 8696 51/push-ecx + 8697 56/push-esi + 8698 57/push-edi + 8699 # esi = in + 8700 8b/-> *(ebp+8) 6/r32/esi + 8701 # edi = out + 8702 8b/-> *(ebp+0xc) 7/r32/edi + 8703 $next-mu-token:start: + 8704 (skip-chars-matching-whitespace %esi) + 8705 $next-mu-token:check0: + 8706 # if (in->read >= in->write) return out = {0, 0} + 8707 # . ecx = in->read + 8708 8b/-> *(esi+4) 1/r32/ecx + 8709 # . if (ecx >= in->write) return out = {0, 0} + 8710 3b/compare<- *esi 1/r32/ecx + 8711 c7 0/subop/copy *edi 0/imm32 + 8712 c7 0/subop/copy *(edi+4) 0/imm32 + 8713 0f 8d/jump-if->= $next-mu-token:end/disp32 + 8714 # out->start = &in->data[in->read] + 8715 8d/copy-address *(esi+ecx+0xc) 0/r32/eax + 8716 89/<- *edi 0/r32/eax + 8717 # var curr-byte/eax: byte = in->data[in->read] + 8718 31/xor-with %eax 0/r32/eax + 8719 8a/copy-byte *(esi+ecx+0xc) 0/r32/AL + 8720 { + 8721 $next-mu-token:check-for-comma: + 8722 # if (curr-byte != ',') break + 8723 3d/compare-eax-and 0x2c/imm32/comma + 8724 75/jump-if-!= break/disp8 + 8725 # ++in->read + 8726 ff 0/subop/increment *(esi+4) + 8727 # restart + 8728 e9/jump $next-mu-token:start/disp32 + 8729 } + 8730 { + 8731 $next-mu-token:check-for-comment: + 8732 # if (curr-byte != '#') break + 8733 3d/compare-eax-and 0x23/imm32/pound + 8734 75/jump-if-!= break/disp8 + 8735 # return eof + 8736 e9/jump $next-mu-token:done/disp32 + 8737 } + 8738 { + 8739 $next-mu-token:check-for-string-literal: + 8740 # if (curr-byte != '"') break + 8741 3d/compare-eax-and 0x22/imm32/dquote + 8742 75/jump-if-!= break/disp8 + 8743 (skip-string %esi) + 8744 # return + 8745 e9/jump $next-mu-token:done/disp32 + 8746 } + 8747 { + 8748 $next-mu-token:check-for-open-paren: + 8749 # if (curr-byte != '(') break + 8750 3d/compare-eax-and 0x28/imm32/open-paren + 8751 75/jump-if-!= break/disp8 + 8752 # ++in->read + 8753 ff 0/subop/increment *(esi+4) + 8754 # return + 8755 e9/jump $next-mu-token:done/disp32 + 8756 } + 8757 { + 8758 $next-mu-token:check-for-close-paren: + 8759 # if (curr-byte != ')') break + 8760 3d/compare-eax-and 0x29/imm32/close-paren + 8761 75/jump-if-!= break/disp8 + 8762 # ++in->read + 8763 ff 0/subop/increment *(esi+4) + 8764 # return + 8765 e9/jump $next-mu-token:done/disp32 + 8766 } + 8767 { + 8768 $next-mu-token:regular-word-without-metadata: + 8769 # if (in->read >= in->write) break + 8770 # . ecx = in->read + 8771 8b/-> *(esi+4) 1/r32/ecx + 8772 # . if (ecx >= in->write) break + 8773 3b/compare<- *esi 1/r32/ecx + 8774 7d/jump-if->= break/disp8 + 8775 # var c/eax: byte = in->data[in->read] + 8776 31/xor-with %eax 0/r32/eax + 8777 8a/copy-byte *(esi+ecx+0xc) 0/r32/AL + 8778 # if (c == ' ') break + 8779 3d/compare-eax-and 0x20/imm32/space + 8780 74/jump-if-= break/disp8 + 8781 # if (c == '\r') break + 8782 3d/compare-eax-and 0xd/imm32/carriage-return + 8783 74/jump-if-= break/disp8 + 8784 # if (c == '\n') break + 8785 3d/compare-eax-and 0xa/imm32/newline + 8786 74/jump-if-= break/disp8 + 8787 # if (c == '(') break + 8788 3d/compare-eax-and 0x28/imm32/open-paren + 8789 0f 84/jump-if-= break/disp32 + 8790 # if (c == ')') break + 8791 3d/compare-eax-and 0x29/imm32/close-paren + 8792 0f 84/jump-if-= break/disp32 + 8793 # if (c == ',') break + 8794 3d/compare-eax-and 0x2c/imm32/comma + 8795 0f 84/jump-if-= break/disp32 + 8796 # ++in->read + 8797 ff 0/subop/increment *(esi+4) + 8798 # + 8799 e9/jump loop/disp32 + 8800 } + 8801 $next-mu-token:done: + 8802 # out->end = &in->data[in->read] + 8803 8b/-> *(esi+4) 1/r32/ecx + 8804 8d/copy-address *(esi+ecx+0xc) 0/r32/eax + 8805 89/<- *(edi+4) 0/r32/eax + 8806 $next-mu-token:end: + 8807 # . restore registers + 8808 5f/pop-to-edi + 8809 5e/pop-to-esi + 8810 59/pop-to-ecx + 8811 58/pop-to-eax + 8812 # . epilogue + 8813 89/<- %esp 5/r32/ebp + 8814 5d/pop-to-ebp + 8815 c3/return + 8816 + 8817 pos-or-insert-slice: # arr: (addr stream (addr array byte)), s: (addr slice) -> index/eax: int + 8818 # . prologue + 8819 55/push-ebp + 8820 89/<- %ebp 4/r32/esp + 8821 # if (pos-slice(arr, s) != -1) return it + 8822 (pos-slice *(ebp+8) *(ebp+0xc)) # => eax + 8823 3d/compare-eax-and -1/imm32 + 8824 75/jump-if-!= $pos-or-insert-slice:end/disp8 + 8825 $pos-or-insert-slice:insert: + 8826 # var s2/eax: (handle array byte) + 8827 68/push 0/imm32 + 8828 68/push 0/imm32 + 8829 89/<- %eax 4/r32/esp + 8830 (slice-to-string Heap *(ebp+0xc) %eax) + 8831 # throw away alloc-id + 8832 (lookup *eax *(eax+4)) # => eax + 8833 (write-int *(ebp+8) %eax) + 8834 (pos-slice *(ebp+8) *(ebp+0xc)) # => eax + 8835 $pos-or-insert-slice:end: + 8836 # . reclaim locals + 8837 81 0/subop/add %esp 8/imm32 + 8838 # . epilogue + 8839 89/<- %esp 5/r32/ebp + 8840 5d/pop-to-ebp + 8841 c3/return + 8842 + 8843 # return the index in an array of strings matching 's', -1 if not found + 8844 # index is denominated in elements, not bytes + 8845 pos-slice: # arr: (addr stream (addr array byte)), s: (addr slice) -> index/eax: int + 8846 # . prologue + 8847 55/push-ebp + 8848 89/<- %ebp 4/r32/esp + 8849 # . save registers + 8850 51/push-ecx + 8851 52/push-edx + 8852 53/push-ebx + 8853 56/push-esi + 8854 #? (write-buffered Stderr "pos-slice: ") + 8855 #? (write-slice-buffered Stderr *(ebp+0xc)) + 8856 #? (write-buffered Stderr "\n") + 8857 #? (flush Stderr) + 8858 # esi = arr + 8859 8b/-> *(ebp+8) 6/r32/esi + 8860 # var index/ecx: int = 0 + 8861 b9/copy-to-ecx 0/imm32 + 8862 # var curr/edx: (addr (addr array byte)) = arr->data + 8863 8d/copy-address *(esi+0xc) 2/r32/edx + 8864 # var max/ebx: (addr (addr array byte)) = &arr->data[arr->write] + 8865 8b/-> *esi 3/r32/ebx + 8866 8d/copy-address *(esi+ebx+0xc) 3/r32/ebx + 8867 { + 8868 #? (write-buffered Stderr " ") + 8869 #? (write-int32-hex-buffered Stderr %ecx) + 8870 #? (write-buffered Stderr "\n") + 8871 #? (flush Stderr) + 8872 # if (curr >= max) return -1 + 8873 39/compare %edx 3/r32/ebx + 8874 b8/copy-to-eax -1/imm32 + 8875 73/jump-if-addr>= $pos-slice:end/disp8 + 8876 # if (slice-equal?(s, *curr)) break + 8877 (slice-equal? *(ebp+0xc) *edx) # => eax + 8878 3d/compare-eax-and 0/imm32/false + 8879 75/jump-if-!= break/disp8 + 8880 # ++index + 8881 41/increment-ecx + 8882 # curr += 4 + 8883 81 0/subop/add %edx 4/imm32 + 8884 # + 8885 eb/jump loop/disp8 + 8886 } + 8887 # return index + 8888 89/<- %eax 1/r32/ecx + 8889 $pos-slice:end: + 8890 #? (write-buffered Stderr "=> ") + 8891 #? (write-int32-hex-buffered Stderr %eax) + 8892 #? (write-buffered Stderr "\n") 8893 # . restore registers - 8894 59/pop-to-ecx - 8895 58/pop-to-eax - 8896 # . epilogue - 8897 89/<- %esp 5/r32/ebp - 8898 5d/pop-to-ebp - 8899 c3/return - 8900 - 8901 parse-mu-named-block: # name: (addr slice), in: (addr buffered-file), vars: (addr stack live-var), fn: (addr function), out: (addr handle stmt), err: (addr buffered-file), ed: (addr exit-descriptor) - 8902 # pseudocode: - 8903 # var v: (handle var) - 8904 # new-literal(name, v) - 8905 # push(vars, {v, false}) - 8906 # parse-mu-block(in, vars, fn, out) - 8907 # pop(vars) - 8908 # out->tag = block - 8909 # out->var = v - 8910 # - 8911 # . prologue - 8912 55/push-ebp - 8913 89/<- %ebp 4/r32/esp - 8914 # . save registers - 8915 50/push-eax - 8916 51/push-ecx - 8917 57/push-edi - 8918 # var v/ecx: (handle var) - 8919 68/push 0/imm32 + 8894 5e/pop-to-esi + 8895 5b/pop-to-ebx + 8896 5a/pop-to-edx + 8897 59/pop-to-ecx + 8898 # . epilogue + 8899 89/<- %esp 5/r32/ebp + 8900 5d/pop-to-ebp + 8901 c3/return + 8902 + 8903 test-parse-var-with-type: + 8904 # . prologue + 8905 55/push-ebp + 8906 89/<- %ebp 4/r32/esp + 8907 # (eax..ecx) = "x:" + 8908 b8/copy-to-eax "x:"/imm32 + 8909 8b/-> *eax 1/r32/ecx + 8910 8d/copy-address *(eax+ecx+4) 1/r32/ecx + 8911 05/add-to-eax 4/imm32 + 8912 # var slice/ecx: slice = {eax, ecx} + 8913 51/push-ecx + 8914 50/push-eax + 8915 89/<- %ecx 4/r32/esp + 8916 # _test-input-stream contains "int" + 8917 (clear-stream _test-input-stream) + 8918 (write _test-input-stream "int") + 8919 # var v/edx: (handle var) 8920 68/push 0/imm32 - 8921 89/<- %ecx 4/r32/esp - 8922 # - 8923 (new-literal Heap *(ebp+8) %ecx) - 8924 # push(vars, v) - 8925 (push *(ebp+0x10) *ecx) - 8926 (push *(ebp+0x10) *(ecx+4)) - 8927 (push *(ebp+0x10) 0) # false - 8928 # - 8929 (parse-mu-block *(ebp+0xc) *(ebp+0x10) *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c) *(ebp+0x20)) - 8930 # pop v off vars - 8931 (pop *(ebp+0x10)) # => eax - 8932 (pop *(ebp+0x10)) # => eax - 8933 (pop *(ebp+0x10)) # => eax - 8934 # var out-addr/edi: (addr stmt) = lookup(*out) - 8935 8b/-> *(ebp+0x18) 7/r32/edi - 8936 (lookup *edi *(edi+4)) # => eax - 8937 89/<- %edi 0/r32/eax - 8938 # out-addr->tag = named-block - 8939 c7 0/subop/copy *edi 0/imm32/block # Stmt-tag - 8940 # out-addr->var = v - 8941 8b/-> *ecx 0/r32/eax - 8942 89/<- *(edi+0xc) 0/r32/eax # Block-var - 8943 8b/-> *(ecx+4) 0/r32/eax - 8944 89/<- *(edi+0x10) 0/r32/eax # Block-var - 8945 $parse-mu-named-block:end: - 8946 # . reclaim locals - 8947 81 0/subop/add %esp 8/imm32 - 8948 # . restore registers - 8949 5f/pop-to-edi - 8950 59/pop-to-ecx - 8951 58/pop-to-eax - 8952 # . epilogue - 8953 89/<- %esp 5/r32/ebp - 8954 5d/pop-to-ebp - 8955 c3/return - 8956 - 8957 parse-mu-var-def: # line: (addr stream byte), vars: (addr stack live-var), out: (addr handle stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) - 8958 # . prologue - 8959 55/push-ebp - 8960 89/<- %ebp 4/r32/esp - 8961 # . save registers - 8962 50/push-eax - 8963 51/push-ecx - 8964 52/push-edx - 8965 53/push-ebx - 8966 57/push-edi - 8967 # edi = out - 8968 8b/-> *(ebp+0x10) 7/r32/edi - 8969 # var word-slice/ecx: slice - 8970 68/push 0/imm32/end - 8971 68/push 0/imm32/start - 8972 89/<- %ecx 4/r32/esp - 8973 # var v/edx: (handle var) - 8974 68/push 0/imm32 - 8975 68/push 0/imm32 - 8976 89/<- %edx 4/r32/esp - 8977 # v = parse-var-with-type(next-mu-token(line)) - 8978 (next-mu-token *(ebp+8) %ecx) - 8979 (parse-var-with-type %ecx *(ebp+8) %edx *(ebp+0x18) *(ebp+0x1c)) - 8980 # var v-addr/eax: (addr var) - 8981 (lookup *edx *(edx+4)) # => eax - 8982 # v->block-depth = *Curr-block-depth - 8983 8b/-> *Curr-block-depth 3/r32/ebx - 8984 89/<- *(eax+0x10) 3/r32/ebx # Var-block-depth - 8985 # either v has no register and there's no more to this line - 8986 8b/-> *(eax+0x18) 0/r32/eax # Var-register - 8987 3d/compare-eax-and 0/imm32 - 8988 { - 8989 75/jump-if-!= break/disp8 - 8990 # TODO: disallow vars of type 'byte' on the stack - 8991 # ensure that there's nothing else on this line - 8992 (next-mu-token *(ebp+8) %ecx) - 8993 (slice-empty? %ecx) # => eax - 8994 3d/compare-eax-and 0/imm32/false - 8995 0f 84/jump-if-= $parse-mu-var-def:error2/disp32 - 8996 # - 8997 (new-var-def Heap *edx *(edx+4) %edi) - 8998 e9/jump $parse-mu-var-def:update-vars/disp32 - 8999 } - 9000 # or v has a register and there's more to this line - 9001 { - 9002 0f 84/jump-if-= break/disp32 - 9003 # TODO: disallow vars of type 'byte' in registers 'esi' or 'edi' - 9004 # TODO: vars of type 'byte' should only be initialized by clearing to 0 - 9005 # ensure that the next word is '<-' - 9006 (next-mu-token *(ebp+8) %ecx) - 9007 (slice-equal? %ecx "<-") # => eax - 9008 3d/compare-eax-and 0/imm32/false - 9009 0f 84/jump-if-= $parse-mu-var-def:error1/disp32 - 9010 # - 9011 (new-reg-var-def Heap *edx *(edx+4) %edi) - 9012 (lookup *edi *(edi+4)) # => eax - 9013 (add-operation-and-inputs-to-stmt %eax *(ebp+8) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c)) - 9014 } - 9015 $parse-mu-var-def:update-vars: - 9016 # push 'v' at end of function - 9017 (push *(ebp+0xc) *edx) - 9018 (push *(ebp+0xc) *(edx+4)) - 9019 (push *(ebp+0xc) 0) # Live-var-register-spilled is unused during parsing - 9020 $parse-mu-var-def:end: - 9021 # . reclaim locals - 9022 81 0/subop/add %esp 0x10/imm32 - 9023 # . restore registers - 9024 5f/pop-to-edi - 9025 5b/pop-to-ebx - 9026 5a/pop-to-edx - 9027 59/pop-to-ecx - 9028 58/pop-to-eax - 9029 # . epilogue - 9030 89/<- %esp 5/r32/ebp - 9031 5d/pop-to-ebp - 9032 c3/return - 9033 - 9034 $parse-mu-var-def:error1: - 9035 (rewind-stream *(ebp+8)) - 9036 # error("register variable requires a valid instruction to initialize but got '" line "'\n") - 9037 (write-buffered *(ebp+0x18) "register variable requires a valid instruction to initialize but got '") - 9038 (flush *(ebp+0x18)) - 9039 (write-stream-data *(ebp+0x18) *(ebp+8)) - 9040 (write-buffered *(ebp+0x18) "'\n") - 9041 (flush *(ebp+0x18)) - 9042 (stop *(ebp+0x1c) 1) - 9043 # never gets here - 9044 - 9045 $parse-mu-var-def:error2: - 9046 (rewind-stream *(ebp+8)) - 9047 # error("fn " fn ": var " var ": variables on the stack can't take an initializer\n") - 9048 (write-buffered *(ebp+0x18) "fn ") - 9049 8b/-> *(ebp+0x14) 0/r32/eax - 9050 (lookup *eax *(eax+4)) # Function-name Function-name => eax - 9051 (write-buffered *(ebp+0x18) %eax) - 9052 (write-buffered *(ebp+0x18) ": var ") - 9053 # var v-addr/eax: (addr var) = lookup(v) - 9054 (lookup *edx *(edx+4)) # => eax - 9055 (lookup *eax *(eax+4)) # Var-name Var-name => eax - 9056 (write-buffered *(ebp+0x18) %eax) - 9057 (write-buffered *(ebp+0x18) ": variables on the stack can't take an initializer\n") - 9058 (flush *(ebp+0x18)) - 9059 (stop *(ebp+0x1c) 1) - 9060 # never gets here - 9061 - 9062 test-parse-mu-var-def: - 9063 # 'var n: int' + 8921 68/push 0/imm32 + 8922 89/<- %edx 4/r32/esp + 8923 # + 8924 (parse-var-with-type %ecx _test-input-stream %edx Stderr 0) + 8925 # var v-addr/edx: (addr var) = lookup(v) + 8926 (lookup *edx *(edx+4)) # => eax + 8927 89/<- %edx 0/r32/eax + 8928 # check v-addr->name + 8929 (lookup *edx *(edx+4)) # Var-name Var-name => eax + 8930 (check-strings-equal %eax "x" "F - test-parse-var-with-type/name") + 8931 # check v-addr->type + 8932 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax + 8933 (check-ints-equal *eax 1 "F - test-parse-var-with-type/type:0") # Type-tree-is-atom + 8934 (check-ints-equal *(eax+4) 1 "F - test-parse-var-with-type/type:1") # Type-tree-value + 8935 (check-ints-equal *(eax+0xc) 0 "F - test-parse-var-with-type/type:2") # Type-tree-right + 8936 # . epilogue + 8937 89/<- %esp 5/r32/ebp + 8938 5d/pop-to-ebp + 8939 c3/return + 8940 + 8941 test-parse-var-with-type-and-register: + 8942 # . prologue + 8943 55/push-ebp + 8944 89/<- %ebp 4/r32/esp + 8945 # (eax..ecx) = "x/eax:" + 8946 b8/copy-to-eax "x/eax:"/imm32 + 8947 8b/-> *eax 1/r32/ecx + 8948 8d/copy-address *(eax+ecx+4) 1/r32/ecx + 8949 05/add-to-eax 4/imm32 + 8950 # var slice/ecx: slice = {eax, ecx} + 8951 51/push-ecx + 8952 50/push-eax + 8953 89/<- %ecx 4/r32/esp + 8954 # _test-input-stream contains "int" + 8955 (clear-stream _test-input-stream) + 8956 (write _test-input-stream "int") + 8957 # var v/edx: (handle var) + 8958 68/push 0/imm32 + 8959 68/push 0/imm32 + 8960 89/<- %edx 4/r32/esp + 8961 # + 8962 (parse-var-with-type %ecx _test-input-stream %edx Stderr 0) + 8963 # var v-addr/edx: (addr var) = lookup(v) + 8964 (lookup *edx *(edx+4)) # => eax + 8965 89/<- %edx 0/r32/eax + 8966 # check v-addr->name + 8967 (lookup *edx *(edx+4)) # Var-name Var-name => eax + 8968 (check-strings-equal %eax "x" "F - test-parse-var-with-type-and-register/name") + 8969 # check v-addr->register + 8970 (lookup *(edx+0x18) *(edx+0x1c)) # Var-register Var-register => eax + 8971 (check-strings-equal %eax "eax" "F - test-parse-var-with-type-and-register/register") + 8972 # check v-addr->type + 8973 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax + 8974 (check-ints-equal *eax 1 "F - test-parse-var-with-type-and-register/type:0") # Type-tree-is-atom + 8975 (check-ints-equal *(eax+4) 1 "F - test-parse-var-with-type-and-register/type:1") # Type-tree-left + 8976 (check-ints-equal *(eax+0xc) 0 "F - test-parse-var-with-type-and-register/type:2") # Type-tree-right + 8977 # . epilogue + 8978 89/<- %esp 5/r32/ebp + 8979 5d/pop-to-ebp + 8980 c3/return + 8981 + 8982 test-parse-var-with-trailing-characters: + 8983 # . prologue + 8984 55/push-ebp + 8985 89/<- %ebp 4/r32/esp + 8986 # (eax..ecx) = "x:" + 8987 b8/copy-to-eax "x:"/imm32 + 8988 8b/-> *eax 1/r32/ecx + 8989 8d/copy-address *(eax+ecx+4) 1/r32/ecx + 8990 05/add-to-eax 4/imm32 + 8991 # var slice/ecx: slice = {eax, ecx} + 8992 51/push-ecx + 8993 50/push-eax + 8994 89/<- %ecx 4/r32/esp + 8995 # _test-input-stream contains "int," + 8996 (clear-stream _test-input-stream) + 8997 (write _test-input-stream "int,") + 8998 # var v/edx: (handle var) + 8999 68/push 0/imm32 + 9000 68/push 0/imm32 + 9001 89/<- %edx 4/r32/esp + 9002 # + 9003 (parse-var-with-type %ecx _test-input-stream %edx Stderr 0) + 9004 # var v-addr/edx: (addr var) = lookup(v) + 9005 (lookup *edx *(edx+4)) # => eax + 9006 89/<- %edx 0/r32/eax + 9007 # check v-addr->name + 9008 (lookup *edx *(edx+4)) # Var-name Var-name => eax + 9009 (check-strings-equal %eax "x" "F - test-parse-var-with-trailing-characters/name") + 9010 # check v-addr->register + 9011 (check-ints-equal *(edx+0x18) 0 "F - test-parse-var-with-trailing-characters/register") # Var-register + 9012 # check v-addr->type + 9013 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax + 9014 (check-ints-equal *eax 1 "F - test-parse-var-with-trailing-characters/type:0") # Type-tree-is-atom + 9015 (check-ints-equal *(eax+4) 1 "F - test-parse-var-with-trailing-characters/type:1") # Type-tree-left + 9016 (check-ints-equal *(eax+0xc) 0 "F - test-parse-var-with-trailing-characters/type:1") # Type-tree-right + 9017 # . epilogue + 9018 89/<- %esp 5/r32/ebp + 9019 5d/pop-to-ebp + 9020 c3/return + 9021 + 9022 test-parse-var-with-register-and-trailing-characters: + 9023 # . prologue + 9024 55/push-ebp + 9025 89/<- %ebp 4/r32/esp + 9026 # (eax..ecx) = "x/eax:" + 9027 b8/copy-to-eax "x/eax:"/imm32 + 9028 8b/-> *eax 1/r32/ecx + 9029 8d/copy-address *(eax+ecx+4) 1/r32/ecx + 9030 05/add-to-eax 4/imm32 + 9031 # var slice/ecx: slice = {eax, ecx} + 9032 51/push-ecx + 9033 50/push-eax + 9034 89/<- %ecx 4/r32/esp + 9035 # _test-input-stream contains "int," + 9036 (clear-stream _test-input-stream) + 9037 (write _test-input-stream "int,") + 9038 # var v/edx: (handle var) + 9039 68/push 0/imm32 + 9040 68/push 0/imm32 + 9041 89/<- %edx 4/r32/esp + 9042 # + 9043 (parse-var-with-type %ecx _test-input-stream %edx Stderr 0) + 9044 # var v-addr/edx: (addr var) = lookup(v) + 9045 (lookup *edx *(edx+4)) # => eax + 9046 89/<- %edx 0/r32/eax + 9047 # check v-addr->name + 9048 (lookup *edx *(edx+4)) # Var-name Var-name => eax + 9049 (check-strings-equal %eax "x" "F - test-parse-var-with-register-and-trailing-characters/name") + 9050 # check v-addr->register + 9051 (lookup *(edx+0x18) *(edx+0x1c)) # Var-register Var-register => eax + 9052 (check-strings-equal %eax "eax" "F - test-parse-var-with-register-and-trailing-characters/register") + 9053 # check v-addr->type + 9054 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax + 9055 (check-ints-equal *eax 1 "F - test-parse-var-with-register-and-trailing-characters/type:0") # Type-tree-is-atom + 9056 (check-ints-equal *(eax+4) 1 "F - test-parse-var-with-register-and-trailing-characters/type:1") # Type-tree-left + 9057 (check-ints-equal *(eax+0xc) 0 "F - test-parse-var-with-register-and-trailing-characters/type:2") # Type-tree-right + 9058 # . epilogue + 9059 89/<- %esp 5/r32/ebp + 9060 5d/pop-to-ebp + 9061 c3/return + 9062 + 9063 test-parse-var-with-compound-type: 9064 # . prologue 9065 55/push-ebp 9066 89/<- %ebp 4/r32/esp - 9067 # setup - 9068 (clear-stream _test-input-stream) - 9069 (write _test-input-stream "n: int\n") # caller has consumed the 'var' - 9070 c7 0/subop/copy *Curr-block-depth 1/imm32 - 9071 # var out/esi: (handle stmt) - 9072 68/push 0/imm32 - 9073 68/push 0/imm32 - 9074 89/<- %esi 4/r32/esp - 9075 # var vars/ecx: (stack (addr var) 16) - 9076 81 5/subop/subtract %esp 0xc0/imm32 - 9077 68/push 0xc0/imm32/size - 9078 68/push 0/imm32/top - 9079 89/<- %ecx 4/r32/esp - 9080 (clear-stack %ecx) - 9081 # convert - 9082 (parse-mu-var-def _test-input-stream %ecx %esi 0 Stderr 0) - 9083 # var out-addr/esi: (addr stmt) - 9084 (lookup *esi *(esi+4)) # => eax - 9085 89/<- %esi 0/r32/eax - 9086 # - 9087 (check-ints-equal *esi 2 "F - test-parse-mu-var-def/tag") # Stmt-tag is var-def - 9088 # var v/ecx: (addr var) = lookup(out->var) - 9089 (lookup *(esi+4) *(esi+8)) # Vardef-var Vardef-var => eax - 9090 89/<- %ecx 0/r32/eax - 9091 # v->name - 9092 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax - 9093 (check-strings-equal %eax "n" "F - test-parse-mu-var-def/var-name") - 9094 # v->register - 9095 (check-ints-equal *(ecx+0x18) 0 "F - test-parse-mu-var-def/var-register") # Var-register - 9096 # v->block-depth - 9097 (check-ints-equal *(ecx+0x10) 1 "F - test-parse-mu-var-def/output-block-depth") # Var-block-depth - 9098 # v->type == int - 9099 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax - 9100 (check-ints-equal *eax 1 "F - test-parse-mu-var-def/var-type:0") # Type-tree-is-atom - 9101 (check-ints-equal *(eax+4) 1 "F - test-parse-mu-var-def/var-type:1") # Type-tree-value - 9102 (check-ints-equal *(eax+0xc) 0 "F - test-parse-mu-var-def/var-type:2") # Type-tree-right - 9103 # . epilogue - 9104 89/<- %esp 5/r32/ebp - 9105 5d/pop-to-ebp - 9106 c3/return - 9107 - 9108 test-parse-mu-reg-var-def: - 9109 # 'var n/eax: int <- copy 0' - 9110 # . prologue - 9111 55/push-ebp - 9112 89/<- %ebp 4/r32/esp - 9113 # setup - 9114 (clear-stream _test-input-stream) - 9115 (write _test-input-stream "n/eax: int <- copy 0\n") # caller has consumed the 'var' - 9116 c7 0/subop/copy *Curr-block-depth 1/imm32 - 9117 # var out/esi: (handle stmt) - 9118 68/push 0/imm32 - 9119 68/push 0/imm32 - 9120 89/<- %esi 4/r32/esp - 9121 # var vars/ecx: (stack (addr var) 16) - 9122 81 5/subop/subtract %esp 0xc0/imm32 - 9123 68/push 0xc0/imm32/size - 9124 68/push 0/imm32/top - 9125 89/<- %ecx 4/r32/esp - 9126 (clear-stack %ecx) - 9127 # convert - 9128 (parse-mu-var-def _test-input-stream %ecx %esi 0 Stderr 0) - 9129 # var out-addr/esi: (addr stmt) - 9130 (lookup *esi *(esi+4)) # => eax - 9131 89/<- %esi 0/r32/eax - 9132 # - 9133 (check-ints-equal *esi 3 "F - test-parse-mu-reg-var-def/tag") # Stmt-tag is reg-var-def - 9134 # var v/ecx: (addr var) = lookup(out->outputs->value) - 9135 # . eax: (addr stmt-var) = lookup(out->outputs) - 9136 (lookup *(esi+0x14) *(esi+0x18)) # Regvardef-outputs Regvardef-outputs => eax - 9137 # . - 9138 (check-ints-equal *(eax+8) 0 "F - test-parse-mu-reg-var-def/single-output") # Stmt-var-next - 9139 # . eax: (addr var) = lookup(eax->value) - 9140 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax - 9141 # . ecx = eax - 9142 89/<- %ecx 0/r32/eax - 9143 # v->name - 9144 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax - 9145 (check-strings-equal %eax "n" "F - test-parse-mu-reg-var-def/output-name") # Var-name - 9146 # v->register - 9147 (lookup *(ecx+0x18) *(ecx+0x1c)) # Var-register Var-register => eax - 9148 (check-strings-equal %eax "eax" "F - test-parse-mu-reg-var-def/output-register") - 9149 # v->block-depth - 9150 (check-ints-equal *(ecx+0x10) 1 "F - test-parse-mu-reg-var-def/output-block-depth") # Var-block-depth - 9151 # v->type == int - 9152 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax - 9153 (check-ints-equal *eax 1 "F - test-parse-mu-reg-var-def/output-type:0") # Type-tree-is-atom - 9154 (check-ints-equal *(eax+4) 1 "F - test-parse-mu-reg-var-def/output-type:1") # Type-tree-value - 9155 (check-ints-equal *(eax+0xc) 0 "F - test-parse-mu-reg-var-def/output-type:2") # Type-tree-right - 9156 # . epilogue - 9157 89/<- %esp 5/r32/ebp - 9158 5d/pop-to-ebp - 9159 c3/return - 9160 - 9161 parse-mu-stmt: # line: (addr stream byte), vars: (addr stack live-var), fn: (addr function), out: (addr handle stmt), err: (addr buffered-file), ed: (addr exit-descriptor) - 9162 # Carefully push any outputs on the vars stack _after_ reading the inputs - 9163 # that may conflict with them. - 9164 # - 9165 # The only situation in which outputs are pushed here (when it's not a - 9166 # 'var' vardef stmt), and so can possibly conflict with inputs, is if the - 9167 # output is a function output. - 9168 # - 9169 # pseudocode: - 9170 # var name: slice - 9171 # allocate(Heap, Stmt-size, out) - 9172 # var out-addr: (addr stmt) = lookup(*out) - 9173 # out-addr->tag = stmt - 9174 # if stmt-has-outputs?(line) - 9175 # while true - 9176 # name = next-mu-token(line) - 9177 # if (name == '<-') break - 9178 # assert(is-identifier?(name)) - 9179 # var v: (handle var) = lookup-var-or-find-in-fn-outputs(name, vars, fn) - 9180 # out-addr->outputs = append(v, out-addr->outputs) - 9181 # add-operation-and-inputs-to-stmt(out-addr, line, vars) - 9182 # for output in stmt->outputs: - 9183 # maybe-define-var(output, vars) - 9184 # - 9185 # . prologue - 9186 55/push-ebp - 9187 89/<- %ebp 4/r32/esp - 9188 # . save registers + 9067 # (eax..ecx) = "x:" + 9068 b8/copy-to-eax "x:"/imm32 + 9069 8b/-> *eax 1/r32/ecx + 9070 8d/copy-address *(eax+ecx+4) 1/r32/ecx + 9071 05/add-to-eax 4/imm32 + 9072 # var slice/ecx: slice = {eax, ecx} + 9073 51/push-ecx + 9074 50/push-eax + 9075 89/<- %ecx 4/r32/esp + 9076 # _test-input-stream contains "(addr int)" + 9077 (clear-stream _test-input-stream) + 9078 (write _test-input-stream "(addr int)") + 9079 # var v/edx: (handle var) + 9080 68/push 0/imm32 + 9081 68/push 0/imm32 + 9082 89/<- %edx 4/r32/esp + 9083 # + 9084 (parse-var-with-type %ecx _test-input-stream %edx Stderr 0) + 9085 # var v-addr/edx: (addr var) = lookup(v) + 9086 (lookup *edx *(edx+4)) # => eax + 9087 89/<- %edx 0/r32/eax + 9088 # check v-addr->name + 9089 (lookup *edx *(edx+4)) # Var-name Var-name => eax + 9090 (check-strings-equal %eax "x" "F - test-parse-var-with-compound-type/name") + 9091 # check v-addr->register + 9092 (check-ints-equal *(edx+0x18) 0 "F - test-parse-var-with-compound-type/register") # Var-register + 9093 # - check v-addr->type + 9094 # var type/edx: (addr type-tree) = var->type + 9095 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax + 9096 89/<- %edx 0/r32/eax + 9097 # type is a non-atom + 9098 (check-ints-equal *edx 0 "F - test-parse-var-with-compound-type/type:0") # Type-tree-is-atom + 9099 # type->left == atom(addr) + 9100 (lookup *(edx+4) *(edx+8)) # Type-tree-left Type-tree-left => eax + 9101 (check-ints-equal *eax 1 "F - test-parse-var-with-compound-type/type:1") # Type-tree-is-atom + 9102 (check-ints-equal *(eax+4) 2 "F - test-parse-var-with-compound-type/type:2") # Type-tree-value + 9103 # type->right->left == atom(int) + 9104 (lookup *(edx+0xc) *(edx+0x10)) # Type-tree-right Type-tree-right => eax + 9105 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax + 9106 (check-ints-equal *eax 1 "F - test-parse-var-with-compound-type/type:3") # Type-tree-is-atom + 9107 (check-ints-equal *(eax+4) 1 "F - test-parse-var-with-compound-type/type:4") # Type-tree-value + 9108 # type->right->right == null + 9109 (check-ints-equal *(eax+0xc) 0 "F - test-parse-var-with-compound-type/type:5") # Type-tree-right + 9110 # . epilogue + 9111 89/<- %esp 5/r32/ebp + 9112 5d/pop-to-ebp + 9113 c3/return + 9114 + 9115 # identifier starts with a letter or '$' or '_' + 9116 # no constraints at the moment on later letters + 9117 # all we really want to do so far is exclude '{', '}' and '->' + 9118 is-identifier?: # in: (addr slice) -> result/eax: boolean + 9119 # . prologue + 9120 55/push-ebp + 9121 89/<- %ebp 4/r32/esp + 9122 # if (slice-empty?(in)) return false + 9123 (slice-empty? *(ebp+8)) # => eax + 9124 3d/compare-eax-and 0/imm32/false + 9125 75/jump-if-!= $is-identifier?:false/disp8 + 9126 # var c/eax: byte = *in->start + 9127 8b/-> *(ebp+8) 0/r32/eax + 9128 8b/-> *eax 0/r32/eax + 9129 8a/copy-byte *eax 0/r32/AL + 9130 81 4/subop/and %eax 0xff/imm32 + 9131 # if (c == '$') return true + 9132 3d/compare-eax-and 0x24/imm32/$ + 9133 74/jump-if-= $is-identifier?:true/disp8 + 9134 # if (c == '_') return true + 9135 3d/compare-eax-and 0x5f/imm32/_ + 9136 74/jump-if-= $is-identifier?:true/disp8 + 9137 # drop case + 9138 25/and-eax-with 0x5f/imm32 + 9139 # if (c < 'A') return false + 9140 3d/compare-eax-and 0x41/imm32/A + 9141 7c/jump-if-< $is-identifier?:false/disp8 + 9142 # if (c > 'Z') return false + 9143 3d/compare-eax-and 0x5a/imm32/Z + 9144 7f/jump-if-> $is-identifier?:false/disp8 + 9145 # otherwise return true + 9146 $is-identifier?:true: + 9147 b8/copy-to-eax 1/imm32/true + 9148 eb/jump $is-identifier?:end/disp8 + 9149 $is-identifier?:false: + 9150 b8/copy-to-eax 0/imm32/false + 9151 $is-identifier?:end: + 9152 # . epilogue + 9153 89/<- %esp 5/r32/ebp + 9154 5d/pop-to-ebp + 9155 c3/return + 9156 + 9157 test-is-identifier-dollar: + 9158 # . prologue + 9159 55/push-ebp + 9160 89/<- %ebp 4/r32/esp + 9161 # (eax..ecx) = "$a" + 9162 b8/copy-to-eax "$a"/imm32 + 9163 8b/-> *eax 1/r32/ecx + 9164 8d/copy-address *(eax+ecx+4) 1/r32/ecx + 9165 05/add-to-eax 4/imm32 + 9166 # var slice/ecx: slice = {eax, ecx} + 9167 51/push-ecx + 9168 50/push-eax + 9169 89/<- %ecx 4/r32/esp + 9170 # + 9171 (is-identifier? %ecx) + 9172 (check-ints-equal %eax 1 "F - test-is-identifier-dollar") + 9173 # . epilogue + 9174 89/<- %esp 5/r32/ebp + 9175 5d/pop-to-ebp + 9176 c3/return + 9177 + 9178 test-is-identifier-underscore: + 9179 # . prologue + 9180 55/push-ebp + 9181 89/<- %ebp 4/r32/esp + 9182 # (eax..ecx) = "_a" + 9183 b8/copy-to-eax "_a"/imm32 + 9184 8b/-> *eax 1/r32/ecx + 9185 8d/copy-address *(eax+ecx+4) 1/r32/ecx + 9186 05/add-to-eax 4/imm32 + 9187 # var slice/ecx: slice = {eax, ecx} + 9188 51/push-ecx 9189 50/push-eax - 9190 51/push-ecx - 9191 52/push-edx - 9192 53/push-ebx - 9193 57/push-edi - 9194 # var name/ecx: slice - 9195 68/push 0/imm32/end - 9196 68/push 0/imm32/start - 9197 89/<- %ecx 4/r32/esp - 9198 # var is-deref?/edx: boolean = false - 9199 ba/copy-to-edx 0/imm32/false - 9200 # var v: (handle var) - 9201 68/push 0/imm32 - 9202 68/push 0/imm32 - 9203 89/<- %ebx 4/r32/esp - 9204 # - 9205 (allocate Heap *Stmt-size *(ebp+0x14)) - 9206 # var out-addr/edi: (addr stmt) = lookup(*out) - 9207 8b/-> *(ebp+0x14) 7/r32/edi - 9208 (lookup *edi *(edi+4)) # => eax - 9209 89/<- %edi 0/r32/eax - 9210 # out-addr->tag = 1/stmt - 9211 c7 0/subop/copy *edi 1/imm32/stmt1 # Stmt-tag - 9212 { - 9213 (stmt-has-outputs? *(ebp+8)) - 9214 3d/compare-eax-and 0/imm32/false - 9215 0f 84/jump-if-= break/disp32 - 9216 { - 9217 $parse-mu-stmt:read-outputs: - 9218 # name = next-mu-token(line) - 9219 (next-mu-token *(ebp+8) %ecx) - 9220 # if slice-empty?(word-slice) break - 9221 (slice-empty? %ecx) # => eax - 9222 3d/compare-eax-and 0/imm32/false - 9223 0f 85/jump-if-!= break/disp32 - 9224 # if (name == "<-") break - 9225 (slice-equal? %ecx "<-") # => eax - 9226 3d/compare-eax-and 0/imm32/false - 9227 0f 85/jump-if-!= break/disp32 - 9228 # is-deref? = false - 9229 ba/copy-to-edx 0/imm32/false - 9230 # if (slice-starts-with?(name, '*')) ++name->start and set is-deref? - 9231 8b/-> *ecx 0/r32/eax # Slice-start - 9232 8a/copy-byte *eax 0/r32/AL - 9233 81 4/subop/and %eax 0xff/imm32 - 9234 3d/compare-eax-and 0x2a/imm32/asterisk - 9235 { - 9236 75/jump-if-!= break/disp8 - 9237 ff 0/subop/increment *ecx - 9238 ba/copy-to-edx 1/imm32/true - 9239 } - 9240 # assert(is-identifier?(name)) - 9241 (is-identifier? %ecx) # => eax - 9242 3d/compare-eax-and 0/imm32/false - 9243 0f 84/jump-if-= $parse-mu-stmt:abort/disp32 - 9244 # - 9245 (lookup-var-or-find-in-fn-outputs %ecx *(ebp+0xc) *(ebp+0x10) %ebx *(ebp+0x18) *(ebp+0x1c)) - 9246 8d/copy-address *(edi+0x14) 0/r32/eax # Stmt1-outputs - 9247 (append-stmt-var Heap *ebx *(ebx+4) *(edi+0x14) *(edi+0x18) %edx %eax) # Stmt1-outputs - 9248 # - 9249 e9/jump loop/disp32 - 9250 } - 9251 } - 9252 (add-operation-and-inputs-to-stmt %edi *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x18) *(ebp+0x1c)) - 9253 $parse-mu-stmt:define-outputs: - 9254 # var output/edi: (addr stmt-var) = lookup(out-addr->outputs) - 9255 (lookup *(edi+0x14) *(edi+0x18)) # Stmt1-outputs Stmt1-outputs => eax - 9256 89/<- %edi 0/r32/eax - 9257 { - 9258 $parse-mu-stmt:define-outputs-loop: - 9259 # if (output == null) break - 9260 81 7/subop/compare %edi 0/imm32 - 9261 74/jump-if-= break/disp8 - 9262 # - 9263 (maybe-define-var *edi *(edi+4) *(ebp+0xc)) # if output is a deref, then it's already been defined, - 9264 # and must be in vars. This call will be a no-op, but safe. - 9265 # output = output->next - 9266 (lookup *(edi+8) *(edi+0xc)) # Stmt-var-next Stmt-var-next => eax - 9267 89/<- %edi 0/r32/eax - 9268 # - 9269 eb/jump loop/disp8 - 9270 } - 9271 $parse-mu-stmt:end: - 9272 # . reclaim locals - 9273 81 0/subop/add %esp 0x10/imm32 - 9274 # . restore registers - 9275 5f/pop-to-edi - 9276 5b/pop-to-ebx - 9277 5a/pop-to-edx - 9278 59/pop-to-ecx - 9279 58/pop-to-eax - 9280 # . epilogue - 9281 89/<- %esp 5/r32/ebp - 9282 5d/pop-to-ebp - 9283 c3/return - 9284 - 9285 $parse-mu-stmt:abort: - 9286 # error("invalid identifier '" name "'\n") - 9287 (write-buffered *(ebp+0x18) "invalid identifier '") - 9288 (write-slice-buffered *(ebp+0x18) %ecx) - 9289 (write-buffered *(ebp+0x18) "'\n") - 9290 (flush *(ebp+0x18)) - 9291 (stop *(ebp+0x1c) 1) - 9292 # never gets here - 9293 - 9294 add-operation-and-inputs-to-stmt: # stmt: (addr stmt), line: (addr stream byte), vars: (addr stack live-var), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) - 9295 # pseudocode: - 9296 # stmt->name = slice-to-string(next-mu-token(line)) - 9297 # while true - 9298 # name = next-mu-token(line) - 9299 # v = lookup-var-or-literal(name) - 9300 # stmt->inouts = append(v, stmt->inouts) - 9301 # - 9302 # . prologue - 9303 55/push-ebp - 9304 89/<- %ebp 4/r32/esp - 9305 # . save registers - 9306 50/push-eax - 9307 51/push-ecx - 9308 52/push-edx - 9309 53/push-ebx - 9310 56/push-esi - 9311 57/push-edi - 9312 # edi = stmt - 9313 8b/-> *(ebp+8) 7/r32/edi - 9314 # var name/ecx: slice - 9315 68/push 0/imm32/end - 9316 68/push 0/imm32/start - 9317 89/<- %ecx 4/r32/esp - 9318 # var is-deref?/edx: boolean = false - 9319 ba/copy-to-edx 0/imm32/false - 9320 # var v/esi: (handle var) - 9321 68/push 0/imm32 - 9322 68/push 0/imm32 - 9323 89/<- %esi 4/r32/esp - 9324 $add-operation-and-inputs-to-stmt:read-operation: - 9325 (next-mu-token *(ebp+0xc) %ecx) - 9326 8d/copy-address *(edi+4) 0/r32/eax # Stmt1-operation or Regvardef-operationStmt1-operation or Regvardef-operation - 9327 (slice-to-string Heap %ecx %eax) - 9328 # var is-get?/ebx: boolean = (name == "get") - 9329 (slice-equal? %ecx "get") # => eax - 9330 89/<- %ebx 0/r32/eax - 9331 { - 9332 $add-operation-and-inputs-to-stmt:read-inouts: - 9333 # name = next-mu-token(line) - 9334 (next-mu-token *(ebp+0xc) %ecx) - 9335 # if slice-empty?(word-slice) break - 9336 (slice-empty? %ecx) # => eax - 9337 3d/compare-eax-and 0/imm32/false - 9338 0f 85/jump-if-!= break/disp32 - 9339 # if (name == "<-") abort - 9340 (slice-equal? %ecx "<-") - 9341 3d/compare-eax-and 0/imm32/false - 9342 0f 85/jump-if-!= $add-operation-and-inputs-to-stmt:abort/disp32 - 9343 # if (is-get? && second operand) lookup or create offset - 9344 { - 9345 81 7/subop/compare %ebx 0/imm32/false - 9346 74/jump-if-= break/disp8 - 9347 (lookup *(edi+0xc) *(edi+0x10)) # Stmt1-inouts Stmt1-inouts => eax - 9348 3d/compare-eax-and 0/imm32 - 9349 74/jump-if-= break/disp8 - 9350 (lookup-or-create-constant %eax %ecx %esi) - 9351 #? (lookup *esi *(esi+4)) - 9352 #? (write-buffered Stderr "creating new output var ") - 9353 #? (write-int32-hex-buffered Stderr %eax) - 9354 #? (write-buffered Stderr " for field called ") - 9355 #? (write-slice-buffered Stderr %ecx) - 9356 #? (write-buffered Stderr "; var name ") - 9357 #? (lookup *eax *(eax+4)) # Var-name - 9358 #? (write-buffered Stderr %eax) - 9359 #? (write-buffered Stderr Newline) - 9360 #? (flush Stderr) - 9361 e9/jump $add-operation-and-inputs-to-stmt:save-var/disp32 - 9362 } - 9363 # is-deref? = false - 9364 ba/copy-to-edx 0/imm32/false - 9365 # if (slice-starts-with?(name, '*')) ++name->start and set is-deref? - 9366 8b/-> *ecx 0/r32/eax # Slice-start - 9367 8a/copy-byte *eax 0/r32/AL - 9368 81 4/subop/and %eax 0xff/imm32 - 9369 3d/compare-eax-and 0x2a/imm32/asterisk - 9370 { - 9371 75/jump-if-!= break/disp8 - 9372 $add-operation-and-inputs-to-stmt:inout-is-deref: - 9373 ff 0/subop/increment *ecx - 9374 ba/copy-to-edx 1/imm32/true - 9375 } - 9376 (lookup-var-or-literal %ecx *(ebp+0x10) %esi *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c)) - 9377 $add-operation-and-inputs-to-stmt:save-var: - 9378 8d/copy-address *(edi+0xc) 0/r32/eax - 9379 (append-stmt-var Heap *esi *(esi+4) *(edi+0xc) *(edi+0x10) %edx %eax) # Stmt1-inouts or Regvardef-inouts - 9380 # - 9381 e9/jump loop/disp32 - 9382 } - 9383 $add-operation-and-inputs-to-stmt:end: - 9384 # . reclaim locals - 9385 81 0/subop/add %esp 0x10/imm32 - 9386 # . restore registers - 9387 5f/pop-to-edi - 9388 5e/pop-to-esi - 9389 5b/pop-to-ebx - 9390 5a/pop-to-edx - 9391 59/pop-to-ecx - 9392 58/pop-to-eax - 9393 # . epilogue - 9394 89/<- %esp 5/r32/ebp - 9395 5d/pop-to-ebp - 9396 c3/return - 9397 - 9398 $add-operation-and-inputs-to-stmt:abort: - 9399 # error("fn ___: invalid identifier in '" line "'\n") - 9400 (write-buffered *(ebp+0x18) "fn ") - 9401 8b/-> *(ebp+0x14) 0/r32/eax - 9402 (lookup *eax *(eax+4)) # Function-name Function-name => eax - 9403 (write-buffered *(ebp+0x18) %eax) - 9404 (rewind-stream *(ebp+0xc)) - 9405 (write-buffered *(ebp+0x18) ": invalid identifier in '") - 9406 (write-stream-data *(ebp+0x18) *(ebp+0xc)) - 9407 (write-buffered *(ebp+0x18) "'\n") - 9408 (flush *(ebp+0x18)) - 9409 (stop *(ebp+0x1c) 1) - 9410 # never gets here - 9411 - 9412 stmt-has-outputs?: # line: (addr stream byte) -> result/eax: boolean - 9413 # . prologue - 9414 55/push-ebp - 9415 89/<- %ebp 4/r32/esp - 9416 # . save registers - 9417 51/push-ecx - 9418 # var word-slice/ecx: slice - 9419 68/push 0/imm32/end - 9420 68/push 0/imm32/start - 9421 89/<- %ecx 4/r32/esp - 9422 # result = false - 9423 b8/copy-to-eax 0/imm32/false - 9424 (rewind-stream *(ebp+8)) - 9425 { - 9426 (next-mu-token *(ebp+8) %ecx) - 9427 # if slice-empty?(word-slice) break - 9428 (slice-empty? %ecx) - 9429 3d/compare-eax-and 0/imm32/false - 9430 b8/copy-to-eax 0/imm32/false/result # restore result (if we're here it's still false) - 9431 0f 85/jump-if-!= break/disp32 - 9432 # if slice-starts-with?(word-slice, '#') break - 9433 # . eax = *word-slice->start - 9434 8b/-> *ecx 0/r32/eax - 9435 8a/copy-byte *eax 0/r32/AL - 9436 81 4/subop/and %eax 0xff/imm32 - 9437 # . if (eax == '#') break - 9438 3d/compare-eax-and 0x23/imm32/hash - 9439 b8/copy-to-eax 0/imm32/false/result # restore result (if we're here it's still false) - 9440 0f 84/jump-if-= break/disp32 - 9441 # if slice-equal?(word-slice, '<-') return true - 9442 (slice-equal? %ecx "<-") - 9443 3d/compare-eax-and 0/imm32/false - 9444 74/jump-if-= loop/disp8 - 9445 b8/copy-to-eax 1/imm32/true - 9446 } - 9447 $stmt-has-outputs:end: - 9448 (rewind-stream *(ebp+8)) - 9449 # . reclaim locals - 9450 81 0/subop/add %esp 8/imm32 - 9451 # . restore registers - 9452 59/pop-to-ecx - 9453 # . epilogue - 9454 89/<- %esp 5/r32/ebp - 9455 5d/pop-to-ebp - 9456 c3/return - 9457 - 9458 # if 'name' starts with a digit, create a new literal var for it - 9459 # otherwise return first 'name' from the top (back) of 'vars' and abort if not found - 9460 lookup-var-or-literal: # name: (addr slice), vars: (addr stack live-var), out: (addr handle var), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) - 9461 # . prologue - 9462 55/push-ebp - 9463 89/<- %ebp 4/r32/esp - 9464 # . save registers - 9465 50/push-eax - 9466 51/push-ecx - 9467 56/push-esi - 9468 # esi = name - 9469 8b/-> *(ebp+8) 6/r32/esi - 9470 # if slice-empty?(name) abort - 9471 (slice-empty? %esi) # => eax - 9472 3d/compare-eax-and 0/imm32/false - 9473 0f 85/jump-if-!= $lookup-var-or-literal:abort/disp32 - 9474 # var c/ecx: byte = *name->start - 9475 8b/-> *esi 1/r32/ecx - 9476 8a/copy-byte *ecx 1/r32/CL - 9477 81 4/subop/and %ecx 0xff/imm32 - 9478 # if is-decimal-digit?(c) return new var(name) - 9479 { - 9480 (is-decimal-digit? %ecx) # => eax - 9481 3d/compare-eax-and 0/imm32/false - 9482 74/jump-if-= break/disp8 - 9483 $lookup-var-or-literal:literal: - 9484 (new-literal-integer Heap %esi *(ebp+0x10) *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c)) - 9485 eb/jump $lookup-var-or-literal:end/disp8 - 9486 } - 9487 # else if (c == '"') return new var(name) - 9488 { - 9489 81 7/subop/compare %ecx 0x22/imm32/dquote - 9490 75/jump-if-!= break/disp8 - 9491 $lookup-var-or-literal:literal-string: - 9492 (new-literal Heap %esi *(ebp+0x10)) - 9493 eb/jump $lookup-var-or-literal:end/disp8 - 9494 } - 9495 # otherwise return lookup-var(name, vars) - 9496 { - 9497 $lookup-var-or-literal:var: - 9498 (lookup-var %esi *(ebp+0xc) *(ebp+0x10) *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c)) - 9499 } - 9500 $lookup-var-or-literal:end: - 9501 # . restore registers - 9502 5e/pop-to-esi - 9503 59/pop-to-ecx - 9504 58/pop-to-eax - 9505 # . epilogue - 9506 89/<- %esp 5/r32/ebp - 9507 5d/pop-to-ebp - 9508 c3/return - 9509 - 9510 $lookup-var-or-literal:abort: - 9511 (write-buffered *(ebp+0x18) "fn ") - 9512 8b/-> *(ebp+0x14) 0/r32/eax - 9513 (lookup *eax *(eax+4)) # Function-name Function-name => eax - 9514 (write-buffered *(ebp+0x18) %eax) - 9515 (write-buffered *(ebp+0x18) ": empty variable!") - 9516 (flush *(ebp+0x18)) - 9517 (stop *(ebp+0x1c) 1) - 9518 # never gets here - 9519 - 9520 # return first 'name' from the top (back) of 'vars' and abort if not found - 9521 lookup-var: # name: (addr slice), vars: (addr stack live-var), out: (addr handle var), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) - 9522 # . prologue - 9523 55/push-ebp - 9524 89/<- %ebp 4/r32/esp - 9525 # . save registers - 9526 50/push-eax - 9527 # - 9528 (lookup-var-helper *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c)) - 9529 # if (*out == 0) abort - 9530 8b/-> *(ebp+0x10) 0/r32/eax - 9531 81 7/subop/compare *eax 0/imm32 - 9532 74/jump-if-= $lookup-var:abort/disp8 - 9533 $lookup-var:end: - 9534 # . restore registers - 9535 58/pop-to-eax - 9536 # . epilogue - 9537 89/<- %esp 5/r32/ebp - 9538 5d/pop-to-ebp - 9539 c3/return - 9540 - 9541 $lookup-var:abort: - 9542 (write-buffered *(ebp+0x18) "fn ") - 9543 8b/-> *(ebp+0x14) 0/r32/eax - 9544 (lookup *eax *(eax+4)) # Function-name Function-name => eax - 9545 (write-buffered *(ebp+0x18) %eax) - 9546 (write-buffered *(ebp+0x18) ": unknown variable '") - 9547 (write-slice-buffered *(ebp+0x18) *(ebp+8)) - 9548 (write-buffered *(ebp+0x18) "'\n") - 9549 (flush *(ebp+0x18)) - 9550 (stop *(ebp+0x1c) 1) - 9551 # never gets here - 9552 - 9553 # return first 'name' from the top (back) of 'vars', and 0/null if not found - 9554 # ensure that 'name' if in a register is the topmost variable in that register - 9555 lookup-var-helper: # name: (addr slice), vars: (addr stack live-var), out: (addr handle var), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) - 9556 # pseudocode: - 9557 # var curr: (addr handle var) = &vars->data[vars->top - 12] - 9558 # var min = vars->data - 9559 # while curr >= min - 9560 # var v: (handle var) = *curr - 9561 # if v->name == name - 9562 # return - 9563 # curr -= 12 - 9564 # - 9565 # . prologue - 9566 55/push-ebp - 9567 89/<- %ebp 4/r32/esp - 9568 # . save registers - 9569 50/push-eax - 9570 51/push-ecx - 9571 52/push-edx - 9572 53/push-ebx - 9573 56/push-esi - 9574 57/push-edi - 9575 # clear out - 9576 (zero-out *(ebp+0x10) *Handle-size) - 9577 # esi = vars - 9578 8b/-> *(ebp+0xc) 6/r32/esi - 9579 # ebx = vars->top - 9580 8b/-> *esi 3/r32/ebx - 9581 # if (vars->top > vars->size) abort - 9582 3b/compare<- *(esi+4) 0/r32/eax - 9583 0f 8f/jump-if-> $lookup-var-helper:error1/disp32 - 9584 # var min/edx: (addr handle var) = vars->data - 9585 8d/copy-address *(esi+8) 2/r32/edx - 9586 # var curr/ebx: (addr handle var) = &vars->data[vars->top - 12] - 9587 8d/copy-address *(esi+ebx-4) 3/r32/ebx # vars + 8 + vars->type - 12 - 9588 # var var-in-reg/edi: 8 addrs - 9589 68/push 0/imm32 - 9590 68/push 0/imm32 - 9591 68/push 0/imm32 - 9592 68/push 0/imm32 - 9593 68/push 0/imm32 - 9594 68/push 0/imm32 - 9595 68/push 0/imm32 - 9596 68/push 0/imm32 - 9597 89/<- %edi 4/r32/esp - 9598 { - 9599 $lookup-var-helper:loop: - 9600 # if (curr < min) return - 9601 39/compare %ebx 2/r32/edx - 9602 0f 82/jump-if-addr< break/disp32 - 9603 # var v/ecx: (addr var) = lookup(*curr) - 9604 (lookup *ebx *(ebx+4)) # => eax - 9605 89/<- %ecx 0/r32/eax - 9606 # var vn/eax: (addr array byte) = lookup(v->name) - 9607 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax - 9608 # if (vn == name) return curr - 9609 (slice-equal? *(ebp+8) %eax) # => eax - 9610 3d/compare-eax-and 0/imm32/false - 9611 { - 9612 74/jump-if-= break/disp8 - 9613 $lookup-var-helper:found: - 9614 # var vr/eax: (addr array byte) = lookup(v->register) - 9615 (lookup *(ecx+0x18) *(ecx+0x1c)) # Var-register Var-register => eax - 9616 3d/compare-eax-and 0/imm32 - 9617 { - 9618 74/jump-if-= break/disp8 - 9619 $lookup-var-helper:found-register: - 9620 # var reg/eax: int = get(Registers, vr) - 9621 (get Mu-registers %eax 0xc "Mu-registers") # => eax - 9622 8b/-> *eax 0/r32/eax - 9623 # if (var-in-reg[reg]) error - 9624 8b/-> *(edi+eax<<2) 0/r32/eax - 9625 3d/compare-eax-and 0/imm32 - 9626 0f 85/jump-if-!= $lookup-var-helper:error2/disp32 - 9627 } - 9628 $lookup-var-helper:return: - 9629 # esi = out - 9630 8b/-> *(ebp+0x10) 6/r32/esi - 9631 # *out = *curr - 9632 8b/-> *ebx 0/r32/eax - 9633 89/<- *esi 0/r32/eax - 9634 8b/-> *(ebx+4) 0/r32/eax - 9635 89/<- *(esi+4) 0/r32/eax - 9636 # return - 9637 eb/jump $lookup-var-helper:end/disp8 - 9638 } - 9639 # 'name' not yet found; update var-in-reg if v in register - 9640 # . var vr/eax: (addr array byte) = lookup(v->register) - 9641 (lookup *(ecx+0x18) *(ecx+0x1c)) # Var-register Var-register => eax - 9642 # . if (var == 0) continue - 9643 3d/compare-eax-and 0/imm32 - 9644 74/jump-if-= $lookup-var-helper:continue/disp8 - 9645 # . var reg/eax: int = get(Registers, vr) - 9646 (get Mu-registers %eax 0xc "Mu-registers") # => eax - 9647 8b/-> *eax 0/r32/eax - 9648 # . if (var-in-reg[reg] == 0) var-in-reg[reg] = v - 9649 81 7/subop/compare *(edi+eax<<2) 0/imm32 - 9650 75/jump-if-!= $lookup-var-helper:continue/disp8 - 9651 89/<- *(edi+eax<<2) 1/r32/ecx - 9652 $lookup-var-helper:continue: - 9653 # curr -= 12 - 9654 81 5/subop/subtract %ebx 0xc/imm32 - 9655 e9/jump loop/disp32 - 9656 } - 9657 $lookup-var-helper:end: - 9658 # . reclaim locals - 9659 81 0/subop/add %esp 0x20/imm32 - 9660 # . restore registers - 9661 5f/pop-to-edi - 9662 5e/pop-to-esi - 9663 5b/pop-to-ebx - 9664 5a/pop-to-edx - 9665 59/pop-to-ecx - 9666 58/pop-to-eax - 9667 # . epilogue - 9668 89/<- %esp 5/r32/ebp - 9669 5d/pop-to-ebp - 9670 c3/return - 9671 - 9672 $lookup-var-helper:error1: - 9673 (write-buffered *(ebp+0x18) "fn ") - 9674 8b/-> *(ebp+0x14) 0/r32/eax - 9675 (lookup *eax *(eax+4)) # Function-name Function-name => eax - 9676 (write-buffered *(ebp+0x18) %eax) - 9677 (write-buffered *(ebp+0x18) ": malformed stack when looking up '") - 9678 (write-slice-buffered *(ebp+0x18) *(ebp+8)) - 9679 (write-buffered *(ebp+0x18) "'\n") - 9680 (flush *(ebp+0x18)) - 9681 (stop *(ebp+0x1c) 1) - 9682 # never gets here - 9683 - 9684 $lookup-var-helper:error2: - 9685 # eax contains the conflicting var at this point - 9686 (write-buffered *(ebp+0x18) "fn ") - 9687 50/push-eax - 9688 8b/-> *(ebp+0x14) 0/r32/eax - 9689 (lookup *eax *(eax+4)) # Function-name Function-name => eax - 9690 (write-buffered *(ebp+0x18) %eax) - 9691 58/pop-eax - 9692 (write-buffered *(ebp+0x18) ": register ") - 9693 50/push-eax - 9694 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax - 9695 (write-buffered *(ebp+0x18) %eax) - 9696 58/pop-to-eax - 9697 (write-buffered *(ebp+0x18) " reads var '") - 9698 (write-slice-buffered *(ebp+0x18) *(ebp+8)) - 9699 (write-buffered *(ebp+0x18) "' after writing var '") - 9700 (lookup *eax *(eax+4)) # Var-name Var-name => eax - 9701 (write-buffered *(ebp+0x18) %eax) - 9702 (write-buffered *(ebp+0x18) "'\n") - 9703 (flush *(ebp+0x18)) - 9704 (stop *(ebp+0x1c) 1) - 9705 # never gets here - 9706 - 9707 dump-vars: # vars: (addr stack live-var) - 9708 # pseudocode: - 9709 # var curr: (addr handle var) = &vars->data[vars->top - 12] - 9710 # var min = vars->data - 9711 # while curr >= min - 9712 # var v: (handle var) = *curr - 9713 # print v - 9714 # curr -= 12 - 9715 # - 9716 # . prologue - 9717 55/push-ebp - 9718 89/<- %ebp 4/r32/esp - 9719 # . save registers - 9720 52/push-edx - 9721 53/push-ebx - 9722 56/push-esi - 9723 # esi = vars - 9724 8b/-> *(ebp+8) 6/r32/esi - 9725 # ebx = vars->top - 9726 8b/-> *esi 3/r32/ebx - 9727 # var min/edx: (addr handle var) = vars->data - 9728 8d/copy-address *(esi+8) 2/r32/edx - 9729 # var curr/ebx: (addr handle var) = &vars->data[vars->top - 12] - 9730 8d/copy-address *(esi+ebx-4) 3/r32/ebx # vars + 8 + vars->type - 12 - 9731 { - 9732 $dump-vars:loop: - 9733 # if (curr < min) return - 9734 39/compare %ebx 2/r32/edx - 9735 0f 82/jump-if-addr< break/disp32 - 9736 # - 9737 (write-buffered Stderr " var@") - 9738 (dump-var 2 %ebx) - 9739 # curr -= 12 - 9740 81 5/subop/subtract %ebx 0xc/imm32 - 9741 e9/jump loop/disp32 - 9742 } - 9743 $dump-vars:end: - 9744 # . restore registers - 9745 5e/pop-to-esi - 9746 5b/pop-to-ebx - 9747 5a/pop-to-edx - 9748 # . epilogue - 9749 89/<- %esp 5/r32/ebp - 9750 5d/pop-to-ebp - 9751 c3/return - 9752 - 9753 == data - 9754 # Like Registers, but no esp or ebp - 9755 Mu-registers: # (addr stream {(handle array byte), int}) - 9756 # a table is a stream - 9757 0x48/imm32/write - 9758 0/imm32/read - 9759 0x48/imm32/length - 9760 # data - 9761 # it is perfectly ok to use fake alloc-ids -- as long as you never try to reclaim them - 9762 0x11/imm32/alloc-id $Mu-register-eax/imm32 0/imm32 - 9763 0x11/imm32/alloc-id $Mu-register-ecx/imm32 1/imm32 - 9764 0x11/imm32/alloc-id $Mu-register-edx/imm32 2/imm32 - 9765 0x11/imm32/alloc-id $Mu-register-ebx/imm32 3/imm32 - 9766 0x11/imm32/alloc-id $Mu-register-esi/imm32 6/imm32 - 9767 0x11/imm32/alloc-id $Mu-register-edi/imm32 7/imm32 - 9768 - 9769 $Mu-register-eax: - 9770 0x11/imm32/alloc-id - 9771 3/imm32/size - 9772 0x65/e 0x61/a 0x78/x - 9773 - 9774 $Mu-register-ecx: - 9775 0x11/imm32/alloc-id - 9776 3/imm32/size - 9777 0x65/e 0x63/c 0x78/x - 9778 - 9779 $Mu-register-edx: - 9780 0x11/imm32/alloc-id - 9781 3/imm32/size - 9782 0x65/e 0x64/d 0x78/x - 9783 - 9784 $Mu-register-ebx: - 9785 0x11/imm32/alloc-id - 9786 3/imm32/size - 9787 0x65/e 0x62/b 0x78/x - 9788 - 9789 $Mu-register-esi: - 9790 0x11/imm32/alloc-id - 9791 3/imm32/size - 9792 0x65/e 0x73/s 0x69/i - 9793 - 9794 $Mu-register-edi: - 9795 0x11/imm32/alloc-id - 9796 3/imm32/size - 9797 0x65/e 0x64/d 0x69/i - 9798 - 9799 == code - 9800 - 9801 # return first 'name' from the top (back) of 'vars' and create a new var for a fn output if not found - 9802 lookup-var-or-find-in-fn-outputs: # name: (addr slice), vars: (addr stack live-var), fn: (addr function), out: (addr handle var), err: (addr buffered-file), ed: (addr exit-descriptor) - 9803 # . prologue - 9804 55/push-ebp - 9805 89/<- %ebp 4/r32/esp - 9806 # . save registers - 9807 50/push-eax - 9808 # - 9809 (lookup-var-helper *(ebp+8) *(ebp+0xc) *(ebp+0x14) *(ebp+0x10) *(ebp+0x18) *(ebp+0x1c)) # arg order slightly different; 'fn' is deemphasized - 9810 { - 9811 # if (out != 0) return - 9812 8b/-> *(ebp+0x14) 0/r32/eax - 9813 81 7/subop/compare *eax 0/imm32 - 9814 75/jump-if-!= break/disp8 - 9815 # if name is one of fn's outputs, return it - 9816 (find-in-function-outputs *(ebp+0x10) *(ebp+8) *(ebp+0x14)) - 9817 8b/-> *(ebp+0x14) 0/r32/eax - 9818 81 7/subop/compare *eax 0/imm32 - 9819 # otherwise abort - 9820 0f 84/jump-if-= $lookup-or-define-var:abort/disp32 - 9821 } - 9822 $lookup-or-define-var:end: - 9823 # . restore registers - 9824 58/pop-to-eax - 9825 # . epilogue - 9826 89/<- %esp 5/r32/ebp - 9827 5d/pop-to-ebp - 9828 c3/return - 9829 - 9830 $lookup-or-define-var:abort: - 9831 (write-buffered *(ebp+0x18) "unknown variable '") - 9832 (write-slice-buffered *(ebp+0x18) *(ebp+8)) - 9833 (write-buffered *(ebp+0x18) "'\n") - 9834 (flush *(ebp+0x18)) - 9835 (stop *(ebp+0x1c) 1) - 9836 # never gets here - 9837 - 9838 find-in-function-outputs: # fn: (addr function), name: (addr slice), out: (addr handle var) - 9839 # . prologue - 9840 55/push-ebp - 9841 89/<- %ebp 4/r32/esp - 9842 # . save registers - 9843 50/push-eax - 9844 51/push-ecx - 9845 # var curr/ecx: (addr list var) = lookup(fn->outputs) - 9846 8b/-> *(ebp+8) 1/r32/ecx - 9847 (lookup *(ecx+0x10) *(ecx+0x14)) # Function-outputs Function-outputs => eax - 9848 89/<- %ecx 0/r32/eax - 9849 # while curr != null - 9850 { - 9851 81 7/subop/compare %ecx 0/imm32 - 9852 74/jump-if-= break/disp8 - 9853 # var v/eax: (addr var) = lookup(curr->value) - 9854 (lookup *ecx *(ecx+4)) # List-value List-value => eax - 9855 # var s/eax: (addr array byte) = lookup(v->name) - 9856 (lookup *eax *(eax+4)) # Var-name Var-name => eax - 9857 # if (s == name) return curr->value - 9858 (slice-equal? *(ebp+0xc) %eax) # => eax - 9859 3d/compare-eax-and 0/imm32/false - 9860 { - 9861 74/jump-if-= break/disp8 - 9862 # var edi = out - 9863 57/push-edi - 9864 8b/-> *(ebp+0x10) 7/r32/edi - 9865 # *out = curr->value - 9866 8b/-> *ecx 0/r32/eax - 9867 89/<- *edi 0/r32/eax - 9868 8b/-> *(ecx+4) 0/r32/eax - 9869 89/<- *(edi+4) 0/r32/eax - 9870 # - 9871 5f/pop-to-edi - 9872 eb/jump $find-in-function-outputs:end/disp8 - 9873 } - 9874 # curr = curr->next - 9875 (lookup *(ecx+8) *(ecx+0xc)) # List-next List-next => eax - 9876 89/<- %ecx 0/r32/eax - 9877 # - 9878 eb/jump loop/disp8 - 9879 } - 9880 b8/copy-to-eax 0/imm32 - 9881 $find-in-function-outputs:end: - 9882 # . restore registers - 9883 59/pop-to-ecx - 9884 58/pop-to-eax - 9885 # . epilogue - 9886 89/<- %esp 5/r32/ebp - 9887 5d/pop-to-ebp - 9888 c3/return - 9889 - 9890 # push 'out' to 'vars' if not already there; it's assumed to be a fn output - 9891 maybe-define-var: # out: (handle var), vars: (addr stack live-var) - 9892 # . prologue - 9893 55/push-ebp - 9894 89/<- %ebp 4/r32/esp - 9895 # . save registers - 9896 50/push-eax - 9897 # var out-addr/eax: (addr var) - 9898 (lookup *(ebp+8) *(ebp+0xc)) # => eax - 9899 # - 9900 (binding-exists? %eax *(ebp+0x10)) # => eax - 9901 3d/compare-eax-and 0/imm32/false - 9902 75/jump-if-!= $maybe-define-var:end/disp8 - 9903 # otherwise update vars - 9904 (push *(ebp+0x10) *(ebp+8)) - 9905 (push *(ebp+0x10) *(ebp+0xc)) - 9906 (push *(ebp+0x10) 0) # 'out' is always a fn output; never spill it - 9907 $maybe-define-var:end: - 9908 # . restore registers - 9909 58/pop-to-eax - 9910 # . epilogue - 9911 89/<- %esp 5/r32/ebp - 9912 5d/pop-to-ebp - 9913 c3/return - 9914 - 9915 # simpler version of lookup-var-helper - 9916 binding-exists?: # target: (addr var), vars: (addr stack live-var) -> result/eax: boolean - 9917 # pseudocode: - 9918 # var curr: (addr handle var) = &vars->data[vars->top - 12] - 9919 # var min = vars->data - 9920 # while curr >= min - 9921 # var v: (handle var) = *curr - 9922 # if v->name == target->name - 9923 # return true - 9924 # curr -= 12 - 9925 # return false - 9926 # - 9927 # . prologue - 9928 55/push-ebp - 9929 89/<- %ebp 4/r32/esp - 9930 # . save registers - 9931 51/push-ecx - 9932 52/push-edx - 9933 56/push-esi - 9934 # var target-name/ecx: (addr array byte) = lookup(target->name) - 9935 8b/-> *(ebp+8) 0/r32/eax - 9936 (lookup *eax *(eax+4)) # Var-name Var-name => eax - 9937 89/<- %ecx 0/r32/eax - 9938 # esi = vars - 9939 8b/-> *(ebp+0xc) 6/r32/esi - 9940 # eax = vars->top - 9941 8b/-> *esi 0/r32/eax - 9942 # var min/edx: (addr handle var) = vars->data - 9943 8d/copy-address *(esi+8) 2/r32/edx - 9944 # var curr/esi: (addr handle var) = &vars->data[vars->top - 12] - 9945 8d/copy-address *(esi+eax-4) 6/r32/esi # vars + 8 + vars->type - 12 - 9946 { - 9947 $binding-exists?:loop: - 9948 # if (curr < min) return - 9949 39/compare %esi 2/r32/edx - 9950 0f 82/jump-if-addr< break/disp32 - 9951 # var v/eax: (addr var) = lookup(*curr) - 9952 (lookup *esi *(esi+4)) # => eax - 9953 # var vn/eax: (addr array byte) = lookup(v->name) - 9954 (lookup *eax *(eax+4)) # Var-name Var-name => eax - 9955 # if (vn == target-name) return true - 9956 (string-equal? %ecx %eax) # => eax - 9957 3d/compare-eax-and 0/imm32/false - 9958 75/jump-if-!= $binding-exists?:end/disp8 # eax already contains true - 9959 # curr -= 12 - 9960 81 5/subop/subtract %esi 0xc/imm32 - 9961 e9/jump loop/disp32 - 9962 } - 9963 b8/copy-to-eax 0/imm32/false - 9964 $binding-exists?:end: - 9965 # . restore registers - 9966 5e/pop-to-esi - 9967 5a/pop-to-edx - 9968 59/pop-to-ecx - 9969 # . epilogue - 9970 89/<- %esp 5/r32/ebp - 9971 5d/pop-to-ebp - 9972 c3/return - 9973 - 9974 test-parse-mu-stmt: - 9975 # . prologue - 9976 55/push-ebp - 9977 89/<- %ebp 4/r32/esp - 9978 # setup - 9979 (clear-stream _test-input-stream) - 9980 (write _test-input-stream "increment n\n") - 9981 # var vars/ecx: (stack (addr var) 16) - 9982 81 5/subop/subtract %esp 0xc0/imm32 - 9983 68/push 0xc0/imm32/size - 9984 68/push 0/imm32/top - 9985 89/<- %ecx 4/r32/esp - 9986 (clear-stack %ecx) - 9987 # var v/edx: (handle var) - 9988 68/push 0/imm32 + 9190 89/<- %ecx 4/r32/esp + 9191 # + 9192 (is-identifier? %ecx) + 9193 (check-ints-equal %eax 1 "F - test-is-identifier-underscore") + 9194 # . epilogue + 9195 89/<- %esp 5/r32/ebp + 9196 5d/pop-to-ebp + 9197 c3/return + 9198 + 9199 test-is-identifier-a: + 9200 # . prologue + 9201 55/push-ebp + 9202 89/<- %ebp 4/r32/esp + 9203 # (eax..ecx) = "a$" + 9204 b8/copy-to-eax "a$"/imm32 + 9205 8b/-> *eax 1/r32/ecx + 9206 8d/copy-address *(eax+ecx+4) 1/r32/ecx + 9207 05/add-to-eax 4/imm32 + 9208 # var slice/ecx: slice = {eax, ecx} + 9209 51/push-ecx + 9210 50/push-eax + 9211 89/<- %ecx 4/r32/esp + 9212 # + 9213 (is-identifier? %ecx) + 9214 (check-ints-equal %eax 1 "F - test-is-identifier-a") + 9215 # . epilogue + 9216 89/<- %esp 5/r32/ebp + 9217 5d/pop-to-ebp + 9218 c3/return + 9219 + 9220 test-is-identifier-z: + 9221 # . prologue + 9222 55/push-ebp + 9223 89/<- %ebp 4/r32/esp + 9224 # (eax..ecx) = "z$" + 9225 b8/copy-to-eax "z$"/imm32 + 9226 8b/-> *eax 1/r32/ecx + 9227 8d/copy-address *(eax+ecx+4) 1/r32/ecx + 9228 05/add-to-eax 4/imm32 + 9229 # var slice/ecx: slice = {eax, ecx} + 9230 51/push-ecx + 9231 50/push-eax + 9232 89/<- %ecx 4/r32/esp + 9233 # + 9234 (is-identifier? %ecx) + 9235 (check-ints-equal %eax 1 "F - test-is-identifier-z") + 9236 # . epilogue + 9237 89/<- %esp 5/r32/ebp + 9238 5d/pop-to-ebp + 9239 c3/return + 9240 + 9241 test-is-identifier-A: + 9242 # . prologue + 9243 55/push-ebp + 9244 89/<- %ebp 4/r32/esp + 9245 # (eax..ecx) = "A$" + 9246 b8/copy-to-eax "A$"/imm32 + 9247 8b/-> *eax 1/r32/ecx + 9248 8d/copy-address *(eax+ecx+4) 1/r32/ecx + 9249 05/add-to-eax 4/imm32 + 9250 # var slice/ecx: slice = {eax, ecx} + 9251 51/push-ecx + 9252 50/push-eax + 9253 89/<- %ecx 4/r32/esp + 9254 # + 9255 (is-identifier? %ecx) + 9256 (check-ints-equal %eax 1 "F - test-is-identifier-A") + 9257 # . epilogue + 9258 89/<- %esp 5/r32/ebp + 9259 5d/pop-to-ebp + 9260 c3/return + 9261 + 9262 test-is-identifier-Z: + 9263 # . prologue + 9264 55/push-ebp + 9265 89/<- %ebp 4/r32/esp + 9266 # (eax..ecx) = "Z$" + 9267 b8/copy-to-eax "Z$"/imm32 + 9268 8b/-> *eax 1/r32/ecx + 9269 8d/copy-address *(eax+ecx+4) 1/r32/ecx + 9270 05/add-to-eax 4/imm32 + 9271 # var slice/ecx: slice = {eax, ecx} + 9272 51/push-ecx + 9273 50/push-eax + 9274 89/<- %ecx 4/r32/esp + 9275 # + 9276 (is-identifier? %ecx) + 9277 (check-ints-equal %eax 1 "F - test-is-identifier-Z") + 9278 # . epilogue + 9279 89/<- %esp 5/r32/ebp + 9280 5d/pop-to-ebp + 9281 c3/return + 9282 + 9283 test-is-identifier-at: + 9284 # character before 'A' is invalid + 9285 # . prologue + 9286 55/push-ebp + 9287 89/<- %ebp 4/r32/esp + 9288 # (eax..ecx) = "@a" + 9289 b8/copy-to-eax "@a"/imm32 + 9290 8b/-> *eax 1/r32/ecx + 9291 8d/copy-address *(eax+ecx+4) 1/r32/ecx + 9292 05/add-to-eax 4/imm32 + 9293 # var slice/ecx: slice = {eax, ecx} + 9294 51/push-ecx + 9295 50/push-eax + 9296 89/<- %ecx 4/r32/esp + 9297 # + 9298 (is-identifier? %ecx) + 9299 (check-ints-equal %eax 0 "F - test-is-identifier-@") + 9300 # . epilogue + 9301 89/<- %esp 5/r32/ebp + 9302 5d/pop-to-ebp + 9303 c3/return + 9304 + 9305 test-is-identifier-square-bracket: + 9306 # character after 'Z' is invalid + 9307 # . prologue + 9308 55/push-ebp + 9309 89/<- %ebp 4/r32/esp + 9310 # (eax..ecx) = "[a" + 9311 b8/copy-to-eax "[a"/imm32 + 9312 8b/-> *eax 1/r32/ecx + 9313 8d/copy-address *(eax+ecx+4) 1/r32/ecx + 9314 05/add-to-eax 4/imm32 + 9315 # var slice/ecx: slice = {eax, ecx} + 9316 51/push-ecx + 9317 50/push-eax + 9318 89/<- %ecx 4/r32/esp + 9319 # + 9320 (is-identifier? %ecx) + 9321 (check-ints-equal %eax 0 "F - test-is-identifier-@") + 9322 # . epilogue + 9323 89/<- %esp 5/r32/ebp + 9324 5d/pop-to-ebp + 9325 c3/return + 9326 + 9327 test-is-identifier-backtick: + 9328 # character before 'a' is invalid + 9329 # . prologue + 9330 55/push-ebp + 9331 89/<- %ebp 4/r32/esp + 9332 # (eax..ecx) = "`a" + 9333 b8/copy-to-eax "`a"/imm32 + 9334 8b/-> *eax 1/r32/ecx + 9335 8d/copy-address *(eax+ecx+4) 1/r32/ecx + 9336 05/add-to-eax 4/imm32 + 9337 # var slice/ecx: slice = {eax, ecx} + 9338 51/push-ecx + 9339 50/push-eax + 9340 89/<- %ecx 4/r32/esp + 9341 # + 9342 (is-identifier? %ecx) + 9343 (check-ints-equal %eax 0 "F - test-is-identifier-backtick") + 9344 # . epilogue + 9345 89/<- %esp 5/r32/ebp + 9346 5d/pop-to-ebp + 9347 c3/return + 9348 + 9349 test-is-identifier-curly-brace-open: + 9350 # character after 'z' is invalid; also used for blocks + 9351 # . prologue + 9352 55/push-ebp + 9353 89/<- %ebp 4/r32/esp + 9354 # (eax..ecx) = "{a" + 9355 b8/copy-to-eax "{a"/imm32 + 9356 8b/-> *eax 1/r32/ecx + 9357 8d/copy-address *(eax+ecx+4) 1/r32/ecx + 9358 05/add-to-eax 4/imm32 + 9359 # var slice/ecx: slice = {eax, ecx} + 9360 51/push-ecx + 9361 50/push-eax + 9362 89/<- %ecx 4/r32/esp + 9363 # + 9364 (is-identifier? %ecx) + 9365 (check-ints-equal %eax 0 "F - test-is-identifier-curly-brace-open") + 9366 # . epilogue + 9367 89/<- %esp 5/r32/ebp + 9368 5d/pop-to-ebp + 9369 c3/return + 9370 + 9371 test-is-identifier-curly-brace-close: + 9372 # . prologue + 9373 55/push-ebp + 9374 89/<- %ebp 4/r32/esp + 9375 # (eax..ecx) = "}a" + 9376 b8/copy-to-eax "}a"/imm32 + 9377 8b/-> *eax 1/r32/ecx + 9378 8d/copy-address *(eax+ecx+4) 1/r32/ecx + 9379 05/add-to-eax 4/imm32 + 9380 # var slice/ecx: slice = {eax, ecx} + 9381 51/push-ecx + 9382 50/push-eax + 9383 89/<- %ecx 4/r32/esp + 9384 # + 9385 (is-identifier? %ecx) + 9386 (check-ints-equal %eax 0 "F - test-is-identifier-curly-brace-close") + 9387 # . epilogue + 9388 89/<- %esp 5/r32/ebp + 9389 5d/pop-to-ebp + 9390 c3/return + 9391 + 9392 test-is-identifier-hyphen: + 9393 # disallow leading '-' since '->' has special meaning + 9394 # . prologue + 9395 55/push-ebp + 9396 89/<- %ebp 4/r32/esp + 9397 # (eax..ecx) = "-a" + 9398 b8/copy-to-eax "-a"/imm32 + 9399 8b/-> *eax 1/r32/ecx + 9400 8d/copy-address *(eax+ecx+4) 1/r32/ecx + 9401 05/add-to-eax 4/imm32 + 9402 # var slice/ecx: slice = {eax, ecx} + 9403 51/push-ecx + 9404 50/push-eax + 9405 89/<- %ecx 4/r32/esp + 9406 # + 9407 (is-identifier? %ecx) + 9408 (check-ints-equal %eax 0 "F - test-is-identifier-hyphen") + 9409 # . epilogue + 9410 89/<- %esp 5/r32/ebp + 9411 5d/pop-to-ebp + 9412 c3/return + 9413 + 9414 populate-mu-function-body: # in: (addr buffered-file), out: (addr function), vars: (addr stack live-var), err: (addr buffered-file), ed: (addr exit-descriptor) + 9415 # . prologue + 9416 55/push-ebp + 9417 89/<- %ebp 4/r32/esp + 9418 # . save registers + 9419 50/push-eax + 9420 56/push-esi + 9421 57/push-edi + 9422 # esi = in + 9423 8b/-> *(ebp+8) 6/r32/esi + 9424 # edi = out + 9425 8b/-> *(ebp+0xc) 7/r32/edi + 9426 # initialize some global state + 9427 c7 0/subop/copy *Curr-block-depth 1/imm32 + 9428 # parse-mu-block(in, vars, out, out->body) + 9429 8d/copy-address *(edi+0x18) 0/r32/eax # Function-body + 9430 (parse-mu-block %esi *(ebp+0x10) %edi %eax *(ebp+0x14) *(ebp+0x18)) + 9431 $populate-mu-function-body:end: + 9432 # . restore registers + 9433 5f/pop-to-edi + 9434 5e/pop-to-esi + 9435 58/pop-to-eax + 9436 # . epilogue + 9437 89/<- %esp 5/r32/ebp + 9438 5d/pop-to-ebp + 9439 c3/return + 9440 + 9441 # parses a block, assuming that the leading '{' has already been read by the caller + 9442 parse-mu-block: # in: (addr buffered-file), vars: (addr stack live-var), fn: (addr function), out: (addr handle block), err: (addr buffered-file), ed: (addr exit-descriptor) + 9443 # pseudocode: + 9444 # var line: (stream byte 512) + 9445 # var word-slice: slice + 9446 # allocate(Heap, Stmt-size, out) + 9447 # var out-addr: (addr block) = lookup(*out) + 9448 # out-addr->tag = 0/block + 9449 # out-addr->var = some unique name + 9450 # push(vars, {out-addr->var, false}) + 9451 # while true # line loop + 9452 # clear-stream(line) + 9453 # read-line-buffered(in, line) + 9454 # if (line->write == 0) break # end of file + 9455 # word-slice = next-mu-token(line) + 9456 # if slice-empty?(word-slice) # end of line + 9457 # continue + 9458 # else if slice-starts-with?(word-slice, "#") + 9459 # continue + 9460 # else if slice-equal?(word-slice, "{") + 9461 # assert(no-tokens-in(line)) + 9462 # block = parse-mu-block(in, vars, fn) + 9463 # append-to-block(out-addr, block) + 9464 # else if slice-equal?(word-slice, "}") + 9465 # break + 9466 # else if slice-ends-with?(word-slice, ":") + 9467 # # TODO: error-check the rest of 'line' + 9468 # --word-slice->end to skip ':' + 9469 # named-block = parse-mu-named-block(word-slice, in, vars, fn) + 9470 # append-to-block(out-addr, named-block) + 9471 # else if slice-equal?(word-slice, "var") + 9472 # var-def = parse-mu-var-def(line, vars, fn) + 9473 # append-to-block(out-addr, var-def) + 9474 # else + 9475 # stmt = parse-mu-stmt(line, vars, fn) + 9476 # append-to-block(out-addr, stmt) + 9477 # pop(vars) + 9478 # + 9479 # . prologue + 9480 55/push-ebp + 9481 89/<- %ebp 4/r32/esp + 9482 # . save registers + 9483 50/push-eax + 9484 51/push-ecx + 9485 52/push-edx + 9486 53/push-ebx + 9487 57/push-edi + 9488 # var line/ecx: (stream byte 512) + 9489 81 5/subop/subtract %esp 0x200/imm32 + 9490 68/push 0x200/imm32/size + 9491 68/push 0/imm32/read + 9492 68/push 0/imm32/write + 9493 89/<- %ecx 4/r32/esp + 9494 # var word-slice/edx: slice + 9495 68/push 0/imm32/end + 9496 68/push 0/imm32/start + 9497 89/<- %edx 4/r32/esp + 9498 # allocate into out + 9499 (allocate Heap *Stmt-size *(ebp+0x14)) + 9500 # var out-addr/edi: (addr block) = lookup(*out) + 9501 8b/-> *(ebp+0x14) 7/r32/edi + 9502 (lookup *edi *(edi+4)) # => eax + 9503 89/<- %edi 0/r32/eax + 9504 # out-addr->tag is 0 (block) by default + 9505 # set out-addr->var + 9506 8d/copy-address *(edi+0xc) 0/r32/eax # Block-var + 9507 (new-block-name *(ebp+0x10) %eax) + 9508 # push(vars, out-addr->var) + 9509 (push *(ebp+0xc) *(edi+0xc)) # Block-var + 9510 (push *(ebp+0xc) *(edi+0x10)) # Block-var + 9511 (push *(ebp+0xc) 0) # false + 9512 # increment *Curr-block-depth + 9513 ff 0/subop/increment *Curr-block-depth + 9514 { + 9515 $parse-mu-block:line-loop: + 9516 # line = read-line-buffered(in) + 9517 (clear-stream %ecx) + 9518 (read-line-buffered *(ebp+8) %ecx) + 9519 #? (write-buffered Stderr "line: ") + 9520 #? (write-stream-data Stderr %ecx) + 9521 #? #? (write-buffered Stderr Newline) # line has its own newline + 9522 #? (flush Stderr) + 9523 #? (rewind-stream %ecx) + 9524 # if (line->write == 0) break + 9525 81 7/subop/compare *ecx 0/imm32 + 9526 0f 84/jump-if-= break/disp32 + 9527 #? (write-buffered Stderr "vars:\n") + 9528 #? (dump-vars *(ebp+0xc)) + 9529 # word-slice = next-mu-token(line) + 9530 (next-mu-token %ecx %edx) + 9531 #? (write-buffered Stderr "word: ") + 9532 #? (write-slice-buffered Stderr %edx) + 9533 #? (write-buffered Stderr Newline) + 9534 #? (flush Stderr) + 9535 # if slice-empty?(word-slice) continue + 9536 (slice-empty? %edx) + 9537 3d/compare-eax-and 0/imm32/false + 9538 0f 85/jump-if-!= loop/disp32 + 9539 # if (slice-starts-with?(word-slice, '#') continue + 9540 # . eax = *word-slice->start + 9541 8b/-> *edx 0/r32/eax + 9542 8a/copy-byte *eax 0/r32/AL + 9543 81 4/subop/and %eax 0xff/imm32 + 9544 # . if (eax == '#') continue + 9545 3d/compare-eax-and 0x23/imm32/hash + 9546 0f 84/jump-if-= loop/disp32 + 9547 # if slice-equal?(word-slice, "{") + 9548 { + 9549 $parse-mu-block:check-for-block: + 9550 (slice-equal? %edx "{") + 9551 3d/compare-eax-and 0/imm32/false + 9552 74/jump-if-= break/disp8 + 9553 (check-no-tokens-left %ecx) + 9554 # parse new block and append + 9555 # . var tmp/eax: (handle block) + 9556 68/push 0/imm32 + 9557 68/push 0/imm32 + 9558 89/<- %eax 4/r32/esp + 9559 # . + 9560 (parse-mu-block *(ebp+8) *(ebp+0xc) *(ebp+0x10) %eax *(ebp+0x18) *(ebp+0x1c)) + 9561 (append-to-block Heap %edi *eax *(eax+4)) + 9562 # . reclaim tmp + 9563 81 0/subop/add %esp 8/imm32 + 9564 # . + 9565 e9/jump $parse-mu-block:line-loop/disp32 + 9566 } + 9567 # if slice-equal?(word-slice, "}") break + 9568 $parse-mu-block:check-for-end: + 9569 (slice-equal? %edx "}") + 9570 3d/compare-eax-and 0/imm32/false + 9571 0f 85/jump-if-!= break/disp32 + 9572 # if slice-ends-with?(word-slice, ":") parse named block and append + 9573 { + 9574 $parse-mu-block:check-for-named-block: + 9575 # . eax = *(word-slice->end-1) + 9576 8b/-> *(edx+4) 0/r32/eax + 9577 48/decrement-eax + 9578 8a/copy-byte *eax 0/r32/AL + 9579 81 4/subop/and %eax 0xff/imm32 + 9580 # . if (eax != ':') break + 9581 3d/compare-eax-and 0x3a/imm32/colon + 9582 0f 85/jump-if-!= break/disp32 + 9583 # TODO: error-check the rest of 'line' + 9584 # + 9585 # skip ':' + 9586 ff 1/subop/decrement *(edx+4) # Slice-end + 9587 # var tmp/eax: (handle block) + 9588 68/push 0/imm32 + 9589 68/push 0/imm32 + 9590 89/<- %eax 4/r32/esp + 9591 # + 9592 (parse-mu-named-block %edx *(ebp+8) *(ebp+0xc) *(ebp+0x10) %eax *(ebp+0x18) *(ebp+0x1c)) + 9593 (append-to-block Heap %edi *eax *(eax+4)) + 9594 # reclaim tmp + 9595 81 0/subop/add %esp 8/imm32 + 9596 # + 9597 e9/jump $parse-mu-block:line-loop/disp32 + 9598 } + 9599 # if slice-equal?(word-slice, "var") + 9600 { + 9601 $parse-mu-block:check-for-var: + 9602 (slice-equal? %edx "var") + 9603 3d/compare-eax-and 0/imm32/false + 9604 74/jump-if-= break/disp8 + 9605 # var tmp/eax: (handle block) + 9606 68/push 0/imm32 + 9607 68/push 0/imm32 + 9608 89/<- %eax 4/r32/esp + 9609 # + 9610 (parse-mu-var-def %ecx *(ebp+0xc) %eax *(ebp+0x10) *(ebp+0x18) *(ebp+0x1c)) + 9611 (append-to-block Heap %edi *eax *(eax+4)) + 9612 # reclaim tmp + 9613 81 0/subop/add %esp 8/imm32 + 9614 # + 9615 e9/jump $parse-mu-block:line-loop/disp32 + 9616 } + 9617 $parse-mu-block:regular-stmt: + 9618 # otherwise + 9619 # var tmp/eax: (handle block) + 9620 68/push 0/imm32 + 9621 68/push 0/imm32 + 9622 89/<- %eax 4/r32/esp + 9623 # + 9624 (parse-mu-stmt %ecx *(ebp+0xc) *(ebp+0x10) %eax *(ebp+0x18) *(ebp+0x1c)) + 9625 (append-to-block Heap %edi *eax *(eax+4)) + 9626 # reclaim tmp + 9627 81 0/subop/add %esp 8/imm32 + 9628 # + 9629 e9/jump loop/disp32 + 9630 } # end line loop + 9631 (clean-up-blocks *(ebp+0xc) *Curr-block-depth *(ebp+0x10)) + 9632 # decrement *Curr-block-depth + 9633 ff 1/subop/decrement *Curr-block-depth + 9634 # pop(vars) + 9635 (pop *(ebp+0xc)) # => eax + 9636 (pop *(ebp+0xc)) # => eax + 9637 (pop *(ebp+0xc)) # => eax + 9638 $parse-mu-block:end: + 9639 # . reclaim locals + 9640 81 0/subop/add %esp 0x214/imm32 + 9641 # . restore registers + 9642 5f/pop-to-edi + 9643 5b/pop-to-ebx + 9644 5a/pop-to-edx + 9645 59/pop-to-ecx + 9646 58/pop-to-eax + 9647 # . epilogue + 9648 89/<- %esp 5/r32/ebp + 9649 5d/pop-to-ebp + 9650 c3/return + 9651 + 9652 $parse-mu-block:abort: + 9653 # error("'{' or '}' should be on its own line, but got '") + 9654 (write-buffered *(ebp+0x18) "'{' or '}' should be on its own line, but got '") + 9655 (rewind-stream %ecx) + 9656 (write-stream-data *(ebp+0x18) %ecx) + 9657 (write-buffered *(ebp+0x18) "'\n") + 9658 (flush *(ebp+0x18)) + 9659 (stop *(ebp+0x1c) 1) + 9660 # never gets here + 9661 + 9662 new-block-name: # fn: (addr function), out: (addr handle var) + 9663 # . prologue + 9664 55/push-ebp + 9665 89/<- %ebp 4/r32/esp + 9666 # . save registers + 9667 50/push-eax + 9668 51/push-ecx + 9669 52/push-edx + 9670 # var n/ecx: int = len(fn->name) + 10 for an int + 2 for '$:' + 9671 8b/-> *(ebp+8) 0/r32/eax + 9672 (lookup *eax *(eax+4)) # Function-name Function-name => eax + 9673 8b/-> *eax 0/r32/eax # String-size + 9674 05/add-to-eax 0xd/imm32 # 10 + 2 for '$:' + 9675 89/<- %ecx 0/r32/eax + 9676 # var name/edx: (stream byte n) + 9677 29/subtract-from %esp 1/r32/ecx + 9678 ff 6/subop/push %ecx + 9679 68/push 0/imm32/read + 9680 68/push 0/imm32/write + 9681 89/<- %edx 4/r32/esp + 9682 (clear-stream %edx) + 9683 # eax = fn->name + 9684 8b/-> *(ebp+8) 0/r32/eax + 9685 (lookup *eax *(eax+4)) # Function-name Function-name => eax + 9686 # construct result using Next-block-index (and increment it) + 9687 (write %edx "$") + 9688 (write %edx %eax) + 9689 (write %edx ":") + 9690 (write-int32-hex %edx *Next-block-index) + 9691 ff 0/subop/increment *Next-block-index + 9692 # var s/eax: slice = {name->data, name->data + name->write} (clobbering edx) + 9693 # . eax = name->write + 9694 8b/-> *edx 0/r32/eax + 9695 # . edx = name->data + 9696 8d/copy-address *(edx+0xc) 2/r32/edx + 9697 # . eax = name->write + name->data + 9698 01/add-to %eax 2/r32/edx + 9699 # . push {edx, eax} + 9700 ff 6/subop/push %eax + 9701 ff 6/subop/push %edx + 9702 89/<- %eax 4/r32/esp + 9703 # out = new literal(s) + 9704 (new-literal Heap %eax *(ebp+0xc)) + 9705 #? 8b/-> *(ebp+0xc) 0/r32/eax + 9706 #? (write-buffered Stderr "type allocid in caller after new-literal: ") + 9707 #? (write-int32-hex-buffered Stderr *(eax+8)) + 9708 #? (write-buffered Stderr " for var ") + 9709 #? (write-int32-hex-buffered Stderr %eax) + 9710 #? (write-buffered Stderr Newline) + 9711 #? (flush Stderr) + 9712 $new-block-name:end: + 9713 # . reclaim locals + 9714 81 0/subop/add %ecx 0xc/imm32 # name.{read/write/len} + 9715 81 0/subop/add %ecx 8/imm32 # slice + 9716 01/add-to %esp 1/r32/ecx + 9717 # . restore registers + 9718 5a/pop-to-edx + 9719 59/pop-to-ecx + 9720 58/pop-to-eax + 9721 # . epilogue + 9722 89/<- %esp 5/r32/ebp + 9723 5d/pop-to-ebp + 9724 c3/return + 9725 + 9726 check-no-tokens-left: # line: (addr stream byte) + 9727 # . prologue + 9728 55/push-ebp + 9729 89/<- %ebp 4/r32/esp + 9730 # . save registers + 9731 50/push-eax + 9732 51/push-ecx + 9733 # var s/ecx: slice + 9734 68/push 0/imm32/end + 9735 68/push 0/imm32/start + 9736 89/<- %ecx 4/r32/esp + 9737 # + 9738 (next-mu-token *(ebp+8) %ecx) + 9739 # if slice-empty?(s) return + 9740 (slice-empty? %ecx) + 9741 3d/compare-eax-and 0/imm32/false + 9742 75/jump-if-!= $check-no-tokens-left:end/disp8 + 9743 # if (slice-starts-with?(s, '#') return + 9744 # . eax = *s->start + 9745 8b/-> *edx 0/r32/eax + 9746 8a/copy-byte *eax 0/r32/AL + 9747 81 4/subop/and %eax 0xff/imm32 + 9748 # . if (eax == '#') continue + 9749 3d/compare-eax-and 0x23/imm32/hash + 9750 74/jump-if-= $check-no-tokens-left:end/disp8 + 9751 # abort + 9752 (write-buffered Stderr "'{' or '}' should be on its own line, but got '") + 9753 (rewind-stream %ecx) + 9754 (write-stream 2 %ecx) + 9755 (write-buffered Stderr "'\n") + 9756 (flush Stderr) + 9757 # . syscall(exit, 1) + 9758 bb/copy-to-ebx 1/imm32 + 9759 e8/call syscall_exit/disp32 + 9760 # never gets here + 9761 $check-no-tokens-left:end: + 9762 # . reclaim locals + 9763 81 0/subop/add %esp 8/imm32 + 9764 # . restore registers + 9765 59/pop-to-ecx + 9766 58/pop-to-eax + 9767 # . epilogue + 9768 89/<- %esp 5/r32/ebp + 9769 5d/pop-to-ebp + 9770 c3/return + 9771 + 9772 parse-mu-named-block: # name: (addr slice), in: (addr buffered-file), vars: (addr stack live-var), fn: (addr function), out: (addr handle stmt), err: (addr buffered-file), ed: (addr exit-descriptor) + 9773 # pseudocode: + 9774 # var v: (handle var) + 9775 # new-literal(name, v) + 9776 # push(vars, {v, false}) + 9777 # parse-mu-block(in, vars, fn, out) + 9778 # pop(vars) + 9779 # out->tag = block + 9780 # out->var = v + 9781 # + 9782 # . prologue + 9783 55/push-ebp + 9784 89/<- %ebp 4/r32/esp + 9785 # . save registers + 9786 50/push-eax + 9787 51/push-ecx + 9788 57/push-edi + 9789 # var v/ecx: (handle var) + 9790 68/push 0/imm32 + 9791 68/push 0/imm32 + 9792 89/<- %ecx 4/r32/esp + 9793 # + 9794 (new-literal Heap *(ebp+8) %ecx) + 9795 # push(vars, v) + 9796 (push *(ebp+0x10) *ecx) + 9797 (push *(ebp+0x10) *(ecx+4)) + 9798 (push *(ebp+0x10) 0) # false + 9799 # + 9800 (parse-mu-block *(ebp+0xc) *(ebp+0x10) *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c) *(ebp+0x20)) + 9801 # pop v off vars + 9802 (pop *(ebp+0x10)) # => eax + 9803 (pop *(ebp+0x10)) # => eax + 9804 (pop *(ebp+0x10)) # => eax + 9805 # var out-addr/edi: (addr stmt) = lookup(*out) + 9806 8b/-> *(ebp+0x18) 7/r32/edi + 9807 (lookup *edi *(edi+4)) # => eax + 9808 89/<- %edi 0/r32/eax + 9809 # out-addr->tag = named-block + 9810 c7 0/subop/copy *edi 0/imm32/block # Stmt-tag + 9811 # out-addr->var = v + 9812 8b/-> *ecx 0/r32/eax + 9813 89/<- *(edi+0xc) 0/r32/eax # Block-var + 9814 8b/-> *(ecx+4) 0/r32/eax + 9815 89/<- *(edi+0x10) 0/r32/eax # Block-var + 9816 $parse-mu-named-block:end: + 9817 # . reclaim locals + 9818 81 0/subop/add %esp 8/imm32 + 9819 # . restore registers + 9820 5f/pop-to-edi + 9821 59/pop-to-ecx + 9822 58/pop-to-eax + 9823 # . epilogue + 9824 89/<- %esp 5/r32/ebp + 9825 5d/pop-to-ebp + 9826 c3/return + 9827 + 9828 parse-mu-var-def: # line: (addr stream byte), vars: (addr stack live-var), out: (addr handle stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) + 9829 # . prologue + 9830 55/push-ebp + 9831 89/<- %ebp 4/r32/esp + 9832 # . save registers + 9833 50/push-eax + 9834 51/push-ecx + 9835 52/push-edx + 9836 53/push-ebx + 9837 57/push-edi + 9838 # edi = out + 9839 8b/-> *(ebp+0x10) 7/r32/edi + 9840 # var word-slice/ecx: slice + 9841 68/push 0/imm32/end + 9842 68/push 0/imm32/start + 9843 89/<- %ecx 4/r32/esp + 9844 # var v/edx: (handle var) + 9845 68/push 0/imm32 + 9846 68/push 0/imm32 + 9847 89/<- %edx 4/r32/esp + 9848 # v = parse-var-with-type(next-mu-token(line)) + 9849 (next-mu-token *(ebp+8) %ecx) + 9850 (parse-var-with-type %ecx *(ebp+8) %edx *(ebp+0x18) *(ebp+0x1c)) + 9851 # var v-addr/eax: (addr var) + 9852 (lookup *edx *(edx+4)) # => eax + 9853 # v->block-depth = *Curr-block-depth + 9854 8b/-> *Curr-block-depth 3/r32/ebx + 9855 89/<- *(eax+0x10) 3/r32/ebx # Var-block-depth + 9856 # either v has no register and there's no more to this line + 9857 8b/-> *(eax+0x18) 0/r32/eax # Var-register + 9858 3d/compare-eax-and 0/imm32 + 9859 { + 9860 75/jump-if-!= break/disp8 + 9861 # TODO: disallow vars of type 'byte' on the stack + 9862 # ensure that there's nothing else on this line + 9863 (next-mu-token *(ebp+8) %ecx) + 9864 (slice-empty? %ecx) # => eax + 9865 3d/compare-eax-and 0/imm32/false + 9866 0f 84/jump-if-= $parse-mu-var-def:error2/disp32 + 9867 # + 9868 (new-var-def Heap *edx *(edx+4) %edi) + 9869 e9/jump $parse-mu-var-def:update-vars/disp32 + 9870 } + 9871 # or v has a register and there's more to this line + 9872 { + 9873 0f 84/jump-if-= break/disp32 + 9874 # TODO: disallow vars of type 'byte' in registers 'esi' or 'edi' + 9875 # TODO: vars of type 'byte' should only be initialized by clearing to 0 + 9876 # ensure that the next word is '<-' + 9877 (next-mu-token *(ebp+8) %ecx) + 9878 (slice-equal? %ecx "<-") # => eax + 9879 3d/compare-eax-and 0/imm32/false + 9880 0f 84/jump-if-= $parse-mu-var-def:error1/disp32 + 9881 # + 9882 (new-reg-var-def Heap *edx *(edx+4) %edi) + 9883 (lookup *edi *(edi+4)) # => eax + 9884 (add-operation-and-inputs-to-stmt %eax *(ebp+8) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c)) + 9885 } + 9886 $parse-mu-var-def:update-vars: + 9887 # push 'v' at end of function + 9888 (push *(ebp+0xc) *edx) + 9889 (push *(ebp+0xc) *(edx+4)) + 9890 (push *(ebp+0xc) 0) # Live-var-register-spilled is unused during parsing + 9891 $parse-mu-var-def:end: + 9892 # . reclaim locals + 9893 81 0/subop/add %esp 0x10/imm32 + 9894 # . restore registers + 9895 5f/pop-to-edi + 9896 5b/pop-to-ebx + 9897 5a/pop-to-edx + 9898 59/pop-to-ecx + 9899 58/pop-to-eax + 9900 # . epilogue + 9901 89/<- %esp 5/r32/ebp + 9902 5d/pop-to-ebp + 9903 c3/return + 9904 + 9905 $parse-mu-var-def:error1: + 9906 (rewind-stream *(ebp+8)) + 9907 # error("register variable requires a valid instruction to initialize but got '" line "'\n") + 9908 (write-buffered *(ebp+0x18) "register variable requires a valid instruction to initialize but got '") + 9909 (flush *(ebp+0x18)) + 9910 (write-stream-data *(ebp+0x18) *(ebp+8)) + 9911 (write-buffered *(ebp+0x18) "'\n") + 9912 (flush *(ebp+0x18)) + 9913 (stop *(ebp+0x1c) 1) + 9914 # never gets here + 9915 + 9916 $parse-mu-var-def:error2: + 9917 (rewind-stream *(ebp+8)) + 9918 # error("fn " fn ": var " var ": variables on the stack can't take an initializer\n") + 9919 (write-buffered *(ebp+0x18) "fn ") + 9920 8b/-> *(ebp+0x14) 0/r32/eax + 9921 (lookup *eax *(eax+4)) # Function-name Function-name => eax + 9922 (write-buffered *(ebp+0x18) %eax) + 9923 (write-buffered *(ebp+0x18) ": var ") + 9924 # var v-addr/eax: (addr var) = lookup(v) + 9925 (lookup *edx *(edx+4)) # => eax + 9926 (lookup *eax *(eax+4)) # Var-name Var-name => eax + 9927 (write-buffered *(ebp+0x18) %eax) + 9928 (write-buffered *(ebp+0x18) ": variables on the stack can't take an initializer\n") + 9929 (flush *(ebp+0x18)) + 9930 (stop *(ebp+0x1c) 1) + 9931 # never gets here + 9932 + 9933 test-parse-mu-var-def: + 9934 # 'var n: int' + 9935 # . prologue + 9936 55/push-ebp + 9937 89/<- %ebp 4/r32/esp + 9938 # setup + 9939 (clear-stream _test-input-stream) + 9940 (write _test-input-stream "n: int\n") # caller has consumed the 'var' + 9941 c7 0/subop/copy *Curr-block-depth 1/imm32 + 9942 # var out/esi: (handle stmt) + 9943 68/push 0/imm32 + 9944 68/push 0/imm32 + 9945 89/<- %esi 4/r32/esp + 9946 # var vars/ecx: (stack (addr var) 16) + 9947 81 5/subop/subtract %esp 0xc0/imm32 + 9948 68/push 0xc0/imm32/size + 9949 68/push 0/imm32/top + 9950 89/<- %ecx 4/r32/esp + 9951 (clear-stack %ecx) + 9952 # convert + 9953 (parse-mu-var-def _test-input-stream %ecx %esi 0 Stderr 0) + 9954 # var out-addr/esi: (addr stmt) + 9955 (lookup *esi *(esi+4)) # => eax + 9956 89/<- %esi 0/r32/eax + 9957 # + 9958 (check-ints-equal *esi 2 "F - test-parse-mu-var-def/tag") # Stmt-tag is var-def + 9959 # var v/ecx: (addr var) = lookup(out->var) + 9960 (lookup *(esi+4) *(esi+8)) # Vardef-var Vardef-var => eax + 9961 89/<- %ecx 0/r32/eax + 9962 # v->name + 9963 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax + 9964 (check-strings-equal %eax "n" "F - test-parse-mu-var-def/var-name") + 9965 # v->register + 9966 (check-ints-equal *(ecx+0x18) 0 "F - test-parse-mu-var-def/var-register") # Var-register + 9967 # v->block-depth + 9968 (check-ints-equal *(ecx+0x10) 1 "F - test-parse-mu-var-def/output-block-depth") # Var-block-depth + 9969 # v->type == int + 9970 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax + 9971 (check-ints-equal *eax 1 "F - test-parse-mu-var-def/var-type:0") # Type-tree-is-atom + 9972 (check-ints-equal *(eax+4) 1 "F - test-parse-mu-var-def/var-type:1") # Type-tree-value + 9973 (check-ints-equal *(eax+0xc) 0 "F - test-parse-mu-var-def/var-type:2") # Type-tree-right + 9974 # . epilogue + 9975 89/<- %esp 5/r32/ebp + 9976 5d/pop-to-ebp + 9977 c3/return + 9978 + 9979 test-parse-mu-reg-var-def: + 9980 # 'var n/eax: int <- copy 0' + 9981 # . prologue + 9982 55/push-ebp + 9983 89/<- %ebp 4/r32/esp + 9984 # setup + 9985 (clear-stream _test-input-stream) + 9986 (write _test-input-stream "n/eax: int <- copy 0\n") # caller has consumed the 'var' + 9987 c7 0/subop/copy *Curr-block-depth 1/imm32 + 9988 # var out/esi: (handle stmt) 9989 68/push 0/imm32 - 9990 89/<- %edx 4/r32/esp - 9991 # var s/eax: (handle array byte) - 9992 68/push 0/imm32 - 9993 68/push 0/imm32 - 9994 89/<- %eax 4/r32/esp - 9995 # v = new var("n") - 9996 (copy-array Heap "n" %eax) - 9997 (new-var Heap *eax *(eax+4) %edx) - 9998 # - 9999 (push %ecx *edx) -10000 (push %ecx *(edx+4)) -10001 (push %ecx 0) -10002 # var out/eax: (handle stmt) -10003 68/push 0/imm32 -10004 68/push 0/imm32 -10005 89/<- %eax 4/r32/esp -10006 # convert -10007 (parse-mu-stmt _test-input-stream %ecx 0 %eax Stderr 0) -10008 # var out-addr/edx: (addr stmt) = lookup(*out) -10009 (lookup *eax *(eax+4)) # => eax -10010 89/<- %edx 0/r32/eax -10011 # out->tag -10012 (check-ints-equal *edx 1 "F - test-parse-mu-stmt/tag") # Stmt-tag is Stmt1 -10013 # out->operation -10014 (lookup *(edx+4) *(edx+8)) # Stmt1-operation Stmt1-operation => eax -10015 (check-strings-equal %eax "increment" "F - test-parse-mu-stmt/name") # Stmt1-operation -10016 # out->inouts->value->name -10017 # . eax = out->inouts -10018 (lookup *(edx+0xc) *(edx+0x10)) # Stmt1-inouts Stmt1-inouts => eax -10019 # . eax = out->inouts->value -10020 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -10021 # . eax = out->inouts->value->name -10022 (lookup *eax *(eax+4)) # Var-name Var-name => eax -10023 # . -10024 (check-strings-equal %eax "n" "F - test-parse-mu-stmt/inout:0") -10025 # . epilogue -10026 89/<- %esp 5/r32/ebp -10027 5d/pop-to-ebp -10028 c3/return -10029 -10030 test-parse-mu-stmt-with-comma: -10031 # . prologue -10032 55/push-ebp -10033 89/<- %ebp 4/r32/esp -10034 # setup -10035 (clear-stream _test-input-stream) -10036 (write _test-input-stream "copy-to n, 3\n") -10037 # var vars/ecx: (stack (addr var) 16) -10038 81 5/subop/subtract %esp 0xc0/imm32 -10039 68/push 0xc0/imm32/size -10040 68/push 0/imm32/top -10041 89/<- %ecx 4/r32/esp -10042 (clear-stack %ecx) -10043 # var v/edx: (handle var) -10044 68/push 0/imm32 -10045 68/push 0/imm32 -10046 89/<- %edx 4/r32/esp -10047 # var s/eax: (handle array byte) -10048 68/push 0/imm32 -10049 68/push 0/imm32 -10050 89/<- %eax 4/r32/esp -10051 # v = new var("n") -10052 (copy-array Heap "n" %eax) -10053 (new-var Heap *eax *(eax+4) %edx) -10054 # -10055 (push %ecx *edx) -10056 (push %ecx *(edx+4)) -10057 (push %ecx 0) -10058 # var out/eax: (handle stmt) -10059 68/push 0/imm32 -10060 68/push 0/imm32 -10061 89/<- %eax 4/r32/esp -10062 # convert -10063 (parse-mu-stmt _test-input-stream %ecx 0 %eax Stderr 0) -10064 # var out-addr/edx: (addr stmt) = lookup(*out) -10065 (lookup *eax *(eax+4)) # => eax -10066 89/<- %edx 0/r32/eax -10067 # out->tag -10068 (check-ints-equal *edx 1 "F - test-parse-mu-stmt-with-comma/tag") # Stmt-tag is Stmt1 -10069 # out->operation -10070 (lookup *(edx+4) *(edx+8)) # Stmt1-operation Stmt1-operation => eax -10071 (check-strings-equal %eax "copy-to" "F - test-parse-mu-stmt-with-comma/name") # Stmt1-operation -10072 # out->inouts->value->name -10073 # . eax = out->inouts -10074 (lookup *(edx+0xc) *(edx+0x10)) # Stmt1-inouts Stmt1-inouts => eax -10075 # . eax = out->inouts->value -10076 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -10077 # . eax = out->inouts->value->name -10078 (lookup *eax *(eax+4)) # Var-name Var-name => eax -10079 # . -10080 (check-strings-equal %eax "n" "F - test-parse-mu-stmt-with-comma/inout:0") -10081 # . epilogue -10082 89/<- %esp 5/r32/ebp -10083 5d/pop-to-ebp -10084 c3/return -10085 -10086 new-var: # ad: (addr allocation-descriptor), name: (handle array byte), out: (addr handle var) -10087 # . prologue -10088 55/push-ebp -10089 89/<- %ebp 4/r32/esp -10090 # . save registers -10091 50/push-eax -10092 51/push-ecx -10093 # ecx = out -10094 8b/-> *(ebp+0x14) 1/r32/ecx -10095 # -10096 (allocate *(ebp+8) *Var-size %ecx) -10097 # var out-addr/eax: (addr var) -10098 (lookup *ecx *(ecx+4)) # => eax -10099 # out-addr->name = name -10100 8b/-> *(ebp+0xc) 1/r32/ecx -10101 89/<- *eax 1/r32/ecx # Var-name -10102 8b/-> *(ebp+0x10) 1/r32/ecx -10103 89/<- *(eax+4) 1/r32/ecx # Var-name -10104 #? (write-buffered Stderr "var ") -10105 #? (lookup *(ebp+0xc) *(ebp+0x10)) -10106 #? (write-buffered Stderr %eax) -10107 #? (write-buffered Stderr " at ") -10108 #? 8b/-> *(ebp+0x14) 1/r32/ecx -10109 #? (lookup *ecx *(ecx+4)) # => eax -10110 #? (write-int32-hex-buffered Stderr %eax) -10111 #? (write-buffered Stderr Newline) -10112 #? (flush Stderr) -10113 $new-var:end: -10114 # . restore registers -10115 59/pop-to-ecx -10116 58/pop-to-eax -10117 # . epilogue -10118 89/<- %esp 5/r32/ebp -10119 5d/pop-to-ebp -10120 c3/return -10121 -10122 new-literal-integer: # ad: (addr allocation-descriptor), name: (addr slice), out: (addr handle var), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -10123 # . prologue -10124 55/push-ebp -10125 89/<- %ebp 4/r32/esp -10126 # . save registers -10127 50/push-eax -10128 51/push-ecx -10129 # if (!is-hex-int?(name)) abort -10130 (is-hex-int? *(ebp+0xc)) # => eax -10131 3d/compare-eax-and 0/imm32/false -10132 0f 84/jump-if-= $new-literal-integer:abort/disp32 -10133 # a little more error-checking -10134 (check-mu-hex-int *(ebp+0xc) *(ebp+0x18) *(ebp+0x1c)) -10135 # out = new var(s) -10136 (new-var-from-slice *(ebp+8) *(ebp+0xc) *(ebp+0x10)) -10137 # var out-addr/ecx: (addr var) = lookup(*out) -10138 8b/-> *(ebp+0x10) 0/r32/eax -10139 (lookup *eax *(eax+4)) # => eax -10140 89/<- %ecx 0/r32/eax -10141 # out-addr->block-depth = *Curr-block-depth -10142 8b/-> *Curr-block-depth 0/r32/eax -10143 89/<- *(ecx+0x10) 0/r32/eax # Var-block-depth -10144 # out-addr->type = new tree() -10145 8d/copy-address *(ecx+8) 0/r32/eax # Var-type -10146 (allocate *(ebp+8) *Type-tree-size %eax) -10147 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax -10148 c7 0/subop/copy *eax 1/imm32/true # Type-tree-is-atom -10149 # nothing else to do; default type is 'literal' -10150 $new-literal-integer:end: -10151 # . reclaim locals -10152 81 0/subop/add %esp 8/imm32 -10153 # . restore registers -10154 59/pop-to-ecx -10155 58/pop-to-eax -10156 # . epilogue -10157 89/<- %esp 5/r32/ebp -10158 5d/pop-to-ebp -10159 c3/return -10160 -10161 $new-literal-integer:abort: -10162 (write-buffered *(ebp+0x18) "fn ") -10163 8b/-> *(ebp+0x14) 0/r32/eax -10164 (lookup *eax *(eax+4)) # Function-name Function-name => eax -10165 (write-buffered *(ebp+0x18) %eax) -10166 (write-buffered *(ebp+0x18) ": variable '") -10167 (write-slice-buffered *(ebp+0x18) *(ebp+0xc)) -10168 (write-buffered *(ebp+0x18) "' cannot begin with a digit (or do you have a typo in a number?)\n") -10169 (flush *(ebp+0x18)) -10170 (stop *(ebp+0x1c) 1) -10171 # never gets here -10172 -10173 # precondition: name is a valid hex integer; require a '0x' prefix -10174 check-mu-hex-int: # name: (addr slice), err: (addr buffered-file), ed: (addr exit-descriptor) -10175 # . prologue -10176 55/push-ebp -10177 89/<- %ebp 4/r32/esp -10178 # . save registers -10179 50/push-eax -10180 51/push-ecx -10181 52/push-edx -10182 # -10183 8b/-> *(ebp+8) 1/r32/ecx -10184 # var start/ecx: (addr byte) = name->start -10185 8b/-> *(ecx+4) 2/r32/edx -10186 # var end/ecx: (addr byte) = name->end -10187 8b/-> *ecx 1/r32/ecx -10188 # var len/eax: int = name->end - name->start -10189 89/<- %eax 2/r32/edx -10190 29/subtract-from %eax 1/r32/ecx -10191 # if (len <= 1) return -10192 3d/compare-eax-with 1/imm32 -10193 0f 8e/jump-if-<= $check-mu-hex-int:end/disp32 -10194 $check-mu-hex-int:length->-1: -10195 # if slice-starts-with?("0x") return -10196 (slice-starts-with? *(ebp+8) "0x") # => eax -10197 3d/compare-eax-with 0/imm32/false -10198 75/jump-if-!= $check-mu-hex-int:end/disp8 -10199 $check-mu-hex-int:abort: -10200 # otherwise abort -10201 (write-buffered *(ebp+0xc) "literal integers are always hex in Mu; either start '") -10202 (write-slice-buffered *(ebp+0xc) *(ebp+8)) -10203 (write-buffered *(ebp+0xc) "' with a '0x' to be unambiguous, or convert it to decimal.\n") -10204 (flush *(ebp+0xc)) -10205 (stop *(ebp+0x10) 1) -10206 $check-mu-hex-int:end: -10207 # . restore registers -10208 5a/pop-to-edx -10209 59/pop-to-ecx -10210 58/pop-to-eax -10211 # . epilogue -10212 89/<- %esp 5/r32/ebp -10213 5d/pop-to-ebp -10214 c3/return -10215 -10216 new-literal: # ad: (addr allocation-descriptor), name: (addr slice), out: (addr handle var) -10217 # . prologue -10218 55/push-ebp -10219 89/<- %ebp 4/r32/esp -10220 # . save registers -10221 50/push-eax -10222 51/push-ecx -10223 # var s/ecx: (handle array byte) -10224 68/push 0/imm32 -10225 68/push 0/imm32 -10226 89/<- %ecx 4/r32/esp -10227 # s = slice-to-string(name) -10228 (slice-to-string Heap *(ebp+0xc) %ecx) -10229 # allocate to out -10230 (new-var *(ebp+8) *ecx *(ecx+4) *(ebp+0x10)) -10231 # var out-addr/ecx: (addr var) = lookup(*out) -10232 8b/-> *(ebp+0x10) 1/r32/ecx -10233 (lookup *ecx *(ecx+4)) # => eax -10234 89/<- %ecx 0/r32/eax -10235 # out-addr->block-depth = *Curr-block-depth -10236 8b/-> *Curr-block-depth 0/r32/eax -10237 89/<- *(ecx+0x10) 0/r32/eax # Var-block-depth -10238 # out-addr->type/eax = new type -10239 8d/copy-address *(ecx+8) 0/r32/eax # Var-type -10240 (allocate *(ebp+8) *Type-tree-size %eax) -10241 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax -10242 # nothing else to do; default type is 'literal' -10243 c7 0/subop/copy *eax 1/imm32/true # Type-tree-is-atom -10244 $new-literal:end: -10245 # . reclaim locals -10246 81 0/subop/add %esp 8/imm32 -10247 # . restore registers -10248 59/pop-to-ecx -10249 58/pop-to-eax -10250 # . epilogue -10251 89/<- %esp 5/r32/ebp -10252 5d/pop-to-ebp -10253 c3/return -10254 -10255 new-var-from-slice: # ad: (addr allocation-descriptor), name: (addr slice), out: (addr handle var) -10256 # . prologue -10257 55/push-ebp -10258 89/<- %ebp 4/r32/esp -10259 # . save registers -10260 51/push-ecx -10261 # var tmp/ecx: (handle array byte) -10262 68/push 0/imm32 -10263 68/push 0/imm32 -10264 89/<- %ecx 4/r32/esp -10265 # tmp = slice-to-string(name) -10266 (slice-to-string Heap *(ebp+0xc) %ecx) -10267 # out = new-var(tmp) -10268 (new-var *(ebp+8) *ecx *(ecx+4) *(ebp+0x10)) -10269 $new-var-from-slice:end: -10270 # . reclaim locals -10271 81 0/subop/add %esp 8/imm32 -10272 # . restore registers -10273 59/pop-to-ecx -10274 # . epilogue -10275 89/<- %esp 5/r32/ebp -10276 5d/pop-to-ebp -10277 c3/return -10278 -10279 new-var-def: # ad: (addr allocation-descriptor), var: (handle var), out: (addr handle stmt) -10280 # . prologue -10281 55/push-ebp -10282 89/<- %ebp 4/r32/esp -10283 # . save registers -10284 50/push-eax -10285 51/push-ecx -10286 # -10287 (allocate *(ebp+8) *Stmt-size *(ebp+0x14)) -10288 # var out-addr/eax: (addr stmt) = lookup(*out) -10289 8b/-> *(ebp+0x14) 0/r32/eax -10290 (lookup *eax *(eax+4)) # => eax -10291 # out-addr->tag = stmt -10292 c7 0/subop/copy *eax 2/imm32/tag/var-on-stack # Stmt-tag -10293 # result->var = var -10294 8b/-> *(ebp+0xc) 1/r32/ecx -10295 89/<- *(eax+4) 1/r32/ecx # Vardef-var -10296 8b/-> *(ebp+0x10) 1/r32/ecx -10297 89/<- *(eax+8) 1/r32/ecx # Vardef-var -10298 $new-var-def:end: -10299 # . restore registers -10300 59/pop-to-ecx -10301 58/pop-to-eax -10302 # . epilogue -10303 89/<- %esp 5/r32/ebp -10304 5d/pop-to-ebp -10305 c3/return -10306 -10307 new-reg-var-def: # ad: (addr allocation-descriptor), var: (handle var), out: (addr handle stmt) -10308 # . prologue -10309 55/push-ebp -10310 89/<- %ebp 4/r32/esp -10311 # . save registers -10312 50/push-eax -10313 # eax = out -10314 8b/-> *(ebp+0x14) 0/r32/eax -10315 # -10316 (allocate *(ebp+8) *Stmt-size %eax) -10317 # var out-addr/eax: (addr stmt) = lookup(*out) -10318 (lookup *eax *(eax+4)) # => eax -10319 # set tag -10320 c7 0/subop/copy *eax 3/imm32/tag/var-in-register # Stmt-tag -10321 # set output -10322 8d/copy-address *(eax+0x14) 0/r32/eax # Regvardef-outputs -10323 (append-stmt-var Heap *(ebp+0xc) *(ebp+0x10) 0 0 0 %eax) -10324 $new-reg-var-def:end: -10325 # . restore registers -10326 58/pop-to-eax -10327 # . epilogue -10328 89/<- %esp 5/r32/ebp -10329 5d/pop-to-ebp -10330 c3/return -10331 -10332 append-list: # ad: (addr allocation-descriptor), value: (handle _type), list: (handle list _type), out: (addr handle list _type) -10333 # . prologue -10334 55/push-ebp -10335 89/<- %ebp 4/r32/esp -10336 # . save registers -10337 50/push-eax -10338 51/push-ecx -10339 57/push-edi -10340 # edi = out -10341 8b/-> *(ebp+0x1c) 7/r32/edi -10342 # *out = new list -10343 (allocate *(ebp+8) *List-size %edi) -10344 # var out-addr/edi: (addr list _type) = lookup(*out) -10345 (lookup *edi *(edi+4)) # => eax -10346 89/<- %edi 0/r32/eax -10347 # out-addr->value = value -10348 8b/-> *(ebp+0xc) 0/r32/eax -10349 89/<- *edi 0/r32/eax # List-value -10350 8b/-> *(ebp+0x10) 0/r32/eax -10351 89/<- *(edi+4) 0/r32/eax # List-value -10352 # if (list == null) return -10353 81 7/subop/compare *(ebp+0x14) 0/imm32 -10354 74/jump-if-= $append-list:end/disp8 -10355 # otherwise append -10356 $append-list:non-empty-list: -10357 # var curr/eax: (addr list _type) = lookup(list) -10358 (lookup *(ebp+0x14) *(ebp+0x18)) # => eax -10359 # while (curr->next != null) curr = curr->next -10360 { -10361 81 7/subop/compare *(eax+8) 0/imm32 # List-next -10362 74/jump-if-= break/disp8 -10363 # curr = lookup(curr->next) -10364 (lookup *(eax+8) *(eax+0xc)) # List-next, List-next => eax -10365 # -10366 eb/jump loop/disp8 -10367 } -10368 # edi = out -10369 8b/-> *(ebp+0x1c) 7/r32/edi -10370 # curr->next = out -10371 8b/-> *edi 1/r32/ecx -10372 89/<- *(eax+8) 1/r32/ecx # List-next -10373 8b/-> *(edi+4) 1/r32/ecx -10374 89/<- *(eax+0xc) 1/r32/ecx # List-next -10375 # out = list -10376 8b/-> *(ebp+0x14) 1/r32/ecx -10377 89/<- *edi 1/r32/ecx -10378 8b/-> *(ebp+0x18) 1/r32/ecx -10379 89/<- *(edi+4) 1/r32/ecx -10380 $append-list:end: -10381 # . restore registers -10382 5f/pop-to-edi -10383 59/pop-to-ecx -10384 58/pop-to-eax -10385 # . epilogue -10386 89/<- %esp 5/r32/ebp -10387 5d/pop-to-ebp -10388 c3/return -10389 -10390 append-stmt-var: # ad: (addr allocation-descriptor), v: (handle var), vars: (handle stmt-var), is-deref?: boolean, out: (addr handle stmt-var) -10391 # . prologue -10392 55/push-ebp -10393 89/<- %ebp 4/r32/esp -10394 # . save registers -10395 50/push-eax -10396 51/push-ecx -10397 57/push-edi -10398 # edi = out -10399 8b/-> *(ebp+0x20) 7/r32/edi -10400 # out = new stmt-var -10401 (allocate *(ebp+8) *Stmt-var-size %edi) -10402 # var out-addr/ecx: (addr stmt-var) = lookup(*out) -10403 (lookup *edi *(edi+4)) # => eax -10404 89/<- %ecx 0/r32/eax -10405 # out-addr->value = v -10406 8b/-> *(ebp+0xc) 0/r32/eax -10407 89/<- *ecx 0/r32/eax # Stmt-var-value -10408 8b/-> *(ebp+0x10) 0/r32/eax -10409 89/<- *(ecx+4) 0/r32/eax # Stmt-var-value -10410 # out-addr->is-deref? = is-deref? -10411 8b/-> *(ebp+0x1c) 0/r32/eax -10412 89/<- *(ecx+0x10) 0/r32/eax # Stmt-var-is-deref -10413 # if (vars == null) return result -10414 81 7/subop/compare *(ebp+0x14) 0/imm32/null -10415 74/jump-if-= $append-stmt-var:end/disp8 -10416 # otherwise append -10417 # var curr/eax: (addr stmt-var) = lookup(vars) -10418 (lookup *(ebp+0x14) *(ebp+0x18)) # => eax -10419 # while (curr->next != null) curr = curr->next -10420 { -10421 81 7/subop/compare *(eax+8) 0/imm32 # Stmt-var-next -10422 74/jump-if-= break/disp8 -10423 # curr = lookup(curr->next) -10424 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next, Stmt-var-next => eax -10425 # -10426 eb/jump loop/disp8 -10427 } -10428 # curr->next = out -10429 8b/-> *edi 1/r32/ecx -10430 89/<- *(eax+8) 1/r32/ecx # Stmt-var-next -10431 8b/-> *(edi+4) 1/r32/ecx -10432 89/<- *(eax+0xc) 1/r32/ecx # Stmt-var-next -10433 # out = vars -10434 8b/-> *(ebp+0x14) 1/r32/ecx -10435 89/<- *edi 1/r32/ecx -10436 8b/-> *(ebp+0x18) 1/r32/ecx -10437 89/<- *(edi+4) 1/r32/ecx -10438 $append-stmt-var:end: -10439 # . restore registers -10440 5f/pop-to-edi -10441 59/pop-to-ecx -10442 58/pop-to-eax -10443 # . epilogue -10444 89/<- %esp 5/r32/ebp -10445 5d/pop-to-ebp -10446 c3/return -10447 -10448 append-to-block: # ad: (addr allocation-descriptor), block: (addr block), x: (handle stmt) -10449 # . prologue -10450 55/push-ebp -10451 89/<- %ebp 4/r32/esp -10452 # . save registers -10453 50/push-eax -10454 56/push-esi -10455 # esi = block -10456 8b/-> *(ebp+0xc) 6/r32/esi -10457 # block->stmts = append(x, block->stmts) -10458 8d/copy-address *(esi+4) 0/r32/eax # Block-stmts -10459 (append-list *(ebp+8) *(ebp+0x10) *(ebp+0x14) *(esi+4) *(esi+8) %eax) # ad, x, x, Block-stmts, Block-stmts -10460 $append-to-block:end: -10461 # . restore registers -10462 5e/pop-to-esi -10463 58/pop-to-eax -10464 # . epilogue -10465 89/<- %esp 5/r32/ebp -10466 5d/pop-to-ebp -10467 c3/return -10468 -10469 ## Parsing types -10470 # We need to create metadata on user-defined types, and we need to use this -10471 # metadata as we parse instructions. -10472 # However, we also want to allow types to be used before their definitions. -10473 # This means we can't ever assume any type data structures exist. -10474 -10475 lookup-or-create-constant: # container: (addr stmt-var), field-name: (addr slice), out: (addr handle var) -10476 # . prologue -10477 55/push-ebp -10478 89/<- %ebp 4/r32/esp -10479 # . save registers -10480 50/push-eax -10481 56/push-esi -10482 # var container-type/esi: type-id -10483 (container-type *(ebp+8)) # => eax -10484 89/<- %esi 0/r32/eax -10485 # var tmp/eax: (handle typeinfo) = find-or-create-typeinfo(container-type) -10486 68/push 0/imm32 -10487 68/push 0/imm32 -10488 89/<- %eax 4/r32/esp -10489 (find-or-create-typeinfo %esi %eax) -10490 # var tmp-addr/eax: (addr typeinfo) = lookup(tmp) -10491 (lookup *eax *(eax+4)) # => eax -10492 # result = find-or-create-typeinfo-output-var(typeinfo, field-name) -10493 #? (write-buffered Stderr "constant: ") -10494 #? (write-slice-buffered Stderr *(ebp+0xc)) -10495 #? (write-buffered Stderr Newline) -10496 #? (flush Stderr) -10497 (find-or-create-typeinfo-output-var %eax *(ebp+0xc) *(ebp+0x10)) -10498 #? 8b/-> *(ebp+0x10) 0/r32/eax -10499 #? (write-buffered Stderr "@") -10500 #? (lookup *eax *(eax+4)) -10501 #? (write-int32-hex-buffered Stderr %eax) -10502 #? (lookup *eax *(eax+4)) -10503 #? (write-buffered Stderr %eax) -10504 #? (write-buffered Stderr Newline) -10505 #? (flush Stderr) -10506 #? (write-buffered Stderr "offset: ") -10507 #? 8b/-> *(eax+0x14) 0/r32/eax -10508 #? (write-int32-hex-buffered Stderr %eax) -10509 #? (write-buffered Stderr Newline) -10510 #? (flush Stderr) -10511 $lookup-or-create-constant:end: -10512 # . reclaim locals -10513 81 0/subop/add %esp 8/imm32 -10514 # . restore registers -10515 5e/pop-to-esi -10516 58/pop-to-eax -10517 # . epilogue -10518 89/<- %esp 5/r32/ebp -10519 5d/pop-to-ebp -10520 c3/return -10521 -10522 # if addr var: -10523 # container->var->type->right->left->value -10524 # otherwise -10525 # container->var->type->value -10526 container-type: # container: (addr stmt-var) -> result/eax: type-id -10527 # . prologue -10528 55/push-ebp -10529 89/<- %ebp 4/r32/esp -10530 # -10531 8b/-> *(ebp+8) 0/r32/eax -10532 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -10533 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax -10534 { -10535 81 7/subop/compare *(eax+8) 0/imm32 # Type-tree-right -10536 74/jump-if-= break/disp8 -10537 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax -10538 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax -10539 } -10540 8b/-> *(eax+4) 0/r32/eax # Type-tree-value -10541 $container-type:end: -10542 # . epilogue -10543 89/<- %esp 5/r32/ebp -10544 5d/pop-to-ebp -10545 c3/return -10546 -10547 is-container?: # t: type-id -> result/eax: boolean -10548 # . prologue -10549 55/push-ebp -10550 89/<- %ebp 4/r32/esp -10551 # -10552 8b/-> *(ebp+8) 0/r32/eax -10553 c1/shift 4/subop/left %eax 2/imm8 -10554 3b/compare 0/r32/eax *Primitive-type-ids -10555 0f 9d/set-if->= %al -10556 81 4/subop/and %eax 0xff/imm32 -10557 $is-container?:end: -10558 # . epilogue -10559 89/<- %esp 5/r32/ebp -10560 5d/pop-to-ebp -10561 c3/return -10562 -10563 find-or-create-typeinfo: # t: type-id, out: (addr handle typeinfo) -10564 # . prologue -10565 55/push-ebp -10566 89/<- %ebp 4/r32/esp -10567 # . save registers -10568 50/push-eax -10569 51/push-ecx -10570 52/push-edx -10571 57/push-edi -10572 # edi = out -10573 8b/-> *(ebp+0xc) 7/r32/edi -10574 # var fields/ecx: (handle table (handle array byte) (handle typeinfo-entry)) -10575 68/push 0/imm32 -10576 68/push 0/imm32 -10577 89/<- %ecx 4/r32/esp -10578 # find-typeinfo(t, out) -10579 (find-typeinfo *(ebp+8) %edi) -10580 { -10581 # if (*out != 0) break -10582 81 7/subop/compare *edi 0/imm32 -10583 0f 85/jump-if-!= break/disp32 -10584 $find-or-create-typeinfo:create: -10585 # *out = allocate -10586 (allocate Heap *Typeinfo-size %edi) -10587 # var tmp/eax: (addr typeinfo) = lookup(*out) -10588 (lookup *edi *(edi+4)) # => eax -10589 #? (write-buffered Stderr "created typeinfo at ") -10590 #? (write-int32-hex-buffered Stderr %eax) -10591 #? (write-buffered Stderr " for type-id ") -10592 #? (write-int32-hex-buffered Stderr *(ebp+8)) -10593 #? (write-buffered Stderr Newline) -10594 #? (flush Stderr) -10595 # tmp->id = t -10596 8b/-> *(ebp+8) 2/r32/edx -10597 89/<- *eax 2/r32/edx # Typeinfo-id -10598 # tmp->fields = new table -10599 # . fields = new table -10600 (new-stream Heap 0x40 *Typeinfo-fields-row-size %ecx) -10601 # . tmp->fields = fields -10602 8b/-> *ecx 2/r32/edx -10603 89/<- *(eax+4) 2/r32/edx # Typeinfo-fields -10604 8b/-> *(ecx+4) 2/r32/edx -10605 89/<- *(eax+8) 2/r32/edx # Typeinfo-fields -10606 # tmp->next = Program->types -10607 8b/-> *_Program-types 1/r32/ecx -10608 89/<- *(eax+0x10) 1/r32/ecx # Typeinfo-next -10609 8b/-> *_Program-types->payload 1/r32/ecx -10610 89/<- *(eax+0x14) 1/r32/ecx # Typeinfo-next -10611 # Program->types = out -10612 8b/-> *edi 1/r32/ecx -10613 89/<- *_Program-types 1/r32/ecx -10614 8b/-> *(edi+4) 1/r32/ecx -10615 89/<- *_Program-types->payload 1/r32/ecx -10616 } -10617 $find-or-create-typeinfo:end: -10618 # . reclaim locals -10619 81 0/subop/add %esp 8/imm32 -10620 # . restore registers -10621 5f/pop-to-edi -10622 5a/pop-to-edx -10623 59/pop-to-ecx -10624 58/pop-to-eax -10625 # . epilogue -10626 89/<- %esp 5/r32/ebp -10627 5d/pop-to-ebp -10628 c3/return -10629 -10630 find-typeinfo: # t: type-id, out: (addr handle typeinfo) -10631 # . prologue -10632 55/push-ebp -10633 89/<- %ebp 4/r32/esp -10634 # . save registers -10635 50/push-eax -10636 51/push-ecx -10637 52/push-edx -10638 57/push-edi -10639 # ecx = t -10640 8b/-> *(ebp+8) 1/r32/ecx -10641 # edi = out -10642 8b/-> *(ebp+0xc) 7/r32/edi -10643 # *out = Program->types -10644 8b/-> *_Program-types 0/r32/eax -10645 89/<- *edi 0/r32/eax -10646 8b/-> *_Program-types->payload 0/r32/eax -10647 89/<- *(edi+4) 0/r32/eax -10648 { -10649 $find-typeinfo:loop: -10650 # if (*out == 0) break -10651 81 7/subop/compare *edi 0/imm32 -10652 74/jump-if-= break/disp8 -10653 $find-typeinfo:check: -10654 # var tmp/eax: (addr typeinfo) = lookup(*out) -10655 (lookup *edi *(edi+4)) # => eax -10656 # if (tmp->id == t) break -10657 39/compare *eax 1/r32/ecx # Typeinfo-id -10658 74/jump-if-= break/disp8 -10659 $find-typeinfo:continue: -10660 # *out = tmp->next -10661 8b/-> *(eax+0x10) 2/r32/edx # Typeinfo-next -10662 89/<- *edi 2/r32/edx -10663 8b/-> *(eax+0x14) 2/r32/edx # Typeinfo-next -10664 89/<- *(edi+4) 2/r32/edx -10665 # -10666 eb/jump loop/disp8 -10667 } -10668 $find-typeinfo:end: -10669 # . restore registers -10670 5f/pop-to-edi -10671 5a/pop-to-edx -10672 59/pop-to-ecx -10673 58/pop-to-eax -10674 # . epilogue -10675 89/<- %esp 5/r32/ebp -10676 5d/pop-to-ebp -10677 c3/return -10678 -10679 find-or-create-typeinfo-output-var: # T: (addr typeinfo), f: (addr slice), out: (addr handle var) -10680 # . prologue -10681 55/push-ebp -10682 89/<- %ebp 4/r32/esp -10683 # . save registers -10684 50/push-eax -10685 52/push-edx -10686 57/push-edi -10687 # var dest/edi: (handle typeinfo-entry) -10688 68/push 0/imm32 -10689 68/push 0/imm32 -10690 89/<- %edi 4/r32/esp -10691 # find-or-create-typeinfo-fields(T, f, dest) -10692 (find-or-create-typeinfo-fields *(ebp+8) *(ebp+0xc) %edi) -10693 # var dest-addr/edi: (addr typeinfo-entry) = lookup(dest) -10694 (lookup *edi *(edi+4)) # => eax -10695 89/<- %edi 0/r32/eax -10696 # if dest-addr->output-var doesn't exist, create it -10697 { -10698 81 7/subop/compare *(edi+0xc) 0/imm32 # Typeinfo-entry-output-var -10699 0f 85/jump-if-!= break/disp32 -10700 # dest-addr->output-var = new var(dummy name, type, -1 offset) -10701 # . var name/eax: (handle array byte) = "field" -10702 68/push 0/imm32 -10703 68/push 0/imm32 -10704 89/<- %eax 4/r32/esp -10705 (slice-to-string Heap *(ebp+0xc) %eax) -10706 # . new var -10707 8d/copy-address *(edi+0xc) 2/r32/edx -10708 (new-var Heap *eax *(eax+4) %edx) -10709 # . reclaim name -10710 81 0/subop/add %esp 8/imm32 -10711 # var result/edx: (addr var) = lookup(dest-addr->output-var) -10712 (lookup *(edi+0xc) *(edi+0x10)) # => eax -10713 89/<- %edx 0/r32/eax -10714 # result->type = new constant type -10715 8d/copy-address *(edx+8) 0/r32/eax # Var-type -10716 (allocate Heap *Type-tree-size %eax) -10717 (lookup *(edx+8) *(edx+0xc)) # => eax -10718 c7 0/subop/copy *eax 1/imm32/true # Type-tree-is-atom -10719 c7 0/subop/copy *(eax+4) 6/imm32/constant # Type-tree-value -10720 c7 0/subop/copy *(eax+8) 0/imm32 # Type-tree-left -10721 c7 0/subop/copy *(eax+0xc) 0/imm32 # Type-tree-right -10722 c7 0/subop/copy *(eax+0x10) 0/imm32 # Type-tree-right -10723 # result->offset isn't filled out yet -10724 c7 0/subop/copy *(edx+0x14) -1/imm32/uninitialized # Var-offset -10725 } -10726 # out = dest-addr->output-var -10727 8b/-> *(ebp+0x10) 2/r32/edx -10728 8b/-> *(edi+0xc) 0/r32/eax # Typeinfo-entry-output-var -10729 89/<- *edx 0/r32/eax -10730 8b/-> *(edi+0x10) 0/r32/eax # Typeinfo-entry-output-var -10731 89/<- *(edx+4) 0/r32/eax -10732 $find-or-create-typeinfo-output-var:end: -10733 # . reclaim locals -10734 81 0/subop/add %esp 8/imm32 -10735 # . restore registers -10736 5f/pop-to-edi -10737 5a/pop-to-edx -10738 58/pop-to-eax -10739 # . epilogue -10740 89/<- %esp 5/r32/ebp -10741 5d/pop-to-ebp -10742 c3/return -10743 -10744 find-or-create-typeinfo-fields: # T: (addr typeinfo), f: (addr slice), out: (addr handle typeinfo-entry) -10745 # . prologue -10746 55/push-ebp -10747 89/<- %ebp 4/r32/esp -10748 # . save registers -10749 50/push-eax -10750 56/push-esi -10751 57/push-edi -10752 # eax = lookup(T->fields) -10753 8b/-> *(ebp+8) 0/r32/eax -10754 (lookup *(eax+4) *(eax+8)) # Typeinfo-fields Typeinfo-fields => eax -10755 # edi = out -10756 8b/-> *(ebp+0x10) 7/r32/edi -10757 # var src/esi: (addr handle typeinfo-entry) = get-or-insert-slice(T->fields, f) -10758 (get-or-insert-slice %eax *(ebp+0xc) *Typeinfo-fields-row-size Heap) # => eax -10759 89/<- %esi 0/r32/eax -10760 # if src doesn't exist, allocate it -10761 { -10762 81 7/subop/compare *esi 0/imm32 -10763 75/jump-if-!= break/disp8 -10764 (allocate Heap *Typeinfo-entry-size %esi) -10765 #? (write-buffered Stderr "handle at ") -10766 #? (write-int32-hex-buffered Stderr %esi) -10767 #? (write-buffered Stderr ": ") -10768 #? (write-int32-hex-buffered Stderr *esi) -10769 #? (write-buffered Stderr " ") -10770 #? (write-int32-hex-buffered Stderr *(esi+4)) -10771 #? (write-buffered Stderr Newline) -10772 #? (flush Stderr) -10773 #? (lookup *esi *(esi+4)) -10774 #? (write-buffered Stderr "created typeinfo fields at ") -10775 #? (write-int32-hex-buffered Stderr %esi) -10776 #? (write-buffered Stderr " for ") -10777 #? (write-int32-hex-buffered Stderr *(ebp+8)) -10778 #? (write-buffered Stderr Newline) -10779 #? (flush Stderr) -10780 } -10781 # *out = src -10782 # . *edi = *src -10783 8b/-> *esi 0/r32/eax -10784 89/<- *edi 0/r32/eax -10785 8b/-> *(esi+4) 0/r32/eax -10786 89/<- *(edi+4) 0/r32/eax -10787 $find-or-create-typeinfo-fields:end: -10788 # . restore registers -10789 5f/pop-to-edi -10790 5e/pop-to-esi -10791 58/pop-to-eax -10792 # . epilogue -10793 89/<- %esp 5/r32/ebp -10794 5d/pop-to-ebp -10795 c3/return -10796 -10797 populate-mu-type: # in: (addr stream byte), t: (addr typeinfo), err: (addr buffered-file), ed: (addr exit-descriptor) -10798 # pseudocode: -10799 # var line: (stream byte 512) -10800 # curr-index = 0 -10801 # while true -10802 # clear-stream(line) -10803 # read-line-buffered(in, line) -10804 # if line->write == 0 -10805 # abort -10806 # word-slice = next-mu-token(line) -10807 # if slice-empty?(word-slice) # end of line -10808 # continue -10809 # if slice-equal?(word-slice, "}") -10810 # break -10811 # var v: (handle var) = parse-var-with-type(word-slice, line) -10812 # var r: (handle typeinfo-fields) = find-or-create-typeinfo-fields(t, word-slice/v->name) -10813 # TODO: ensure that r->first is null -10814 # r->index = curr-index -10815 # curr-index++ -10816 # r->input-var = v -10817 # if r->output-var == 0 -10818 # r->output-var = new literal -10819 # TODO: ensure nothing else in line -10820 # t->total-size-in-bytes = -2 (not yet initialized) -10821 # -10822 # . prologue -10823 55/push-ebp -10824 89/<- %ebp 4/r32/esp -10825 # var curr-index: int at *(ebp-4) -10826 68/push 0/imm32 -10827 # . save registers -10828 50/push-eax -10829 51/push-ecx -10830 52/push-edx -10831 53/push-ebx -10832 56/push-esi -10833 57/push-edi -10834 # edi = t -10835 8b/-> *(ebp+0xc) 7/r32/edi -10836 # var line/ecx: (stream byte 512) -10837 81 5/subop/subtract %esp 0x200/imm32 -10838 68/push 0x200/imm32/size -10839 68/push 0/imm32/read -10840 68/push 0/imm32/write -10841 89/<- %ecx 4/r32/esp -10842 # var word-slice/edx: slice -10843 68/push 0/imm32/end -10844 68/push 0/imm32/start -10845 89/<- %edx 4/r32/esp -10846 # var v/esi: (handle var) -10847 68/push 0/imm32 -10848 68/push 0/imm32 -10849 89/<- %esi 4/r32/esp -10850 # var r/ebx: (handle typeinfo-entry) -10851 68/push 0/imm32 -10852 68/push 0/imm32 -10853 89/<- %ebx 4/r32/esp -10854 { -10855 $populate-mu-type:line-loop: -10856 (clear-stream %ecx) -10857 (read-line-buffered *(ebp+8) %ecx) -10858 # if (line->write == 0) abort -10859 81 7/subop/compare *ecx 0/imm32 -10860 0f 84/jump-if-= $populate-mu-type:error1/disp32 -10861 +-- 6 lines: #? # dump line ------------------------------------------------------------------------------------------------------------------------------------------------------ -10867 (next-mu-token %ecx %edx) -10868 # if slice-empty?(word-slice) continue -10869 (slice-empty? %edx) # => eax -10870 3d/compare-eax-and 0/imm32 -10871 0f 85/jump-if-!= loop/disp32 -10872 # if slice-equal?(word-slice, "}") break -10873 (slice-equal? %edx "}") -10874 3d/compare-eax-and 0/imm32 -10875 0f 85/jump-if-!= break/disp32 -10876 $populate-mu-type:parse-element: -10877 # v = parse-var-with-type(word-slice, first-line) -10878 # must do this first to strip the trailing ':' from word-slice before -10879 # using it in find-or-create-typeinfo-fields below -10880 # TODO: clean up that mutation in parse-var-with-type -10881 (parse-var-with-type %edx %ecx %esi *(ebp+0x10) *(ebp+0x14)) -10882 # if v is an addr, abort -10883 (lookup *esi *(esi+4)) # => eax -10884 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax -10885 (is-mu-addr-type? %eax) # => eax -10886 3d/compare-eax-and 0/imm32/false -10887 0f 85/jump-if-!= $populate-mu-type:error2/disp32 -10888 # if v is an array, abort (we could support it, but initialization gets complex) -10889 (lookup *esi *(esi+4)) # => eax -10890 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax -10891 (is-mu-array-type? %eax) # => eax -10892 3d/compare-eax-and 0/imm32/false -10893 0f 85/jump-if-!= $populate-mu-type:error3/disp32 -10894 # if v is a byte, abort -10895 (lookup *esi *(esi+4)) # => eax -10896 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax -10897 (is-simple-mu-type? %eax 8) # byte => eax -10898 3d/compare-eax-and 0/imm32/false -10899 0f 85/jump-if-!= $populate-mu-type:error4/disp32 -10900 # if v is a slice, abort -10901 (lookup *esi *(esi+4)) # => eax -10902 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax -10903 (is-simple-mu-type? %eax 0xc) # slice => eax -10904 3d/compare-eax-and 0/imm32/false -10905 0f 85/jump-if-!= $populate-mu-type:error5/disp32 -10906 # if v is a stream, abort (we could support it, but initialization gets even more complex) -10907 (lookup *esi *(esi+4)) # => eax -10908 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax -10909 (is-mu-stream-type? %eax) # => eax -10910 3d/compare-eax-and 0/imm32/false -10911 0f 85/jump-if-!= $populate-mu-type:error6/disp32 -10912 # var tmp/ecx -10913 51/push-ecx -10914 $populate-mu-type:create-typeinfo-fields: -10915 # var r/ebx: (handle typeinfo-entry) -10916 (find-or-create-typeinfo-fields %edi %edx %ebx) -10917 # r->index = curr-index -10918 (lookup *ebx *(ebx+4)) # => eax -10919 8b/-> *(ebp-4) 1/r32/ecx -10920 #? (write-buffered Stderr "saving index ") -10921 #? (write-int32-hex-buffered Stderr %ecx) -10922 #? (write-buffered Stderr " at ") -10923 #? (write-int32-hex-buffered Stderr %edi) -10924 #? (write-buffered Stderr Newline) -10925 #? (flush Stderr) -10926 89/<- *(eax+8) 1/r32/ecx # Typeinfo-entry-index -10927 # ++curr-index -10928 ff 0/subop/increment *(ebp-4) -10929 $populate-mu-type:set-input-type: -10930 # r->input-var = v -10931 8b/-> *esi 1/r32/ecx -10932 89/<- *eax 1/r32/ecx # Typeinfo-entry-input-var -10933 8b/-> *(esi+4) 1/r32/ecx -10934 89/<- *(eax+4) 1/r32/ecx # Typeinfo-entry-input-var -10935 # restore line -10936 59/pop-to-ecx -10937 { -10938 $populate-mu-type:create-output-type: -10939 # if (r->output-var == 0) create a new var with some placeholder data -10940 81 7/subop/compare *(eax+0xc) 0/imm32 # Typeinfo-entry-output-var -10941 75/jump-if-!= break/disp8 -10942 8d/copy-address *(eax+0xc) 0/r32/eax # Typeinfo-entry-output-var -10943 (new-literal Heap %edx %eax) -10944 } -10945 e9/jump loop/disp32 -10946 } -10947 $populate-mu-type:invalidate-total-size-in-bytes: -10948 # Offsets and total size may not be accurate here since we may not yet -10949 # have encountered the element types. -10950 # We'll recompute them separately after parsing the entire program. -10951 c7 0/subop/copy *(edi+0xc) -2/imm32/uninitialized # Typeinfo-total-size-in-bytes -10952 $populate-mu-type:end: -10953 # . reclaim locals -10954 81 0/subop/add %esp 0x224/imm32 -10955 # . restore registers -10956 5f/pop-to-edi -10957 5e/pop-to-esi -10958 5b/pop-to-ebx -10959 5a/pop-to-edx -10960 59/pop-to-ecx -10961 58/pop-to-eax -10962 # reclaim curr-index -10963 81 0/subop/add %esp 4/imm32 -10964 # . epilogue -10965 89/<- %esp 5/r32/ebp -10966 5d/pop-to-ebp -10967 c3/return -10968 -10969 $populate-mu-type:error1: -10970 # error("incomplete type definition '" t->name "'\n") -10971 (write-buffered *(ebp+0x10) "incomplete type definition '") -10972 (type-name *edi) # Typeinfo-id => eax -10973 (write-buffered *(ebp+0x10) %eax) -10974 (write-buffered *(ebp+0x10) "\n") -10975 (flush *(ebp+0x10)) -10976 (stop *(ebp+0x14) 1) -10977 # never gets here -10978 -10979 $populate-mu-type:error2: -10980 (write-buffered *(ebp+0x10) "type ") -10981 (type-name *edi) # Typeinfo-id => eax -10982 (write-buffered *(ebp+0x10) %eax) -10983 (write-buffered *(ebp+0x10) ": 'addr' elements not allowed\n") -10984 (flush *(ebp+0x10)) -10985 (stop *(ebp+0x14) 1) -10986 # never gets here -10987 -10988 $populate-mu-type:error3: -10989 (write-buffered *(ebp+0x10) "type ") -10990 (type-name *edi) # Typeinfo-id => eax -10991 (write-buffered *(ebp+0x10) %eax) -10992 (write-buffered *(ebp+0x10) ": 'array' elements not allowed for now\n") -10993 (flush *(ebp+0x10)) -10994 (stop *(ebp+0x14) 1) -10995 # never gets here -10996 -10997 $populate-mu-type:error4: -10998 (write-buffered *(ebp+0x10) "type ") -10999 (type-name *edi) # Typeinfo-id => eax -11000 (write-buffered *(ebp+0x10) %eax) -11001 (write-buffered *(ebp+0x10) ": 'byte' elements not allowed\n") -11002 (flush *(ebp+0x10)) -11003 (stop *(ebp+0x14) 1) -11004 # never gets here -11005 -11006 $populate-mu-type:error5: -11007 (write-buffered *(ebp+0x10) "type ") -11008 (type-name *edi) # Typeinfo-id => eax -11009 (write-buffered *(ebp+0x10) %eax) -11010 (write-buffered *(ebp+0x10) ": 'slice' elements not allowed\n") -11011 (flush *(ebp+0x10)) -11012 (stop *(ebp+0x14) 1) -11013 # never gets here -11014 -11015 $populate-mu-type:error6: -11016 (write-buffered *(ebp+0x10) "type ") -11017 (type-name *edi) # Typeinfo-id => eax -11018 (write-buffered *(ebp+0x10) %eax) -11019 (write-buffered *(ebp+0x10) ": 'stream' elements not allowed for now\n") -11020 (flush *(ebp+0x10)) -11021 (stop *(ebp+0x14) 1) -11022 # never gets here -11023 -11024 type-name: # index: int -> result/eax: (addr array byte) -11025 # . prologue -11026 55/push-ebp -11027 89/<- %ebp 4/r32/esp -11028 # -11029 (index Type-id *(ebp+8)) -11030 $type-name:end: -11031 # . epilogue -11032 89/<- %esp 5/r32/ebp -11033 5d/pop-to-ebp -11034 c3/return -11035 -11036 index: # arr: (addr stream (handle array byte)), index: int -> result/eax: (addr array byte) -11037 # . prologue -11038 55/push-ebp -11039 89/<- %ebp 4/r32/esp -11040 # . save registers -11041 56/push-esi -11042 # TODO: bounds-check index -11043 # esi = arr -11044 8b/-> *(ebp+8) 6/r32/esi -11045 # eax = index -11046 8b/-> *(ebp+0xc) 0/r32/eax -11047 # eax = *(arr + 12 + index) -11048 8b/-> *(esi+eax<<2+0xc) 0/r32/eax -11049 $index:end: -11050 # . restore registers -11051 5e/pop-to-esi -11052 # . epilogue -11053 89/<- %esp 5/r32/ebp -11054 5d/pop-to-ebp -11055 c3/return -11056 -11057 ####################################################### -11058 # Compute type sizes -11059 ####################################################### -11060 -11061 # Compute the sizes of all user-defined types. -11062 # We'll need the sizes of their elements, which may be other user-defined -11063 # types, which we will compute as needed. -11064 -11065 # Initially, all user-defined types have their sizes set to -2 (invalid) -11066 populate-mu-type-sizes: # err: (addr buffered-file), ed: (addr exit-descriptor) -11067 # . prologue -11068 55/push-ebp -11069 89/<- %ebp 4/r32/esp -11070 $populate-mu-type-sizes:total-sizes: -11071 # var curr/eax: (addr typeinfo) = lookup(Program->types) -11072 (lookup *_Program-types *_Program-types->payload) # => eax -11073 { -11074 # if (curr == null) break -11075 3d/compare-eax-and 0/imm32/null -11076 74/jump-if-= break/disp8 -11077 (populate-mu-type-sizes-in-type %eax *(ebp+8) *(ebp+0xc)) -11078 # curr = lookup(curr->next) -11079 (lookup *(eax+0x10) *(eax+0x14)) # Typeinfo-next Typeinfo-next => eax -11080 eb/jump loop/disp8 -11081 } -11082 $populate-mu-type-sizes:offsets: -11083 # curr = *Program->types -11084 (lookup *_Program-types *_Program-types->payload) # => eax -11085 { -11086 # if (curr == null) break -11087 3d/compare-eax-and 0/imm32/null -11088 74/jump-if-= break/disp8 -11089 (populate-mu-type-offsets %eax *(ebp+8) *(ebp+0xc)) -11090 # curr = curr->next -11091 (lookup *(eax+0x10) *(eax+0x14)) # Typeinfo-next Typeinfo-next => eax -11092 eb/jump loop/disp8 -11093 } -11094 $populate-mu-type-sizes:end: -11095 # . epilogue -11096 89/<- %esp 5/r32/ebp -11097 5d/pop-to-ebp -11098 c3/return -11099 -11100 # compute sizes of all fields, recursing as necessary -11101 # sum up all their sizes to arrive at total size -11102 # fields may be out of order, but that doesn't affect the answer -11103 populate-mu-type-sizes-in-type: # T: (addr typeinfo), err: (addr buffered-file), ed: (addr exit-descriptor) -11104 # . prologue -11105 55/push-ebp -11106 89/<- %ebp 4/r32/esp -11107 # . save registers -11108 50/push-eax -11109 51/push-ecx -11110 52/push-edx -11111 56/push-esi -11112 57/push-edi -11113 # esi = T -11114 8b/-> *(ebp+8) 6/r32/esi -11115 # if T is already computed, return -11116 81 7/subop/compare *(esi+0xc) 0/imm32 # Typeinfo-total-size-in-bytes -11117 0f 8d/jump-if->= $populate-mu-type-sizes-in-type:end/disp32 -11118 # if T is being computed, abort -11119 81 7/subop/compare *(esi+0xc) -1/imm32/being-computed # Typeinfo-total-size-in-bytes -11120 0f 84/jump-if-= $populate-mu-type-sizes-in-type:abort/disp32 -11121 # tag T (-2 to -1) to avoid infinite recursion -11122 c7 0/subop/copy *(esi+0xc) -1/imm32/being-computed # Typeinfo-total-size-in-bytes -11123 # var total-size/edi: int = 0 -11124 bf/copy-to-edi 0/imm32 -11125 # - for every field, if it's a user-defined type, compute its size -11126 # var table/ecx: (addr table (handle array byte) (handle typeinfo-entry)) = lookup(T->fields) -11127 (lookup *(esi+4) *(esi+8)) # Typeinfo-fields Typeinfo-fields => eax -11128 89/<- %ecx 0/r32/eax -11129 # var table-size/edx: int = table->write -11130 8b/-> *ecx 2/r32/edx # stream-write -11131 # var curr/ecx: (addr table_row) = table->data -11132 8d/copy-address *(ecx+0xc) 1/r32/ecx -11133 # var max/edx: (addr table_row) = table->data + table->write -11134 8d/copy-address *(ecx+edx) 2/r32/edx -11135 { -11136 $populate-mu-type-sizes-in-type:loop: -11137 # if (curr >= max) break -11138 39/compare %ecx 2/r32/edx -11139 73/jump-if-addr>= break/disp8 -11140 # var t/eax: (addr typeinfo-entry) = lookup(curr->value) -11141 (lookup *(ecx+8) *(ecx+0xc)) # => eax -11142 # if (t->input-var == 0) silently ignore it; we'll emit a nice error message while type-checking -11143 81 7/subop/compare *eax 0/imm32 # Typeinfo-entry-input-var -11144 74/jump-if-= $populate-mu-type-sizes-in-type:end/disp8 -11145 # compute size of t->input-var -11146 (lookup *eax *(eax+4)) # Typeinfo-entry-input-var Typeinfo-entry-input-var => eax -11147 (compute-size-of-var %eax *(ebp+0xc) *(ebp+0x10)) # => eax -11148 # result += eax -11149 01/add-to %edi 0/r32/eax -11150 # curr += row-size -11151 81 0/subop/add %ecx 0x10/imm32 # Typeinfo-fields-row-size -11152 # -11153 eb/jump loop/disp8 -11154 } -11155 # - save result -11156 89/<- *(esi+0xc) 7/r32/edi # Typeinfo-total-size-in-bytes -11157 $populate-mu-type-sizes-in-type:end: -11158 # . restore registers -11159 5f/pop-to-edi -11160 5e/pop-to-esi -11161 5a/pop-to-edx -11162 59/pop-to-ecx -11163 58/pop-to-eax -11164 # . epilogue -11165 89/<- %esp 5/r32/ebp -11166 5d/pop-to-ebp -11167 c3/return -11168 -11169 $populate-mu-type-sizes-in-type:abort: -11170 (write-buffered *(ebp+0xc) "cycle in type definitions\n") -11171 (flush *(ebp+0xc)) -11172 (stop *(ebp+0x10) 1) -11173 # never gets here -11174 -11175 # Analogous to size-of, except we need to compute what size-of can just read -11176 # off the right data structures. -11177 compute-size-of-var: # in: (addr var), err: (addr buffered-file), ed: (addr exit-descriptor) -> result/eax: int -11178 # . prologue -11179 55/push-ebp -11180 89/<- %ebp 4/r32/esp -11181 # . push registers -11182 51/push-ecx -11183 # var t/ecx: (addr type-tree) = lookup(v->type) -11184 8b/-> *(ebp+8) 1/r32/ecx -11185 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax -11186 89/<- %ecx 0/r32/eax -11187 # if (t->is-atom == false) t = lookup(t->left) -11188 { -11189 81 7/subop/compare *ecx 0/imm32/false # Type-tree-is-atom -11190 75/jump-if-!= break/disp8 -11191 (lookup *(ecx+4) *(ecx+8)) # Type-tree-left Type-tree-left => eax -11192 89/<- %ecx 0/r32/eax -11193 } -11194 # TODO: ensure t is an atom -11195 (compute-size-of-type-id *(ecx+4) *(ebp+0xc) *(ebp+0x10)) # Type-tree-value => eax -11196 $compute-size-of-var:end: -11197 # . restore registers -11198 59/pop-to-ecx -11199 # . epilogue -11200 89/<- %esp 5/r32/ebp -11201 5d/pop-to-ebp -11202 c3/return -11203 -11204 compute-size-of-type-id: # t: type-id, err: (addr buffered-file), ed: (addr exit-descriptor) -> result/eax: int -11205 # . prologue -11206 55/push-ebp -11207 89/<- %ebp 4/r32/esp -11208 # . save registers + 9990 68/push 0/imm32 + 9991 89/<- %esi 4/r32/esp + 9992 # var vars/ecx: (stack (addr var) 16) + 9993 81 5/subop/subtract %esp 0xc0/imm32 + 9994 68/push 0xc0/imm32/size + 9995 68/push 0/imm32/top + 9996 89/<- %ecx 4/r32/esp + 9997 (clear-stack %ecx) + 9998 # convert + 9999 (parse-mu-var-def _test-input-stream %ecx %esi 0 Stderr 0) +10000 # var out-addr/esi: (addr stmt) +10001 (lookup *esi *(esi+4)) # => eax +10002 89/<- %esi 0/r32/eax +10003 # +10004 (check-ints-equal *esi 3 "F - test-parse-mu-reg-var-def/tag") # Stmt-tag is reg-var-def +10005 # var v/ecx: (addr var) = lookup(out->outputs->value) +10006 # . eax: (addr stmt-var) = lookup(out->outputs) +10007 (lookup *(esi+0x14) *(esi+0x18)) # Regvardef-outputs Regvardef-outputs => eax +10008 # . +10009 (check-ints-equal *(eax+8) 0 "F - test-parse-mu-reg-var-def/single-output") # Stmt-var-next +10010 # . eax: (addr var) = lookup(eax->value) +10011 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +10012 # . ecx = eax +10013 89/<- %ecx 0/r32/eax +10014 # v->name +10015 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax +10016 (check-strings-equal %eax "n" "F - test-parse-mu-reg-var-def/output-name") # Var-name +10017 # v->register +10018 (lookup *(ecx+0x18) *(ecx+0x1c)) # Var-register Var-register => eax +10019 (check-strings-equal %eax "eax" "F - test-parse-mu-reg-var-def/output-register") +10020 # v->block-depth +10021 (check-ints-equal *(ecx+0x10) 1 "F - test-parse-mu-reg-var-def/output-block-depth") # Var-block-depth +10022 # v->type == int +10023 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax +10024 (check-ints-equal *eax 1 "F - test-parse-mu-reg-var-def/output-type:0") # Type-tree-is-atom +10025 (check-ints-equal *(eax+4) 1 "F - test-parse-mu-reg-var-def/output-type:1") # Type-tree-value +10026 (check-ints-equal *(eax+0xc) 0 "F - test-parse-mu-reg-var-def/output-type:2") # Type-tree-right +10027 # . epilogue +10028 89/<- %esp 5/r32/ebp +10029 5d/pop-to-ebp +10030 c3/return +10031 +10032 parse-mu-stmt: # line: (addr stream byte), vars: (addr stack live-var), fn: (addr function), out: (addr handle stmt), err: (addr buffered-file), ed: (addr exit-descriptor) +10033 # Carefully push any outputs on the vars stack _after_ reading the inputs +10034 # that may conflict with them. +10035 # +10036 # The only situation in which outputs are pushed here (when it's not a +10037 # 'var' vardef stmt), and so can possibly conflict with inputs, is if the +10038 # output is a function output. +10039 # +10040 # pseudocode: +10041 # var name: slice +10042 # allocate(Heap, Stmt-size, out) +10043 # var out-addr: (addr stmt) = lookup(*out) +10044 # out-addr->tag = stmt +10045 # if stmt-has-outputs?(line) +10046 # while true +10047 # name = next-mu-token(line) +10048 # if (name == '<-') break +10049 # assert(is-identifier?(name)) +10050 # var v: (handle var) = lookup-var-or-find-in-fn-outputs(name, vars, fn) +10051 # out-addr->outputs = append(v, out-addr->outputs) +10052 # add-operation-and-inputs-to-stmt(out-addr, line, vars) +10053 # for output in stmt->outputs: +10054 # maybe-define-var(output, vars) +10055 # +10056 # . prologue +10057 55/push-ebp +10058 89/<- %ebp 4/r32/esp +10059 # . save registers +10060 50/push-eax +10061 51/push-ecx +10062 52/push-edx +10063 53/push-ebx +10064 57/push-edi +10065 # var name/ecx: slice +10066 68/push 0/imm32/end +10067 68/push 0/imm32/start +10068 89/<- %ecx 4/r32/esp +10069 # var is-deref?/edx: boolean = false +10070 ba/copy-to-edx 0/imm32/false +10071 # var v: (handle var) +10072 68/push 0/imm32 +10073 68/push 0/imm32 +10074 89/<- %ebx 4/r32/esp +10075 # +10076 (allocate Heap *Stmt-size *(ebp+0x14)) +10077 # var out-addr/edi: (addr stmt) = lookup(*out) +10078 8b/-> *(ebp+0x14) 7/r32/edi +10079 (lookup *edi *(edi+4)) # => eax +10080 89/<- %edi 0/r32/eax +10081 # out-addr->tag = 1/stmt +10082 c7 0/subop/copy *edi 1/imm32/stmt1 # Stmt-tag +10083 { +10084 (stmt-has-outputs? *(ebp+8)) +10085 3d/compare-eax-and 0/imm32/false +10086 0f 84/jump-if-= break/disp32 +10087 { +10088 $parse-mu-stmt:read-outputs: +10089 # name = next-mu-token(line) +10090 (next-mu-token *(ebp+8) %ecx) +10091 # if slice-empty?(word-slice) break +10092 (slice-empty? %ecx) # => eax +10093 3d/compare-eax-and 0/imm32/false +10094 0f 85/jump-if-!= break/disp32 +10095 # if (name == "<-") break +10096 (slice-equal? %ecx "<-") # => eax +10097 3d/compare-eax-and 0/imm32/false +10098 0f 85/jump-if-!= break/disp32 +10099 # is-deref? = false +10100 ba/copy-to-edx 0/imm32/false +10101 # if (slice-starts-with?(name, '*')) ++name->start and set is-deref? +10102 8b/-> *ecx 0/r32/eax # Slice-start +10103 8a/copy-byte *eax 0/r32/AL +10104 81 4/subop/and %eax 0xff/imm32 +10105 3d/compare-eax-and 0x2a/imm32/asterisk +10106 { +10107 75/jump-if-!= break/disp8 +10108 ff 0/subop/increment *ecx +10109 ba/copy-to-edx 1/imm32/true +10110 } +10111 # assert(is-identifier?(name)) +10112 (is-identifier? %ecx) # => eax +10113 3d/compare-eax-and 0/imm32/false +10114 0f 84/jump-if-= $parse-mu-stmt:abort/disp32 +10115 # +10116 (lookup-var-or-find-in-fn-outputs %ecx *(ebp+0xc) *(ebp+0x10) %ebx *(ebp+0x18) *(ebp+0x1c)) +10117 8d/copy-address *(edi+0x14) 0/r32/eax # Stmt1-outputs +10118 (append-stmt-var Heap *ebx *(ebx+4) *(edi+0x14) *(edi+0x18) %edx %eax) # Stmt1-outputs +10119 # +10120 e9/jump loop/disp32 +10121 } +10122 } +10123 (add-operation-and-inputs-to-stmt %edi *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x18) *(ebp+0x1c)) +10124 $parse-mu-stmt:define-outputs: +10125 # var output/edi: (addr stmt-var) = lookup(out-addr->outputs) +10126 (lookup *(edi+0x14) *(edi+0x18)) # Stmt1-outputs Stmt1-outputs => eax +10127 89/<- %edi 0/r32/eax +10128 { +10129 $parse-mu-stmt:define-outputs-loop: +10130 # if (output == null) break +10131 81 7/subop/compare %edi 0/imm32 +10132 74/jump-if-= break/disp8 +10133 # +10134 (maybe-define-var *edi *(edi+4) *(ebp+0xc)) # if output is a deref, then it's already been defined, +10135 # and must be in vars. This call will be a no-op, but safe. +10136 # output = output->next +10137 (lookup *(edi+8) *(edi+0xc)) # Stmt-var-next Stmt-var-next => eax +10138 89/<- %edi 0/r32/eax +10139 # +10140 eb/jump loop/disp8 +10141 } +10142 $parse-mu-stmt:end: +10143 # . reclaim locals +10144 81 0/subop/add %esp 0x10/imm32 +10145 # . restore registers +10146 5f/pop-to-edi +10147 5b/pop-to-ebx +10148 5a/pop-to-edx +10149 59/pop-to-ecx +10150 58/pop-to-eax +10151 # . epilogue +10152 89/<- %esp 5/r32/ebp +10153 5d/pop-to-ebp +10154 c3/return +10155 +10156 $parse-mu-stmt:abort: +10157 # error("invalid identifier '" name "'\n") +10158 (write-buffered *(ebp+0x18) "invalid identifier '") +10159 (write-slice-buffered *(ebp+0x18) %ecx) +10160 (write-buffered *(ebp+0x18) "'\n") +10161 (flush *(ebp+0x18)) +10162 (stop *(ebp+0x1c) 1) +10163 # never gets here +10164 +10165 add-operation-and-inputs-to-stmt: # stmt: (addr stmt), line: (addr stream byte), vars: (addr stack live-var), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +10166 # pseudocode: +10167 # stmt->name = slice-to-string(next-mu-token(line)) +10168 # while true +10169 # name = next-mu-token(line) +10170 # v = lookup-var-or-literal(name) +10171 # stmt->inouts = append(v, stmt->inouts) +10172 # +10173 # . prologue +10174 55/push-ebp +10175 89/<- %ebp 4/r32/esp +10176 # . save registers +10177 50/push-eax +10178 51/push-ecx +10179 52/push-edx +10180 53/push-ebx +10181 56/push-esi +10182 57/push-edi +10183 # edi = stmt +10184 8b/-> *(ebp+8) 7/r32/edi +10185 # var name/ecx: slice +10186 68/push 0/imm32/end +10187 68/push 0/imm32/start +10188 89/<- %ecx 4/r32/esp +10189 # var is-deref?/edx: boolean = false +10190 ba/copy-to-edx 0/imm32/false +10191 # var v/esi: (handle var) +10192 68/push 0/imm32 +10193 68/push 0/imm32 +10194 89/<- %esi 4/r32/esp +10195 $add-operation-and-inputs-to-stmt:read-operation: +10196 (next-mu-token *(ebp+0xc) %ecx) +10197 8d/copy-address *(edi+4) 0/r32/eax # Stmt1-operation or Regvardef-operationStmt1-operation or Regvardef-operation +10198 (slice-to-string Heap %ecx %eax) +10199 # var is-get?/ebx: boolean = (name == "get") +10200 (slice-equal? %ecx "get") # => eax +10201 89/<- %ebx 0/r32/eax +10202 { +10203 $add-operation-and-inputs-to-stmt:read-inouts: +10204 # name = next-mu-token(line) +10205 (next-mu-token *(ebp+0xc) %ecx) +10206 # if slice-empty?(word-slice) break +10207 (slice-empty? %ecx) # => eax +10208 3d/compare-eax-and 0/imm32/false +10209 0f 85/jump-if-!= break/disp32 +10210 # if (name == "<-") abort +10211 (slice-equal? %ecx "<-") +10212 3d/compare-eax-and 0/imm32/false +10213 0f 85/jump-if-!= $add-operation-and-inputs-to-stmt:abort/disp32 +10214 # if (is-get? && second operand) lookup or create offset +10215 { +10216 81 7/subop/compare %ebx 0/imm32/false +10217 74/jump-if-= break/disp8 +10218 (lookup *(edi+0xc) *(edi+0x10)) # Stmt1-inouts Stmt1-inouts => eax +10219 3d/compare-eax-and 0/imm32 +10220 74/jump-if-= break/disp8 +10221 (lookup-or-create-constant %eax %ecx %esi) +10222 #? (lookup *esi *(esi+4)) +10223 #? (write-buffered Stderr "creating new output var ") +10224 #? (write-int32-hex-buffered Stderr %eax) +10225 #? (write-buffered Stderr " for field called ") +10226 #? (write-slice-buffered Stderr %ecx) +10227 #? (write-buffered Stderr "; var name ") +10228 #? (lookup *eax *(eax+4)) # Var-name +10229 #? (write-buffered Stderr %eax) +10230 #? (write-buffered Stderr Newline) +10231 #? (flush Stderr) +10232 e9/jump $add-operation-and-inputs-to-stmt:save-var/disp32 +10233 } +10234 # is-deref? = false +10235 ba/copy-to-edx 0/imm32/false +10236 # if (slice-starts-with?(name, '*')) ++name->start and set is-deref? +10237 8b/-> *ecx 0/r32/eax # Slice-start +10238 8a/copy-byte *eax 0/r32/AL +10239 81 4/subop/and %eax 0xff/imm32 +10240 3d/compare-eax-and 0x2a/imm32/asterisk +10241 { +10242 75/jump-if-!= break/disp8 +10243 $add-operation-and-inputs-to-stmt:inout-is-deref: +10244 ff 0/subop/increment *ecx +10245 ba/copy-to-edx 1/imm32/true +10246 } +10247 (lookup-var-or-literal %ecx *(ebp+0x10) %esi *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c)) +10248 $add-operation-and-inputs-to-stmt:save-var: +10249 8d/copy-address *(edi+0xc) 0/r32/eax +10250 (append-stmt-var Heap *esi *(esi+4) *(edi+0xc) *(edi+0x10) %edx %eax) # Stmt1-inouts or Regvardef-inouts +10251 # +10252 e9/jump loop/disp32 +10253 } +10254 $add-operation-and-inputs-to-stmt:end: +10255 # . reclaim locals +10256 81 0/subop/add %esp 0x10/imm32 +10257 # . restore registers +10258 5f/pop-to-edi +10259 5e/pop-to-esi +10260 5b/pop-to-ebx +10261 5a/pop-to-edx +10262 59/pop-to-ecx +10263 58/pop-to-eax +10264 # . epilogue +10265 89/<- %esp 5/r32/ebp +10266 5d/pop-to-ebp +10267 c3/return +10268 +10269 $add-operation-and-inputs-to-stmt:abort: +10270 # error("fn ___: invalid identifier in '" line "'\n") +10271 (write-buffered *(ebp+0x18) "fn ") +10272 8b/-> *(ebp+0x14) 0/r32/eax +10273 (lookup *eax *(eax+4)) # Function-name Function-name => eax +10274 (write-buffered *(ebp+0x18) %eax) +10275 (rewind-stream *(ebp+0xc)) +10276 (write-buffered *(ebp+0x18) ": invalid identifier in '") +10277 (write-stream-data *(ebp+0x18) *(ebp+0xc)) +10278 (write-buffered *(ebp+0x18) "'\n") +10279 (flush *(ebp+0x18)) +10280 (stop *(ebp+0x1c) 1) +10281 # never gets here +10282 +10283 stmt-has-outputs?: # line: (addr stream byte) -> result/eax: boolean +10284 # . prologue +10285 55/push-ebp +10286 89/<- %ebp 4/r32/esp +10287 # . save registers +10288 51/push-ecx +10289 # var word-slice/ecx: slice +10290 68/push 0/imm32/end +10291 68/push 0/imm32/start +10292 89/<- %ecx 4/r32/esp +10293 # result = false +10294 b8/copy-to-eax 0/imm32/false +10295 (rewind-stream *(ebp+8)) +10296 { +10297 (next-mu-token *(ebp+8) %ecx) +10298 # if slice-empty?(word-slice) break +10299 (slice-empty? %ecx) +10300 3d/compare-eax-and 0/imm32/false +10301 b8/copy-to-eax 0/imm32/false/result # restore result (if we're here it's still false) +10302 0f 85/jump-if-!= break/disp32 +10303 # if slice-starts-with?(word-slice, '#') break +10304 # . eax = *word-slice->start +10305 8b/-> *ecx 0/r32/eax +10306 8a/copy-byte *eax 0/r32/AL +10307 81 4/subop/and %eax 0xff/imm32 +10308 # . if (eax == '#') break +10309 3d/compare-eax-and 0x23/imm32/hash +10310 b8/copy-to-eax 0/imm32/false/result # restore result (if we're here it's still false) +10311 0f 84/jump-if-= break/disp32 +10312 # if slice-equal?(word-slice, '<-') return true +10313 (slice-equal? %ecx "<-") +10314 3d/compare-eax-and 0/imm32/false +10315 74/jump-if-= loop/disp8 +10316 b8/copy-to-eax 1/imm32/true +10317 } +10318 $stmt-has-outputs:end: +10319 (rewind-stream *(ebp+8)) +10320 # . reclaim locals +10321 81 0/subop/add %esp 8/imm32 +10322 # . restore registers +10323 59/pop-to-ecx +10324 # . epilogue +10325 89/<- %esp 5/r32/ebp +10326 5d/pop-to-ebp +10327 c3/return +10328 +10329 # if 'name' starts with a digit, create a new literal var for it +10330 # otherwise return first 'name' from the top (back) of 'vars' and abort if not found +10331 lookup-var-or-literal: # name: (addr slice), vars: (addr stack live-var), out: (addr handle var), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +10332 # . prologue +10333 55/push-ebp +10334 89/<- %ebp 4/r32/esp +10335 # . save registers +10336 50/push-eax +10337 51/push-ecx +10338 56/push-esi +10339 # esi = name +10340 8b/-> *(ebp+8) 6/r32/esi +10341 # if slice-empty?(name) abort +10342 (slice-empty? %esi) # => eax +10343 3d/compare-eax-and 0/imm32/false +10344 0f 85/jump-if-!= $lookup-var-or-literal:abort/disp32 +10345 # var c/ecx: byte = *name->start +10346 8b/-> *esi 1/r32/ecx +10347 8a/copy-byte *ecx 1/r32/CL +10348 81 4/subop/and %ecx 0xff/imm32 +10349 # if is-decimal-digit?(c) return new var(name) +10350 { +10351 (is-decimal-digit? %ecx) # => eax +10352 3d/compare-eax-and 0/imm32/false +10353 74/jump-if-= break/disp8 +10354 $lookup-var-or-literal:literal: +10355 (new-literal-integer Heap %esi *(ebp+0x10) *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c)) +10356 eb/jump $lookup-var-or-literal:end/disp8 +10357 } +10358 # else if (c == '"') return new var(name) +10359 { +10360 81 7/subop/compare %ecx 0x22/imm32/dquote +10361 75/jump-if-!= break/disp8 +10362 $lookup-var-or-literal:literal-string: +10363 (new-literal Heap %esi *(ebp+0x10)) +10364 eb/jump $lookup-var-or-literal:end/disp8 +10365 } +10366 # otherwise return lookup-var(name, vars) +10367 { +10368 $lookup-var-or-literal:var: +10369 (lookup-var %esi *(ebp+0xc) *(ebp+0x10) *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c)) +10370 } +10371 $lookup-var-or-literal:end: +10372 # . restore registers +10373 5e/pop-to-esi +10374 59/pop-to-ecx +10375 58/pop-to-eax +10376 # . epilogue +10377 89/<- %esp 5/r32/ebp +10378 5d/pop-to-ebp +10379 c3/return +10380 +10381 $lookup-var-or-literal:abort: +10382 (write-buffered *(ebp+0x18) "fn ") +10383 8b/-> *(ebp+0x14) 0/r32/eax +10384 (lookup *eax *(eax+4)) # Function-name Function-name => eax +10385 (write-buffered *(ebp+0x18) %eax) +10386 (write-buffered *(ebp+0x18) ": empty variable!") +10387 (flush *(ebp+0x18)) +10388 (stop *(ebp+0x1c) 1) +10389 # never gets here +10390 +10391 # return first 'name' from the top (back) of 'vars' and abort if not found +10392 lookup-var: # name: (addr slice), vars: (addr stack live-var), out: (addr handle var), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +10393 # . prologue +10394 55/push-ebp +10395 89/<- %ebp 4/r32/esp +10396 # . save registers +10397 50/push-eax +10398 # +10399 (lookup-var-helper *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c)) +10400 # if (*out == 0) abort +10401 8b/-> *(ebp+0x10) 0/r32/eax +10402 81 7/subop/compare *eax 0/imm32 +10403 74/jump-if-= $lookup-var:abort/disp8 +10404 $lookup-var:end: +10405 # . restore registers +10406 58/pop-to-eax +10407 # . epilogue +10408 89/<- %esp 5/r32/ebp +10409 5d/pop-to-ebp +10410 c3/return +10411 +10412 $lookup-var:abort: +10413 (write-buffered *(ebp+0x18) "fn ") +10414 8b/-> *(ebp+0x14) 0/r32/eax +10415 (lookup *eax *(eax+4)) # Function-name Function-name => eax +10416 (write-buffered *(ebp+0x18) %eax) +10417 (write-buffered *(ebp+0x18) ": unknown variable '") +10418 (write-slice-buffered *(ebp+0x18) *(ebp+8)) +10419 (write-buffered *(ebp+0x18) "'\n") +10420 (flush *(ebp+0x18)) +10421 (stop *(ebp+0x1c) 1) +10422 # never gets here +10423 +10424 # return first 'name' from the top (back) of 'vars', and 0/null if not found +10425 # ensure that 'name' if in a register is the topmost variable in that register +10426 lookup-var-helper: # name: (addr slice), vars: (addr stack live-var), out: (addr handle var), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +10427 # pseudocode: +10428 # var curr: (addr handle var) = &vars->data[vars->top - 12] +10429 # var min = vars->data +10430 # while curr >= min +10431 # var v: (handle var) = *curr +10432 # if v->name == name +10433 # return +10434 # curr -= 12 +10435 # +10436 # . prologue +10437 55/push-ebp +10438 89/<- %ebp 4/r32/esp +10439 # . save registers +10440 50/push-eax +10441 51/push-ecx +10442 52/push-edx +10443 53/push-ebx +10444 56/push-esi +10445 57/push-edi +10446 # clear out +10447 (zero-out *(ebp+0x10) *Handle-size) +10448 # esi = vars +10449 8b/-> *(ebp+0xc) 6/r32/esi +10450 # ebx = vars->top +10451 8b/-> *esi 3/r32/ebx +10452 # if (vars->top > vars->size) abort +10453 3b/compare<- *(esi+4) 0/r32/eax +10454 0f 8f/jump-if-> $lookup-var-helper:error1/disp32 +10455 # var min/edx: (addr handle var) = vars->data +10456 8d/copy-address *(esi+8) 2/r32/edx +10457 # var curr/ebx: (addr handle var) = &vars->data[vars->top - 12] +10458 8d/copy-address *(esi+ebx-4) 3/r32/ebx # vars + 8 + vars->type - 12 +10459 # var var-in-reg/edi: 8 addrs +10460 68/push 0/imm32 +10461 68/push 0/imm32 +10462 68/push 0/imm32 +10463 68/push 0/imm32 +10464 68/push 0/imm32 +10465 68/push 0/imm32 +10466 68/push 0/imm32 +10467 68/push 0/imm32 +10468 89/<- %edi 4/r32/esp +10469 { +10470 $lookup-var-helper:loop: +10471 # if (curr < min) return +10472 39/compare %ebx 2/r32/edx +10473 0f 82/jump-if-addr< break/disp32 +10474 # var v/ecx: (addr var) = lookup(*curr) +10475 (lookup *ebx *(ebx+4)) # => eax +10476 89/<- %ecx 0/r32/eax +10477 # var vn/eax: (addr array byte) = lookup(v->name) +10478 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax +10479 # if (vn == name) return curr +10480 (slice-equal? *(ebp+8) %eax) # => eax +10481 3d/compare-eax-and 0/imm32/false +10482 { +10483 74/jump-if-= break/disp8 +10484 $lookup-var-helper:found: +10485 # var vr/eax: (addr array byte) = lookup(v->register) +10486 (lookup *(ecx+0x18) *(ecx+0x1c)) # Var-register Var-register => eax +10487 3d/compare-eax-and 0/imm32 +10488 { +10489 74/jump-if-= break/disp8 +10490 $lookup-var-helper:found-register: +10491 # var reg/eax: int = get(Registers, vr) +10492 (get Mu-registers %eax 0xc "Mu-registers") # => eax +10493 8b/-> *eax 0/r32/eax +10494 # if (var-in-reg[reg]) error +10495 8b/-> *(edi+eax<<2) 0/r32/eax +10496 3d/compare-eax-and 0/imm32 +10497 0f 85/jump-if-!= $lookup-var-helper:error2/disp32 +10498 } +10499 $lookup-var-helper:return: +10500 # esi = out +10501 8b/-> *(ebp+0x10) 6/r32/esi +10502 # *out = *curr +10503 8b/-> *ebx 0/r32/eax +10504 89/<- *esi 0/r32/eax +10505 8b/-> *(ebx+4) 0/r32/eax +10506 89/<- *(esi+4) 0/r32/eax +10507 # return +10508 eb/jump $lookup-var-helper:end/disp8 +10509 } +10510 # 'name' not yet found; update var-in-reg if v in register +10511 # . var vr/eax: (addr array byte) = lookup(v->register) +10512 (lookup *(ecx+0x18) *(ecx+0x1c)) # Var-register Var-register => eax +10513 # . if (var == 0) continue +10514 3d/compare-eax-and 0/imm32 +10515 74/jump-if-= $lookup-var-helper:continue/disp8 +10516 # . var reg/eax: int = get(Registers, vr) +10517 (get Mu-registers %eax 0xc "Mu-registers") # => eax +10518 8b/-> *eax 0/r32/eax +10519 # . if (var-in-reg[reg] == 0) var-in-reg[reg] = v +10520 81 7/subop/compare *(edi+eax<<2) 0/imm32 +10521 75/jump-if-!= $lookup-var-helper:continue/disp8 +10522 89/<- *(edi+eax<<2) 1/r32/ecx +10523 $lookup-var-helper:continue: +10524 # curr -= 12 +10525 81 5/subop/subtract %ebx 0xc/imm32 +10526 e9/jump loop/disp32 +10527 } +10528 $lookup-var-helper:end: +10529 # . reclaim locals +10530 81 0/subop/add %esp 0x20/imm32 +10531 # . restore registers +10532 5f/pop-to-edi +10533 5e/pop-to-esi +10534 5b/pop-to-ebx +10535 5a/pop-to-edx +10536 59/pop-to-ecx +10537 58/pop-to-eax +10538 # . epilogue +10539 89/<- %esp 5/r32/ebp +10540 5d/pop-to-ebp +10541 c3/return +10542 +10543 $lookup-var-helper:error1: +10544 (write-buffered *(ebp+0x18) "fn ") +10545 8b/-> *(ebp+0x14) 0/r32/eax +10546 (lookup *eax *(eax+4)) # Function-name Function-name => eax +10547 (write-buffered *(ebp+0x18) %eax) +10548 (write-buffered *(ebp+0x18) ": malformed stack when looking up '") +10549 (write-slice-buffered *(ebp+0x18) *(ebp+8)) +10550 (write-buffered *(ebp+0x18) "'\n") +10551 (flush *(ebp+0x18)) +10552 (stop *(ebp+0x1c) 1) +10553 # never gets here +10554 +10555 $lookup-var-helper:error2: +10556 # eax contains the conflicting var at this point +10557 (write-buffered *(ebp+0x18) "fn ") +10558 50/push-eax +10559 8b/-> *(ebp+0x14) 0/r32/eax +10560 (lookup *eax *(eax+4)) # Function-name Function-name => eax +10561 (write-buffered *(ebp+0x18) %eax) +10562 58/pop-eax +10563 (write-buffered *(ebp+0x18) ": register ") +10564 50/push-eax +10565 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax +10566 (write-buffered *(ebp+0x18) %eax) +10567 58/pop-to-eax +10568 (write-buffered *(ebp+0x18) " reads var '") +10569 (write-slice-buffered *(ebp+0x18) *(ebp+8)) +10570 (write-buffered *(ebp+0x18) "' after writing var '") +10571 (lookup *eax *(eax+4)) # Var-name Var-name => eax +10572 (write-buffered *(ebp+0x18) %eax) +10573 (write-buffered *(ebp+0x18) "'\n") +10574 (flush *(ebp+0x18)) +10575 (stop *(ebp+0x1c) 1) +10576 # never gets here +10577 +10578 dump-vars: # vars: (addr stack live-var) +10579 # pseudocode: +10580 # var curr: (addr handle var) = &vars->data[vars->top - 12] +10581 # var min = vars->data +10582 # while curr >= min +10583 # var v: (handle var) = *curr +10584 # print v +10585 # curr -= 12 +10586 # +10587 # . prologue +10588 55/push-ebp +10589 89/<- %ebp 4/r32/esp +10590 # . save registers +10591 52/push-edx +10592 53/push-ebx +10593 56/push-esi +10594 # esi = vars +10595 8b/-> *(ebp+8) 6/r32/esi +10596 # ebx = vars->top +10597 8b/-> *esi 3/r32/ebx +10598 # var min/edx: (addr handle var) = vars->data +10599 8d/copy-address *(esi+8) 2/r32/edx +10600 # var curr/ebx: (addr handle var) = &vars->data[vars->top - 12] +10601 8d/copy-address *(esi+ebx-4) 3/r32/ebx # vars + 8 + vars->type - 12 +10602 { +10603 $dump-vars:loop: +10604 # if (curr < min) return +10605 39/compare %ebx 2/r32/edx +10606 0f 82/jump-if-addr< break/disp32 +10607 # +10608 (write-buffered Stderr " var@") +10609 (dump-var 2 %ebx) +10610 # curr -= 12 +10611 81 5/subop/subtract %ebx 0xc/imm32 +10612 e9/jump loop/disp32 +10613 } +10614 $dump-vars:end: +10615 # . restore registers +10616 5e/pop-to-esi +10617 5b/pop-to-ebx +10618 5a/pop-to-edx +10619 # . epilogue +10620 89/<- %esp 5/r32/ebp +10621 5d/pop-to-ebp +10622 c3/return +10623 +10624 == data +10625 # Like Registers, but no esp or ebp +10626 Mu-registers: # (addr stream {(handle array byte), int}) +10627 # a table is a stream +10628 0x48/imm32/write +10629 0/imm32/read +10630 0x48/imm32/length +10631 # data +10632 # it is perfectly ok to use fake alloc-ids -- as long as you never try to reclaim them +10633 0x11/imm32/alloc-id $Mu-register-eax/imm32 0/imm32 +10634 0x11/imm32/alloc-id $Mu-register-ecx/imm32 1/imm32 +10635 0x11/imm32/alloc-id $Mu-register-edx/imm32 2/imm32 +10636 0x11/imm32/alloc-id $Mu-register-ebx/imm32 3/imm32 +10637 0x11/imm32/alloc-id $Mu-register-esi/imm32 6/imm32 +10638 0x11/imm32/alloc-id $Mu-register-edi/imm32 7/imm32 +10639 +10640 $Mu-register-eax: +10641 0x11/imm32/alloc-id +10642 3/imm32/size +10643 0x65/e 0x61/a 0x78/x +10644 +10645 $Mu-register-ecx: +10646 0x11/imm32/alloc-id +10647 3/imm32/size +10648 0x65/e 0x63/c 0x78/x +10649 +10650 $Mu-register-edx: +10651 0x11/imm32/alloc-id +10652 3/imm32/size +10653 0x65/e 0x64/d 0x78/x +10654 +10655 $Mu-register-ebx: +10656 0x11/imm32/alloc-id +10657 3/imm32/size +10658 0x65/e 0x62/b 0x78/x +10659 +10660 $Mu-register-esi: +10661 0x11/imm32/alloc-id +10662 3/imm32/size +10663 0x65/e 0x73/s 0x69/i +10664 +10665 $Mu-register-edi: +10666 0x11/imm32/alloc-id +10667 3/imm32/size +10668 0x65/e 0x64/d 0x69/i +10669 +10670 == code +10671 +10672 # return first 'name' from the top (back) of 'vars' and create a new var for a fn output if not found +10673 lookup-var-or-find-in-fn-outputs: # name: (addr slice), vars: (addr stack live-var), fn: (addr function), out: (addr handle var), err: (addr buffered-file), ed: (addr exit-descriptor) +10674 # . prologue +10675 55/push-ebp +10676 89/<- %ebp 4/r32/esp +10677 # . save registers +10678 50/push-eax +10679 # +10680 (lookup-var-helper *(ebp+8) *(ebp+0xc) *(ebp+0x14) *(ebp+0x10) *(ebp+0x18) *(ebp+0x1c)) # arg order slightly different; 'fn' is deemphasized +10681 { +10682 # if (out != 0) return +10683 8b/-> *(ebp+0x14) 0/r32/eax +10684 81 7/subop/compare *eax 0/imm32 +10685 75/jump-if-!= break/disp8 +10686 # if name is one of fn's outputs, return it +10687 (find-in-function-outputs *(ebp+0x10) *(ebp+8) *(ebp+0x14)) +10688 8b/-> *(ebp+0x14) 0/r32/eax +10689 81 7/subop/compare *eax 0/imm32 +10690 # otherwise abort +10691 0f 84/jump-if-= $lookup-or-define-var:abort/disp32 +10692 } +10693 $lookup-or-define-var:end: +10694 # . restore registers +10695 58/pop-to-eax +10696 # . epilogue +10697 89/<- %esp 5/r32/ebp +10698 5d/pop-to-ebp +10699 c3/return +10700 +10701 $lookup-or-define-var:abort: +10702 (write-buffered *(ebp+0x18) "unknown variable '") +10703 (write-slice-buffered *(ebp+0x18) *(ebp+8)) +10704 (write-buffered *(ebp+0x18) "'\n") +10705 (flush *(ebp+0x18)) +10706 (stop *(ebp+0x1c) 1) +10707 # never gets here +10708 +10709 find-in-function-outputs: # fn: (addr function), name: (addr slice), out: (addr handle var) +10710 # . prologue +10711 55/push-ebp +10712 89/<- %ebp 4/r32/esp +10713 # . save registers +10714 50/push-eax +10715 51/push-ecx +10716 # var curr/ecx: (addr list var) = lookup(fn->outputs) +10717 8b/-> *(ebp+8) 1/r32/ecx +10718 (lookup *(ecx+0x10) *(ecx+0x14)) # Function-outputs Function-outputs => eax +10719 89/<- %ecx 0/r32/eax +10720 # while curr != null +10721 { +10722 81 7/subop/compare %ecx 0/imm32 +10723 74/jump-if-= break/disp8 +10724 # var v/eax: (addr var) = lookup(curr->value) +10725 (lookup *ecx *(ecx+4)) # List-value List-value => eax +10726 # var s/eax: (addr array byte) = lookup(v->name) +10727 (lookup *eax *(eax+4)) # Var-name Var-name => eax +10728 # if (s == name) return curr->value +10729 (slice-equal? *(ebp+0xc) %eax) # => eax +10730 3d/compare-eax-and 0/imm32/false +10731 { +10732 74/jump-if-= break/disp8 +10733 # var edi = out +10734 57/push-edi +10735 8b/-> *(ebp+0x10) 7/r32/edi +10736 # *out = curr->value +10737 8b/-> *ecx 0/r32/eax +10738 89/<- *edi 0/r32/eax +10739 8b/-> *(ecx+4) 0/r32/eax +10740 89/<- *(edi+4) 0/r32/eax +10741 # +10742 5f/pop-to-edi +10743 eb/jump $find-in-function-outputs:end/disp8 +10744 } +10745 # curr = curr->next +10746 (lookup *(ecx+8) *(ecx+0xc)) # List-next List-next => eax +10747 89/<- %ecx 0/r32/eax +10748 # +10749 eb/jump loop/disp8 +10750 } +10751 b8/copy-to-eax 0/imm32 +10752 $find-in-function-outputs:end: +10753 # . restore registers +10754 59/pop-to-ecx +10755 58/pop-to-eax +10756 # . epilogue +10757 89/<- %esp 5/r32/ebp +10758 5d/pop-to-ebp +10759 c3/return +10760 +10761 # push 'out' to 'vars' if not already there; it's assumed to be a fn output +10762 maybe-define-var: # out: (handle var), vars: (addr stack live-var) +10763 # . prologue +10764 55/push-ebp +10765 89/<- %ebp 4/r32/esp +10766 # . save registers +10767 50/push-eax +10768 # var out-addr/eax: (addr var) +10769 (lookup *(ebp+8) *(ebp+0xc)) # => eax +10770 # +10771 (binding-exists? %eax *(ebp+0x10)) # => eax +10772 3d/compare-eax-and 0/imm32/false +10773 75/jump-if-!= $maybe-define-var:end/disp8 +10774 # otherwise update vars +10775 (push *(ebp+0x10) *(ebp+8)) +10776 (push *(ebp+0x10) *(ebp+0xc)) +10777 (push *(ebp+0x10) 0) # 'out' is always a fn output; never spill it +10778 $maybe-define-var:end: +10779 # . restore registers +10780 58/pop-to-eax +10781 # . epilogue +10782 89/<- %esp 5/r32/ebp +10783 5d/pop-to-ebp +10784 c3/return +10785 +10786 # simpler version of lookup-var-helper +10787 binding-exists?: # target: (addr var), vars: (addr stack live-var) -> result/eax: boolean +10788 # pseudocode: +10789 # var curr: (addr handle var) = &vars->data[vars->top - 12] +10790 # var min = vars->data +10791 # while curr >= min +10792 # var v: (handle var) = *curr +10793 # if v->name == target->name +10794 # return true +10795 # curr -= 12 +10796 # return false +10797 # +10798 # . prologue +10799 55/push-ebp +10800 89/<- %ebp 4/r32/esp +10801 # . save registers +10802 51/push-ecx +10803 52/push-edx +10804 56/push-esi +10805 # var target-name/ecx: (addr array byte) = lookup(target->name) +10806 8b/-> *(ebp+8) 0/r32/eax +10807 (lookup *eax *(eax+4)) # Var-name Var-name => eax +10808 89/<- %ecx 0/r32/eax +10809 # esi = vars +10810 8b/-> *(ebp+0xc) 6/r32/esi +10811 # eax = vars->top +10812 8b/-> *esi 0/r32/eax +10813 # var min/edx: (addr handle var) = vars->data +10814 8d/copy-address *(esi+8) 2/r32/edx +10815 # var curr/esi: (addr handle var) = &vars->data[vars->top - 12] +10816 8d/copy-address *(esi+eax-4) 6/r32/esi # vars + 8 + vars->type - 12 +10817 { +10818 $binding-exists?:loop: +10819 # if (curr < min) return +10820 39/compare %esi 2/r32/edx +10821 0f 82/jump-if-addr< break/disp32 +10822 # var v/eax: (addr var) = lookup(*curr) +10823 (lookup *esi *(esi+4)) # => eax +10824 # var vn/eax: (addr array byte) = lookup(v->name) +10825 (lookup *eax *(eax+4)) # Var-name Var-name => eax +10826 # if (vn == target-name) return true +10827 (string-equal? %ecx %eax) # => eax +10828 3d/compare-eax-and 0/imm32/false +10829 75/jump-if-!= $binding-exists?:end/disp8 # eax already contains true +10830 # curr -= 12 +10831 81 5/subop/subtract %esi 0xc/imm32 +10832 e9/jump loop/disp32 +10833 } +10834 b8/copy-to-eax 0/imm32/false +10835 $binding-exists?:end: +10836 # . restore registers +10837 5e/pop-to-esi +10838 5a/pop-to-edx +10839 59/pop-to-ecx +10840 # . epilogue +10841 89/<- %esp 5/r32/ebp +10842 5d/pop-to-ebp +10843 c3/return +10844 +10845 test-parse-mu-stmt: +10846 # . prologue +10847 55/push-ebp +10848 89/<- %ebp 4/r32/esp +10849 # setup +10850 (clear-stream _test-input-stream) +10851 (write _test-input-stream "increment n\n") +10852 # var vars/ecx: (stack (addr var) 16) +10853 81 5/subop/subtract %esp 0xc0/imm32 +10854 68/push 0xc0/imm32/size +10855 68/push 0/imm32/top +10856 89/<- %ecx 4/r32/esp +10857 (clear-stack %ecx) +10858 # var v/edx: (handle var) +10859 68/push 0/imm32 +10860 68/push 0/imm32 +10861 89/<- %edx 4/r32/esp +10862 # var s/eax: (handle array byte) +10863 68/push 0/imm32 +10864 68/push 0/imm32 +10865 89/<- %eax 4/r32/esp +10866 # v = new var("n") +10867 (copy-array Heap "n" %eax) +10868 (new-var Heap *eax *(eax+4) %edx) +10869 # +10870 (push %ecx *edx) +10871 (push %ecx *(edx+4)) +10872 (push %ecx 0) +10873 # var out/eax: (handle stmt) +10874 68/push 0/imm32 +10875 68/push 0/imm32 +10876 89/<- %eax 4/r32/esp +10877 # convert +10878 (parse-mu-stmt _test-input-stream %ecx 0 %eax Stderr 0) +10879 # var out-addr/edx: (addr stmt) = lookup(*out) +10880 (lookup *eax *(eax+4)) # => eax +10881 89/<- %edx 0/r32/eax +10882 # out->tag +10883 (check-ints-equal *edx 1 "F - test-parse-mu-stmt/tag") # Stmt-tag is Stmt1 +10884 # out->operation +10885 (lookup *(edx+4) *(edx+8)) # Stmt1-operation Stmt1-operation => eax +10886 (check-strings-equal %eax "increment" "F - test-parse-mu-stmt/name") # Stmt1-operation +10887 # out->inouts->value->name +10888 # . eax = out->inouts +10889 (lookup *(edx+0xc) *(edx+0x10)) # Stmt1-inouts Stmt1-inouts => eax +10890 # . eax = out->inouts->value +10891 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +10892 # . eax = out->inouts->value->name +10893 (lookup *eax *(eax+4)) # Var-name Var-name => eax +10894 # . +10895 (check-strings-equal %eax "n" "F - test-parse-mu-stmt/inout:0") +10896 # . epilogue +10897 89/<- %esp 5/r32/ebp +10898 5d/pop-to-ebp +10899 c3/return +10900 +10901 test-parse-mu-stmt-with-comma: +10902 # . prologue +10903 55/push-ebp +10904 89/<- %ebp 4/r32/esp +10905 # setup +10906 (clear-stream _test-input-stream) +10907 (write _test-input-stream "copy-to n, 3\n") +10908 # var vars/ecx: (stack (addr var) 16) +10909 81 5/subop/subtract %esp 0xc0/imm32 +10910 68/push 0xc0/imm32/size +10911 68/push 0/imm32/top +10912 89/<- %ecx 4/r32/esp +10913 (clear-stack %ecx) +10914 # var v/edx: (handle var) +10915 68/push 0/imm32 +10916 68/push 0/imm32 +10917 89/<- %edx 4/r32/esp +10918 # var s/eax: (handle array byte) +10919 68/push 0/imm32 +10920 68/push 0/imm32 +10921 89/<- %eax 4/r32/esp +10922 # v = new var("n") +10923 (copy-array Heap "n" %eax) +10924 (new-var Heap *eax *(eax+4) %edx) +10925 # +10926 (push %ecx *edx) +10927 (push %ecx *(edx+4)) +10928 (push %ecx 0) +10929 # var out/eax: (handle stmt) +10930 68/push 0/imm32 +10931 68/push 0/imm32 +10932 89/<- %eax 4/r32/esp +10933 # convert +10934 (parse-mu-stmt _test-input-stream %ecx 0 %eax Stderr 0) +10935 # var out-addr/edx: (addr stmt) = lookup(*out) +10936 (lookup *eax *(eax+4)) # => eax +10937 89/<- %edx 0/r32/eax +10938 # out->tag +10939 (check-ints-equal *edx 1 "F - test-parse-mu-stmt-with-comma/tag") # Stmt-tag is Stmt1 +10940 # out->operation +10941 (lookup *(edx+4) *(edx+8)) # Stmt1-operation Stmt1-operation => eax +10942 (check-strings-equal %eax "copy-to" "F - test-parse-mu-stmt-with-comma/name") # Stmt1-operation +10943 # out->inouts->value->name +10944 # . eax = out->inouts +10945 (lookup *(edx+0xc) *(edx+0x10)) # Stmt1-inouts Stmt1-inouts => eax +10946 # . eax = out->inouts->value +10947 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +10948 # . eax = out->inouts->value->name +10949 (lookup *eax *(eax+4)) # Var-name Var-name => eax +10950 # . +10951 (check-strings-equal %eax "n" "F - test-parse-mu-stmt-with-comma/inout:0") +10952 # . epilogue +10953 89/<- %esp 5/r32/ebp +10954 5d/pop-to-ebp +10955 c3/return +10956 +10957 new-var: # ad: (addr allocation-descriptor), name: (handle array byte), out: (addr handle var) +10958 # . prologue +10959 55/push-ebp +10960 89/<- %ebp 4/r32/esp +10961 # . save registers +10962 50/push-eax +10963 51/push-ecx +10964 # ecx = out +10965 8b/-> *(ebp+0x14) 1/r32/ecx +10966 # +10967 (allocate *(ebp+8) *Var-size %ecx) +10968 # var out-addr/eax: (addr var) +10969 (lookup *ecx *(ecx+4)) # => eax +10970 # out-addr->name = name +10971 8b/-> *(ebp+0xc) 1/r32/ecx +10972 89/<- *eax 1/r32/ecx # Var-name +10973 8b/-> *(ebp+0x10) 1/r32/ecx +10974 89/<- *(eax+4) 1/r32/ecx # Var-name +10975 #? (write-buffered Stderr "var ") +10976 #? (lookup *(ebp+0xc) *(ebp+0x10)) +10977 #? (write-buffered Stderr %eax) +10978 #? (write-buffered Stderr " at ") +10979 #? 8b/-> *(ebp+0x14) 1/r32/ecx +10980 #? (lookup *ecx *(ecx+4)) # => eax +10981 #? (write-int32-hex-buffered Stderr %eax) +10982 #? (write-buffered Stderr Newline) +10983 #? (flush Stderr) +10984 $new-var:end: +10985 # . restore registers +10986 59/pop-to-ecx +10987 58/pop-to-eax +10988 # . epilogue +10989 89/<- %esp 5/r32/ebp +10990 5d/pop-to-ebp +10991 c3/return +10992 +10993 new-literal-integer: # ad: (addr allocation-descriptor), name: (addr slice), out: (addr handle var), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +10994 # . prologue +10995 55/push-ebp +10996 89/<- %ebp 4/r32/esp +10997 # . save registers +10998 50/push-eax +10999 51/push-ecx +11000 # if (!is-hex-int?(name)) abort +11001 (is-hex-int? *(ebp+0xc)) # => eax +11002 3d/compare-eax-and 0/imm32/false +11003 0f 84/jump-if-= $new-literal-integer:abort/disp32 +11004 # a little more error-checking +11005 (check-mu-hex-int *(ebp+0xc) *(ebp+0x18) *(ebp+0x1c)) +11006 # out = new var(s) +11007 (new-var-from-slice *(ebp+8) *(ebp+0xc) *(ebp+0x10)) +11008 # var out-addr/ecx: (addr var) = lookup(*out) +11009 8b/-> *(ebp+0x10) 0/r32/eax +11010 (lookup *eax *(eax+4)) # => eax +11011 89/<- %ecx 0/r32/eax +11012 # out-addr->block-depth = *Curr-block-depth +11013 8b/-> *Curr-block-depth 0/r32/eax +11014 89/<- *(ecx+0x10) 0/r32/eax # Var-block-depth +11015 # out-addr->type = new tree() +11016 8d/copy-address *(ecx+8) 0/r32/eax # Var-type +11017 (allocate *(ebp+8) *Type-tree-size %eax) +11018 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax +11019 c7 0/subop/copy *eax 1/imm32/true # Type-tree-is-atom +11020 # nothing else to do; default type is 'literal' +11021 $new-literal-integer:end: +11022 # . reclaim locals +11023 81 0/subop/add %esp 8/imm32 +11024 # . restore registers +11025 59/pop-to-ecx +11026 58/pop-to-eax +11027 # . epilogue +11028 89/<- %esp 5/r32/ebp +11029 5d/pop-to-ebp +11030 c3/return +11031 +11032 $new-literal-integer:abort: +11033 (write-buffered *(ebp+0x18) "fn ") +11034 8b/-> *(ebp+0x14) 0/r32/eax +11035 (lookup *eax *(eax+4)) # Function-name Function-name => eax +11036 (write-buffered *(ebp+0x18) %eax) +11037 (write-buffered *(ebp+0x18) ": variable '") +11038 (write-slice-buffered *(ebp+0x18) *(ebp+0xc)) +11039 (write-buffered *(ebp+0x18) "' cannot begin with a digit (or do you have a typo in a number?)\n") +11040 (flush *(ebp+0x18)) +11041 (stop *(ebp+0x1c) 1) +11042 # never gets here +11043 +11044 # precondition: name is a valid hex integer; require a '0x' prefix +11045 check-mu-hex-int: # name: (addr slice), err: (addr buffered-file), ed: (addr exit-descriptor) +11046 # . prologue +11047 55/push-ebp +11048 89/<- %ebp 4/r32/esp +11049 # . save registers +11050 50/push-eax +11051 51/push-ecx +11052 52/push-edx +11053 # +11054 8b/-> *(ebp+8) 1/r32/ecx +11055 # var start/ecx: (addr byte) = name->start +11056 8b/-> *(ecx+4) 2/r32/edx +11057 # var end/ecx: (addr byte) = name->end +11058 8b/-> *ecx 1/r32/ecx +11059 # var len/eax: int = name->end - name->start +11060 89/<- %eax 2/r32/edx +11061 29/subtract-from %eax 1/r32/ecx +11062 # if (len <= 1) return +11063 3d/compare-eax-with 1/imm32 +11064 0f 8e/jump-if-<= $check-mu-hex-int:end/disp32 +11065 $check-mu-hex-int:length->-1: +11066 # if slice-starts-with?("0x") return +11067 (slice-starts-with? *(ebp+8) "0x") # => eax +11068 3d/compare-eax-with 0/imm32/false +11069 75/jump-if-!= $check-mu-hex-int:end/disp8 +11070 $check-mu-hex-int:abort: +11071 # otherwise abort +11072 (write-buffered *(ebp+0xc) "literal integers are always hex in Mu; either start '") +11073 (write-slice-buffered *(ebp+0xc) *(ebp+8)) +11074 (write-buffered *(ebp+0xc) "' with a '0x' to be unambiguous, or convert it to decimal.\n") +11075 (flush *(ebp+0xc)) +11076 (stop *(ebp+0x10) 1) +11077 $check-mu-hex-int:end: +11078 # . restore registers +11079 5a/pop-to-edx +11080 59/pop-to-ecx +11081 58/pop-to-eax +11082 # . epilogue +11083 89/<- %esp 5/r32/ebp +11084 5d/pop-to-ebp +11085 c3/return +11086 +11087 new-literal: # ad: (addr allocation-descriptor), name: (addr slice), out: (addr handle var) +11088 # . prologue +11089 55/push-ebp +11090 89/<- %ebp 4/r32/esp +11091 # . save registers +11092 50/push-eax +11093 51/push-ecx +11094 # var s/ecx: (handle array byte) +11095 68/push 0/imm32 +11096 68/push 0/imm32 +11097 89/<- %ecx 4/r32/esp +11098 # s = slice-to-string(name) +11099 (slice-to-string Heap *(ebp+0xc) %ecx) +11100 # allocate to out +11101 (new-var *(ebp+8) *ecx *(ecx+4) *(ebp+0x10)) +11102 # var out-addr/ecx: (addr var) = lookup(*out) +11103 8b/-> *(ebp+0x10) 1/r32/ecx +11104 (lookup *ecx *(ecx+4)) # => eax +11105 89/<- %ecx 0/r32/eax +11106 # out-addr->block-depth = *Curr-block-depth +11107 8b/-> *Curr-block-depth 0/r32/eax +11108 89/<- *(ecx+0x10) 0/r32/eax # Var-block-depth +11109 # out-addr->type/eax = new type +11110 8d/copy-address *(ecx+8) 0/r32/eax # Var-type +11111 (allocate *(ebp+8) *Type-tree-size %eax) +11112 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax +11113 # nothing else to do; default type is 'literal' +11114 c7 0/subop/copy *eax 1/imm32/true # Type-tree-is-atom +11115 $new-literal:end: +11116 # . reclaim locals +11117 81 0/subop/add %esp 8/imm32 +11118 # . restore registers +11119 59/pop-to-ecx +11120 58/pop-to-eax +11121 # . epilogue +11122 89/<- %esp 5/r32/ebp +11123 5d/pop-to-ebp +11124 c3/return +11125 +11126 new-var-from-slice: # ad: (addr allocation-descriptor), name: (addr slice), out: (addr handle var) +11127 # . prologue +11128 55/push-ebp +11129 89/<- %ebp 4/r32/esp +11130 # . save registers +11131 51/push-ecx +11132 # var tmp/ecx: (handle array byte) +11133 68/push 0/imm32 +11134 68/push 0/imm32 +11135 89/<- %ecx 4/r32/esp +11136 # tmp = slice-to-string(name) +11137 (slice-to-string Heap *(ebp+0xc) %ecx) +11138 # out = new-var(tmp) +11139 (new-var *(ebp+8) *ecx *(ecx+4) *(ebp+0x10)) +11140 $new-var-from-slice:end: +11141 # . reclaim locals +11142 81 0/subop/add %esp 8/imm32 +11143 # . restore registers +11144 59/pop-to-ecx +11145 # . epilogue +11146 89/<- %esp 5/r32/ebp +11147 5d/pop-to-ebp +11148 c3/return +11149 +11150 new-var-def: # ad: (addr allocation-descriptor), var: (handle var), out: (addr handle stmt) +11151 # . prologue +11152 55/push-ebp +11153 89/<- %ebp 4/r32/esp +11154 # . save registers +11155 50/push-eax +11156 51/push-ecx +11157 # +11158 (allocate *(ebp+8) *Stmt-size *(ebp+0x14)) +11159 # var out-addr/eax: (addr stmt) = lookup(*out) +11160 8b/-> *(ebp+0x14) 0/r32/eax +11161 (lookup *eax *(eax+4)) # => eax +11162 # out-addr->tag = stmt +11163 c7 0/subop/copy *eax 2/imm32/tag/var-on-stack # Stmt-tag +11164 # result->var = var +11165 8b/-> *(ebp+0xc) 1/r32/ecx +11166 89/<- *(eax+4) 1/r32/ecx # Vardef-var +11167 8b/-> *(ebp+0x10) 1/r32/ecx +11168 89/<- *(eax+8) 1/r32/ecx # Vardef-var +11169 $new-var-def:end: +11170 # . restore registers +11171 59/pop-to-ecx +11172 58/pop-to-eax +11173 # . epilogue +11174 89/<- %esp 5/r32/ebp +11175 5d/pop-to-ebp +11176 c3/return +11177 +11178 new-reg-var-def: # ad: (addr allocation-descriptor), var: (handle var), out: (addr handle stmt) +11179 # . prologue +11180 55/push-ebp +11181 89/<- %ebp 4/r32/esp +11182 # . save registers +11183 50/push-eax +11184 # eax = out +11185 8b/-> *(ebp+0x14) 0/r32/eax +11186 # +11187 (allocate *(ebp+8) *Stmt-size %eax) +11188 # var out-addr/eax: (addr stmt) = lookup(*out) +11189 (lookup *eax *(eax+4)) # => eax +11190 # set tag +11191 c7 0/subop/copy *eax 3/imm32/tag/var-in-register # Stmt-tag +11192 # set output +11193 8d/copy-address *(eax+0x14) 0/r32/eax # Regvardef-outputs +11194 (append-stmt-var Heap *(ebp+0xc) *(ebp+0x10) 0 0 0 %eax) +11195 $new-reg-var-def:end: +11196 # . restore registers +11197 58/pop-to-eax +11198 # . epilogue +11199 89/<- %esp 5/r32/ebp +11200 5d/pop-to-ebp +11201 c3/return +11202 +11203 append-list: # ad: (addr allocation-descriptor), value: (handle _type), list: (handle list _type), out: (addr handle list _type) +11204 # . prologue +11205 55/push-ebp +11206 89/<- %ebp 4/r32/esp +11207 # . save registers +11208 50/push-eax 11209 51/push-ecx -11210 # var out/ecx: (handle typeinfo) -11211 68/push 0/imm32 -11212 68/push 0/imm32 -11213 89/<- %ecx 4/r32/esp -11214 # eax = t -11215 8b/-> *(ebp+8) 0/r32/eax -11216 # if t is a literal, return 0 -11217 3d/compare-eax-and 0/imm32/literal -11218 0f 84/jump-if-= $compute-size-of-type-id:end/disp32 # eax changes type from type-id to int -11219 # if t is a byte, return 4 (because we don't really support non-multiples of 4) -11220 3d/compare-eax-and 8/imm32/byte -11221 { -11222 75/jump-if-!= break/disp8 -11223 b8/copy-to-eax 4/imm32 -11224 eb/jump $compute-size-of-type-id:end/disp8 -11225 } -11226 # if t is a handle, return 8 -11227 3d/compare-eax-and 4/imm32/handle -11228 { -11229 75/jump-if-!= break/disp8 -11230 b8/copy-to-eax 8/imm32 -11231 eb/jump $compute-size-of-type-id:end/disp8 # eax changes type from type-id to int -11232 } -11233 # if t is a slice, return 8 -11234 3d/compare-eax-and 0xc/imm32/slice -11235 { -11236 75/jump-if-!= break/disp8 -11237 b8/copy-to-eax 8/imm32 -11238 eb/jump $compute-size-of-type-id:end/disp8 # eax changes type from type-id to int -11239 } -11240 # if t is a user-defined type, compute its size -11241 # TODO: support non-atom type -11242 (find-typeinfo %eax %ecx) -11243 { -11244 81 7/subop/compare *ecx 0/imm32 -11245 74/jump-if-= break/disp8 -11246 $compute-size-of-type-id:user-defined: -11247 (lookup *ecx *(ecx+4)) # => eax -11248 (populate-mu-type-sizes-in-type %eax *(ebp+0xc) *(ebp+0x10)) -11249 8b/-> *(eax+0xc) 0/r32/eax # Typeinfo-total-size-in-bytes -11250 eb/jump $compute-size-of-type-id:end/disp8 -11251 } -11252 # otherwise return the word size -11253 b8/copy-to-eax 4/imm32 -11254 $compute-size-of-type-id:end: -11255 # . reclaim locals -11256 81 0/subop/add %esp 8/imm32 -11257 # . restore registers -11258 59/pop-to-ecx -11259 # . epilogue -11260 89/<- %esp 5/r32/ebp -11261 5d/pop-to-ebp -11262 c3/return -11263 -11264 # at this point we have total sizes for all user-defined types -11265 # compute offsets for each element -11266 # complication: fields may be out of order -11267 populate-mu-type-offsets: # in: (addr typeinfo), err: (addr buffered-file), ed: (addr exit-descriptor) -11268 # . prologue -11269 55/push-ebp -11270 89/<- %ebp 4/r32/esp -11271 # . save registers -11272 50/push-eax -11273 51/push-ecx -11274 52/push-edx -11275 53/push-ebx -11276 56/push-esi -11277 57/push-edi -11278 #? (dump-typeinfos "aaa\n") -11279 # var curr-offset/edi: int = 0 -11280 bf/copy-to-edi 0/imm32 -11281 # var table/ecx: (addr table string_key (handle typeinfo-entry)) = lookup(in->fields) -11282 8b/-> *(ebp+8) 1/r32/ecx -11283 (lookup *(ecx+4) *(ecx+8)) # Typeinfo-fields Typeinfo-fields => eax -11284 89/<- %ecx 0/r32/eax -11285 # var num-elems/edx: int = table->write / Typeinfo-fields-row-size -11286 8b/-> *ecx 2/r32/edx # stream-write -11287 c1 5/subop/shift-right-logical %edx 4/imm8 -11288 # var i/ebx: int = 0 -11289 bb/copy-to-ebx 0/imm32 -11290 { -11291 $populate-mu-type-offsets:loop: -11292 39/compare %ebx 2/r32/edx -11293 0f 8d/jump-if->= break/disp32 -11294 #? (write-buffered Stderr "looking up index ") -11295 #? (write-int32-hex-buffered Stderr %ebx) -11296 #? (write-buffered Stderr " in ") -11297 #? (write-int32-hex-buffered Stderr *(ebp+8)) -11298 #? (write-buffered Stderr Newline) -11299 #? (flush Stderr) -11300 # var v/esi: (addr typeinfo-entry) -11301 (locate-typeinfo-entry-with-index %ecx %ebx *(ebp+0xc) *(ebp+0x10)) # => eax -11302 89/<- %esi 0/r32/eax -11303 # if v is null, silently move on; we'll emit a nice error message while type-checking -11304 81 7/subop/compare %esi 0/imm32 # Typeinfo-entry-input-var -11305 74/jump-if-= $populate-mu-type-offsets:end/disp8 -11306 # if (v->input-var == 0) silently ignore v; we'll emit a nice error message while type-checking -11307 81 7/subop/compare *esi 0/imm32 # Typeinfo-entry-input-var -11308 74/jump-if-= $populate-mu-type-offsets:end/disp8 -11309 # v->output-var->offset = curr-offset -11310 # . eax: (addr var) -11311 (lookup *(esi+0xc) *(esi+0x10)) # Typeinfo-entry-output-var Typeinfo-entry-output-var => eax -11312 89/<- *(eax+0x14) 7/r32/edi # Var-offset -11313 # curr-offset += size-of(v->input-var) -11314 (lookup *esi *(esi+4)) # Typeinfo-entry-input-var Typeinfo-entry-input-var => eax -11315 (size-of %eax) # => eax -11316 01/add-to %edi 0/r32/eax -11317 # ++i -11318 43/increment-ebx -11319 e9/jump loop/disp32 -11320 } -11321 $populate-mu-type-offsets:end: -11322 # . restore registers -11323 5f/pop-to-edi -11324 5e/pop-to-esi -11325 5b/pop-to-ebx -11326 5a/pop-to-edx -11327 59/pop-to-ecx -11328 58/pop-to-eax -11329 # . epilogue -11330 89/<- %esp 5/r32/ebp -11331 5d/pop-to-ebp -11332 c3/return -11333 -11334 locate-typeinfo-entry-with-index: # table: (addr table (handle array byte) (handle typeinfo-entry)), idx: int, err: (addr buffered-file), ed: (addr exit-descriptor) -> result/eax: (addr typeinfo-entry) -11335 # . prologue -11336 55/push-ebp -11337 89/<- %ebp 4/r32/esp -11338 # . save registers -11339 51/push-ecx -11340 52/push-edx -11341 53/push-ebx -11342 56/push-esi -11343 57/push-edi -11344 # esi = table -11345 8b/-> *(ebp+8) 6/r32/esi -11346 # var curr/ecx: (addr row (handle array byte) (handle typeinfo-entry)) = table->data -11347 8d/copy-address *(esi+0xc) 1/r32/ecx -11348 # var max/edx: (addr byte) = &table->data[table->write] -11349 8b/-> *esi 2/r32/edx -11350 8d/copy-address *(ecx+edx) 2/r32/edx -11351 { -11352 $locate-typeinfo-entry-with-index:loop: -11353 39/compare %ecx 2/r32/edx -11354 73/jump-if-addr>= break/disp8 -11355 # var v/eax: (addr typeinfo-entry) -11356 (lookup *(ecx+8) *(ecx+0xc)) # => eax -11357 # if (v->index == idx) return v -11358 8b/-> *(eax+8) 3/r32/ebx # Typeinfo-entry-index -11359 #? (write-buffered Stderr "comparing ") -11360 #? (write-int32-hex-buffered Stderr %ebx) -11361 #? (write-buffered Stderr " and ") -11362 #? (write-int32-hex-buffered Stderr *(ebp+0xc)) -11363 #? (write-buffered Stderr Newline) -11364 #? (flush Stderr) -11365 39/compare *(ebp+0xc) 3/r32/ebx -11366 74/jump-if-= $locate-typeinfo-entry-with-index:end/disp8 -11367 # curr += Typeinfo-entry-size -11368 81 0/subop/add %ecx 0x10/imm32 # Typeinfo-entry-size -11369 # -11370 eb/jump loop/disp8 -11371 } -11372 # return 0 -11373 b8/copy-to-eax 0/imm32 -11374 $locate-typeinfo-entry-with-index:end: -11375 #? (write-buffered Stderr "returning ") -11376 #? (write-int32-hex-buffered Stderr %eax) -11377 #? (write-buffered Stderr Newline) -11378 #? (flush Stderr) -11379 # . restore registers -11380 5f/pop-to-edi -11381 5e/pop-to-esi -11382 5b/pop-to-ebx -11383 5a/pop-to-edx -11384 59/pop-to-ecx -11385 # . epilogue -11386 89/<- %esp 5/r32/ebp -11387 5d/pop-to-ebp -11388 c3/return -11389 -11390 dump-typeinfos: # hdr: (addr array byte) -11391 # . prologue -11392 55/push-ebp -11393 89/<- %ebp 4/r32/esp -11394 # . save registers -11395 50/push-eax -11396 # -11397 (write-buffered Stderr *(ebp+8)) -11398 (flush Stderr) -11399 # var curr/eax: (addr typeinfo) = lookup(Program->types) -11400 (lookup *_Program-types *_Program-types->payload) # => eax -11401 { -11402 # if (curr == null) break -11403 3d/compare-eax-and 0/imm32 -11404 74/jump-if-= break/disp8 -11405 (write-buffered Stderr "---\n") -11406 (flush Stderr) -11407 (dump-typeinfo %eax) -11408 # curr = lookup(curr->next) -11409 (lookup *(eax+0x10) *(eax+0x14)) # Typeinfo-next Typeinfo-next => eax -11410 eb/jump loop/disp8 -11411 } -11412 $dump-typeinfos:end: -11413 # . restore registers -11414 58/pop-to-eax -11415 # . epilogue -11416 89/<- %esp 5/r32/ebp -11417 5d/pop-to-ebp -11418 c3/return -11419 -11420 dump-typeinfo: # in: (addr typeinfo) -11421 # . prologue -11422 55/push-ebp -11423 89/<- %ebp 4/r32/esp -11424 # . save registers -11425 50/push-eax -11426 51/push-ecx -11427 52/push-edx -11428 53/push-ebx -11429 56/push-esi -11430 57/push-edi -11431 # esi = in -11432 8b/-> *(ebp+8) 6/r32/esi -11433 # var table/ecx: (addr table (handle array byte) (handle typeinfo-entry)) = lookup(T->fields) -11434 (lookup *(esi+4) *(esi+8)) # Typeinfo-fields Typeinfo-fields => eax -11435 89/<- %ecx 0/r32/eax -11436 (write-buffered Stderr "id:") -11437 (write-int32-hex-buffered Stderr *esi) -11438 (write-buffered Stderr "\n") -11439 (write-buffered Stderr "fields @ ") -11440 (write-int32-hex-buffered Stderr %ecx) -11441 (write-buffered Stderr Newline) -11442 (flush Stderr) -11443 (write-buffered Stderr " write: ") -11444 (write-int32-hex-buffered Stderr *ecx) -11445 (write-buffered Stderr Newline) -11446 (flush Stderr) -11447 (write-buffered Stderr " read: ") -11448 (write-int32-hex-buffered Stderr *(ecx+4)) -11449 (write-buffered Stderr Newline) -11450 (flush Stderr) -11451 (write-buffered Stderr " size: ") -11452 (write-int32-hex-buffered Stderr *(ecx+8)) -11453 (write-buffered Stderr Newline) -11454 (flush Stderr) -11455 # var table-size/edx: int = table->write -11456 8b/-> *ecx 2/r32/edx # stream-write -11457 # var curr/ecx: (addr table_row) = table->data -11458 8d/copy-address *(ecx+0xc) 1/r32/ecx -11459 # var max/edx: (addr table_row) = table->data + table->write -11460 8d/copy-address *(ecx+edx) 2/r32/edx -11461 { -11462 $dump-typeinfo:loop: -11463 # if (curr >= max) break -11464 39/compare %ecx 2/r32/edx -11465 0f 83/jump-if-addr>= break/disp32 -11466 (write-buffered Stderr " row:\n") -11467 (write-buffered Stderr " key: ") -11468 (write-int32-hex-buffered Stderr *ecx) -11469 (write-buffered Stderr ",") -11470 (write-int32-hex-buffered Stderr *(ecx+4)) -11471 (write-buffered Stderr " = '") -11472 (lookup *ecx *(ecx+4)) -11473 (write-buffered Stderr %eax) -11474 (write-buffered Stderr "' @ ") -11475 (write-int32-hex-buffered Stderr %eax) -11476 (write-buffered Stderr Newline) -11477 (flush Stderr) -11478 (write-buffered Stderr " value: ") -11479 (write-int32-hex-buffered Stderr *(ecx+8)) -11480 (write-buffered Stderr ",") -11481 (write-int32-hex-buffered Stderr *(ecx+0xc)) -11482 (write-buffered Stderr " = typeinfo-entry@") -11483 (lookup *(ecx+8) *(ecx+0xc)) -11484 (write-int32-hex-buffered Stderr %eax) -11485 (write-buffered Stderr Newline) -11486 (flush Stderr) -11487 (write-buffered Stderr " input var@") -11488 (dump-var 5 %eax) -11489 (lookup *(ecx+8) *(ecx+0xc)) -11490 (write-buffered Stderr " index: ") -11491 (write-int32-hex-buffered Stderr *(eax+8)) -11492 (write-buffered Stderr Newline) -11493 (flush Stderr) -11494 (write-buffered Stderr " output var@") -11495 8d/copy-address *(eax+0xc) 0/r32/eax # Typeinfo-entry-output-var -11496 (dump-var 5 %eax) -11497 (flush Stderr) -11498 # curr += row-size -11499 81 0/subop/add %ecx 0x10/imm32 # Typeinfo-fields-row-size -11500 # -11501 e9/jump loop/disp32 -11502 } -11503 $dump-typeinfo:end: -11504 # . restore registers -11505 5f/pop-to-edi -11506 5e/pop-to-esi -11507 5b/pop-to-ebx -11508 5a/pop-to-edx -11509 59/pop-to-ecx -11510 58/pop-to-eax -11511 # . epilogue -11512 89/<- %esp 5/r32/ebp -11513 5d/pop-to-ebp -11514 c3/return -11515 -11516 dump-var: # indent: int, v: (addr handle var) -11517 # . prologue -11518 55/push-ebp -11519 89/<- %ebp 4/r32/esp -11520 # . save registers -11521 50/push-eax -11522 53/push-ebx -11523 # eax = v -11524 8b/-> *(ebp+0xc) 0/r32/eax -11525 # -11526 (write-int32-hex-buffered Stderr *eax) -11527 (write-buffered Stderr ",") -11528 (write-int32-hex-buffered Stderr *(eax+4)) -11529 (write-buffered Stderr "->") -11530 (lookup *eax *(eax+4)) -11531 (write-int32-hex-buffered Stderr %eax) -11532 (write-buffered Stderr Newline) -11533 (flush Stderr) -11534 { -11535 3d/compare-eax-and 0/imm32 -11536 0f 84/jump-if-= break/disp32 -11537 (emit-indent Stderr *(ebp+8)) -11538 (write-buffered Stderr "name: ") -11539 89/<- %ebx 0/r32/eax -11540 (write-int32-hex-buffered Stderr *ebx) # Var-name -11541 (write-buffered Stderr ",") -11542 (write-int32-hex-buffered Stderr *(ebx+4)) # Var-name -11543 (write-buffered Stderr "->") -11544 (lookup *ebx *(ebx+4)) # Var-name -11545 (write-int32-hex-buffered Stderr %eax) -11546 { -11547 3d/compare-eax-and 0/imm32 -11548 74/jump-if-= break/disp8 -11549 (write-buffered Stderr Space) -11550 (write-buffered Stderr %eax) -11551 } -11552 (write-buffered Stderr Newline) -11553 (flush Stderr) -11554 (emit-indent Stderr *(ebp+8)) -11555 (write-buffered Stderr "block depth: ") -11556 (write-int32-hex-buffered Stderr *(ebx+0x10)) # Var-block-depth -11557 (write-buffered Stderr Newline) -11558 (flush Stderr) -11559 (emit-indent Stderr *(ebp+8)) -11560 (write-buffered Stderr "stack offset: ") -11561 (write-int32-hex-buffered Stderr *(ebx+0x14)) # Var-offset -11562 (write-buffered Stderr Newline) -11563 (flush Stderr) -11564 (emit-indent Stderr *(ebp+8)) -11565 (write-buffered Stderr "reg: ") -11566 (write-int32-hex-buffered Stderr *(ebx+0x18)) # Var-register -11567 (write-buffered Stderr ",") -11568 (write-int32-hex-buffered Stderr *(ebx+0x1c)) # Var-register -11569 (write-buffered Stderr "->") -11570 (flush Stderr) -11571 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register -11572 (write-int32-hex-buffered Stderr %eax) -11573 { -11574 3d/compare-eax-and 0/imm32 -11575 74/jump-if-= break/disp8 -11576 (write-buffered Stderr Space) -11577 (write-buffered Stderr %eax) -11578 } -11579 (write-buffered Stderr Newline) -11580 (flush Stderr) -11581 } -11582 $dump-var:end: -11583 # . restore registers -11584 5b/pop-to-ebx -11585 58/pop-to-eax -11586 # . epilogue -11587 89/<- %esp 5/r32/ebp -11588 5d/pop-to-ebp -11589 c3/return -11590 -11591 ####################################################### -11592 # Type-checking -11593 ####################################################### -11594 -11595 check-mu-types: # err: (addr buffered-file), ed: (addr exit-descriptor) -11596 # . prologue -11597 55/push-ebp -11598 89/<- %ebp 4/r32/esp -11599 # . save registers -11600 50/push-eax -11601 # var curr/eax: (addr function) = lookup(Program->functions) -11602 (lookup *_Program-functions *_Program-functions->payload) # => eax -11603 { -11604 $check-mu-types:loop: -11605 # if (curr == null) break -11606 3d/compare-eax-and 0/imm32 -11607 0f 84/jump-if-= break/disp32 -11608 +-- 8 lines: #? # dump curr->name ------------------------------------------------------------------------------------------------------------------------------------------------ -11616 (check-mu-function %eax *(ebp+8) *(ebp+0xc)) -11617 # curr = lookup(curr->next) -11618 (lookup *(eax+0x20) *(eax+0x24)) # Function-next Function-next => eax -11619 e9/jump loop/disp32 -11620 } -11621 $check-mu-types:end: -11622 # . restore registers -11623 58/pop-to-eax -11624 # . epilogue -11625 89/<- %esp 5/r32/ebp -11626 5d/pop-to-ebp -11627 c3/return -11628 -11629 check-mu-function: # fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -11630 # . prologue -11631 55/push-ebp -11632 89/<- %ebp 4/r32/esp -11633 # . save registers -11634 50/push-eax -11635 # eax = f -11636 8b/-> *(ebp+8) 0/r32/eax -11637 # TODO: anything to check in header? -11638 # var body/eax: (addr block) = lookup(f->body) -11639 (lookup *(eax+0x18) *(eax+0x1c)) # Function-body Function-body => eax -11640 (check-mu-block %eax *(ebp+8) *(ebp+0xc) *(ebp+0x10)) -11641 $check-mu-function:end: -11642 # . restore registers -11643 58/pop-to-eax -11644 # . epilogue -11645 89/<- %esp 5/r32/ebp -11646 5d/pop-to-ebp -11647 c3/return -11648 -11649 check-mu-block: # block: (addr block), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -11650 # . prologue -11651 55/push-ebp -11652 89/<- %ebp 4/r32/esp -11653 # . save registers -11654 50/push-eax -11655 # eax = block -11656 8b/-> *(ebp+8) 0/r32/eax -11657 # var stmts/eax: (addr list stmt) = lookup(block->statements) -11658 (lookup *(eax+4) *(eax+8)) # Block-stmts Block-stmts => eax -11659 # -11660 { -11661 $check-mu-block:check-empty: -11662 3d/compare-eax-and 0/imm32 -11663 0f 84/jump-if-= break/disp32 -11664 # emit block->statements -11665 (check-mu-stmt-list %eax *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -11666 } -11667 $check-mu-block:end: -11668 # . restore registers -11669 58/pop-to-eax -11670 # . epilogue -11671 89/<- %esp 5/r32/ebp -11672 5d/pop-to-ebp -11673 c3/return -11674 -11675 check-mu-stmt-list: # stmts: (addr list stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -11676 # . prologue -11677 55/push-ebp -11678 89/<- %ebp 4/r32/esp -11679 # . save registers -11680 50/push-eax -11681 56/push-esi -11682 # esi = stmts -11683 8b/-> *(ebp+8) 6/r32/esi -11684 { -11685 $check-mu-stmt-list:loop: -11686 81 7/subop/compare %esi 0/imm32 -11687 0f 84/jump-if-= break/disp32 -11688 # var curr-stmt/eax: (addr stmt) = lookup(stmts->value) -11689 (lookup *esi *(esi+4)) # List-value List-value => eax -11690 { -11691 $check-mu-stmt-list:check-for-block: -11692 81 7/subop/compare *eax 0/imm32/block # Stmt-tag -11693 75/jump-if-!= break/disp8 -11694 $check-mu-stmt-list:block: -11695 (check-mu-block %eax *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -11696 eb/jump $check-mu-stmt-list:continue/disp8 -11697 } -11698 { -11699 $check-mu-stmt-list:check-for-stmt1: -11700 81 7/subop/compare *eax 1/imm32/stmt1 # Stmt-tag -11701 0f 85/jump-if-!= break/disp32 -11702 $check-mu-stmt-list:stmt1: -11703 (check-mu-stmt %eax *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -11704 eb/jump $check-mu-stmt-list:continue/disp8 -11705 } -11706 { -11707 $check-mu-stmt-list:check-for-reg-var-def: -11708 81 7/subop/compare *eax 3/imm32/reg-var-def # Stmt-tag -11709 0f 85/jump-if-!= break/disp32 -11710 $check-mu-stmt-list:reg-var-def: -11711 (check-mu-stmt %eax *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -11712 eb/jump $check-mu-stmt-list:continue/disp8 -11713 } -11714 $check-mu-stmt-list:continue: -11715 # TODO: raise an error on unrecognized Stmt-tag -11716 (lookup *(esi+8) *(esi+0xc)) # List-next List-next => eax -11717 89/<- %esi 0/r32/eax -11718 e9/jump loop/disp32 -11719 } -11720 $check-mu-stmt-list:end: -11721 # . restore registers -11722 5e/pop-to-esi -11723 58/pop-to-eax -11724 # . epilogue -11725 89/<- %esp 5/r32/ebp -11726 5d/pop-to-ebp -11727 c3/return -11728 -11729 check-mu-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -11730 # . prologue -11731 55/push-ebp -11732 89/<- %ebp 4/r32/esp -11733 # . save registers -11734 50/push-eax -11735 # - if stmt's operation matches a primitive, check against it -11736 (has-primitive-name? *(ebp+8)) # => eax -11737 3d/compare-eax-and 0/imm32/false -11738 { -11739 74/jump-if-= break/disp8 -11740 (check-mu-primitive *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -11741 e9/jump $check-mu-stmt:end/disp32 -11742 } -11743 # - otherwise find a function to check against -11744 # var f/eax: (addr function) = lookup(*Program->functions) -11745 (lookup *_Program-functions *_Program-functions->payload) # => eax -11746 (find-matching-function %eax *(ebp+8)) # => eax -11747 3d/compare-eax-and 0/imm32 -11748 { -11749 74/jump-if-= break/disp8 -11750 (check-mu-call *(ebp+8) %eax *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -11751 eb/jump $check-mu-stmt:end/disp8 -11752 } -11753 # var f/eax: (addr function) = lookup(*Program->signatures) -11754 (lookup *_Program-signatures *_Program-signatures->payload) # => eax -11755 (find-matching-function %eax *(ebp+8)) # => eax -11756 3d/compare-eax-and 0/imm32 -11757 { -11758 74/jump-if-= break/disp8 -11759 (check-mu-call *(ebp+8) %eax *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -11760 eb/jump $check-mu-stmt:end/disp8 -11761 } -11762 # - otherwise abort -11763 e9/jump $check-mu-stmt:unknown-call/disp32 -11764 $check-mu-stmt:end: -11765 # . restore registers -11766 58/pop-to-eax -11767 # . epilogue -11768 89/<- %esp 5/r32/ebp -11769 5d/pop-to-ebp -11770 c3/return -11771 -11772 $check-mu-stmt:unknown-call: -11773 (write-buffered *(ebp+0x10) "unknown function '") -11774 8b/-> *(ebp+8) 0/r32/eax -11775 (lookup *(eax+4) *(eax+8)) # Stmt1-operation Stmt1-operation => eax -11776 (write-buffered *(ebp+0x10) %eax) -11777 (write-buffered *(ebp+0x10) "'\n") -11778 (flush *(ebp+0x10)) -11779 (stop *(ebp+0x14) 1) -11780 # never gets here -11781 -11782 has-primitive-name?: # stmt: (addr stmt) -> result/eax: boolean -11783 # . prologue -11784 55/push-ebp -11785 89/<- %ebp 4/r32/esp -11786 # . save registers -11787 51/push-ecx -11788 56/push-esi -11789 # var name/esi: (addr array byte) = lookup(stmt->operation) -11790 8b/-> *(ebp+8) 6/r32/esi -11791 (lookup *(esi+4) *(esi+8)) # Stmt1-operation Stmt1-operation => eax -11792 89/<- %esi 0/r32/eax -11793 # if (name == "get") return true -11794 (string-equal? %esi "get") # => eax -11795 3d/compare-eax-and 0/imm32/false -11796 0f 85/jump-if-!= $has-primitive-name?:end/disp32 -11797 # if (name == "index") return true -11798 (string-equal? %esi "index") # => eax -11799 3d/compare-eax-and 0/imm32/false -11800 0f 85/jump-if-!= $has-primitive-name?:end/disp32 -11801 # if (name == "length") return true -11802 (string-equal? %esi "length") # => eax -11803 3d/compare-eax-and 0/imm32/false -11804 0f 85/jump-if-!= $has-primitive-name?:end/disp32 -11805 # if (name == "compute-offset") return true -11806 (string-equal? %esi "compute-offset") # => eax -11807 3d/compare-eax-and 0/imm32/false -11808 0f 85/jump-if-!= $has-primitive-name?:end/disp32 -11809 # if (name == "allocate") return true -11810 (string-equal? %esi "allocate") # => eax -11811 3d/compare-eax-and 0/imm32/false -11812 0f 85/jump-if-!= $has-primitive-name?:end/disp32 -11813 # if (name == "populate") return true -11814 (string-equal? %esi "populate") # => eax -11815 3d/compare-eax-and 0/imm32/false -11816 0f 85/jump-if-!= $has-primitive-name?:end/disp32 -11817 # if (name == "populate-stream") return true -11818 (string-equal? %esi "populate-stream") # => eax -11819 3d/compare-eax-and 0/imm32/false -11820 0f 85/jump-if-!= $has-primitive-name?:end/disp32 -11821 # if (name == "read-from-stream") return true -11822 (string-equal? %esi "read-from-stream") # => eax -11823 3d/compare-eax-and 0/imm32/false -11824 0f 85/jump-if-!= $has-primitive-name?:end/disp32 -11825 # if (name == "write-to-stream") return true -11826 (string-equal? %esi "write-to-stream") # => eax -11827 3d/compare-eax-and 0/imm32/false -11828 0f 85/jump-if-!= $has-primitive-name?:end/disp32 -11829 # var curr/ecx: (addr primitive) = Primitives -11830 b9/copy-to-ecx Primitives/imm32 -11831 { -11832 $has-primitive-name?:loop: -11833 # if (curr == null) break -11834 81 7/subop/compare %ecx 0/imm32 -11835 74/jump-if-= break/disp8 -11836 # if (primitive->name == name) return true -11837 (lookup *ecx *(ecx+4)) # Primitive-name Primitive-name => eax -11838 (string-equal? %esi %eax) # => eax -11839 3d/compare-eax-and 0/imm32/false -11840 75/jump-if-!= $has-primitive-name?:end/disp8 -11841 $has-primitive-name?:next-primitive: -11842 # curr = curr->next -11843 (lookup *(ecx+0x38) *(ecx+0x3c)) # Primitive-next Primitive-next => eax -11844 89/<- %ecx 0/r32/eax -11845 # -11846 e9/jump loop/disp32 -11847 } -11848 # return null -11849 b8/copy-to-eax 0/imm32 -11850 $has-primitive-name?:end: -11851 # . restore registers -11852 5e/pop-to-esi -11853 59/pop-to-ecx -11854 # . epilogue -11855 89/<- %esp 5/r32/ebp -11856 5d/pop-to-ebp -11857 c3/return +11210 57/push-edi +11211 # edi = out +11212 8b/-> *(ebp+0x1c) 7/r32/edi +11213 # *out = new list +11214 (allocate *(ebp+8) *List-size %edi) +11215 # var out-addr/edi: (addr list _type) = lookup(*out) +11216 (lookup *edi *(edi+4)) # => eax +11217 89/<- %edi 0/r32/eax +11218 # out-addr->value = value +11219 8b/-> *(ebp+0xc) 0/r32/eax +11220 89/<- *edi 0/r32/eax # List-value +11221 8b/-> *(ebp+0x10) 0/r32/eax +11222 89/<- *(edi+4) 0/r32/eax # List-value +11223 # if (list == null) return +11224 81 7/subop/compare *(ebp+0x14) 0/imm32 +11225 74/jump-if-= $append-list:end/disp8 +11226 # otherwise append +11227 $append-list:non-empty-list: +11228 # var curr/eax: (addr list _type) = lookup(list) +11229 (lookup *(ebp+0x14) *(ebp+0x18)) # => eax +11230 # while (curr->next != null) curr = curr->next +11231 { +11232 81 7/subop/compare *(eax+8) 0/imm32 # List-next +11233 74/jump-if-= break/disp8 +11234 # curr = lookup(curr->next) +11235 (lookup *(eax+8) *(eax+0xc)) # List-next, List-next => eax +11236 # +11237 eb/jump loop/disp8 +11238 } +11239 # edi = out +11240 8b/-> *(ebp+0x1c) 7/r32/edi +11241 # curr->next = out +11242 8b/-> *edi 1/r32/ecx +11243 89/<- *(eax+8) 1/r32/ecx # List-next +11244 8b/-> *(edi+4) 1/r32/ecx +11245 89/<- *(eax+0xc) 1/r32/ecx # List-next +11246 # out = list +11247 8b/-> *(ebp+0x14) 1/r32/ecx +11248 89/<- *edi 1/r32/ecx +11249 8b/-> *(ebp+0x18) 1/r32/ecx +11250 89/<- *(edi+4) 1/r32/ecx +11251 $append-list:end: +11252 # . restore registers +11253 5f/pop-to-edi +11254 59/pop-to-ecx +11255 58/pop-to-eax +11256 # . epilogue +11257 89/<- %esp 5/r32/ebp +11258 5d/pop-to-ebp +11259 c3/return +11260 +11261 append-stmt-var: # ad: (addr allocation-descriptor), v: (handle var), vars: (handle stmt-var), is-deref?: boolean, out: (addr handle stmt-var) +11262 # . prologue +11263 55/push-ebp +11264 89/<- %ebp 4/r32/esp +11265 # . save registers +11266 50/push-eax +11267 51/push-ecx +11268 57/push-edi +11269 # edi = out +11270 8b/-> *(ebp+0x20) 7/r32/edi +11271 # out = new stmt-var +11272 (allocate *(ebp+8) *Stmt-var-size %edi) +11273 # var out-addr/ecx: (addr stmt-var) = lookup(*out) +11274 (lookup *edi *(edi+4)) # => eax +11275 89/<- %ecx 0/r32/eax +11276 # out-addr->value = v +11277 8b/-> *(ebp+0xc) 0/r32/eax +11278 89/<- *ecx 0/r32/eax # Stmt-var-value +11279 8b/-> *(ebp+0x10) 0/r32/eax +11280 89/<- *(ecx+4) 0/r32/eax # Stmt-var-value +11281 # out-addr->is-deref? = is-deref? +11282 8b/-> *(ebp+0x1c) 0/r32/eax +11283 89/<- *(ecx+0x10) 0/r32/eax # Stmt-var-is-deref +11284 # if (vars == null) return result +11285 81 7/subop/compare *(ebp+0x14) 0/imm32/null +11286 74/jump-if-= $append-stmt-var:end/disp8 +11287 # otherwise append +11288 # var curr/eax: (addr stmt-var) = lookup(vars) +11289 (lookup *(ebp+0x14) *(ebp+0x18)) # => eax +11290 # while (curr->next != null) curr = curr->next +11291 { +11292 81 7/subop/compare *(eax+8) 0/imm32 # Stmt-var-next +11293 74/jump-if-= break/disp8 +11294 # curr = lookup(curr->next) +11295 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next, Stmt-var-next => eax +11296 # +11297 eb/jump loop/disp8 +11298 } +11299 # curr->next = out +11300 8b/-> *edi 1/r32/ecx +11301 89/<- *(eax+8) 1/r32/ecx # Stmt-var-next +11302 8b/-> *(edi+4) 1/r32/ecx +11303 89/<- *(eax+0xc) 1/r32/ecx # Stmt-var-next +11304 # out = vars +11305 8b/-> *(ebp+0x14) 1/r32/ecx +11306 89/<- *edi 1/r32/ecx +11307 8b/-> *(ebp+0x18) 1/r32/ecx +11308 89/<- *(edi+4) 1/r32/ecx +11309 $append-stmt-var:end: +11310 # . restore registers +11311 5f/pop-to-edi +11312 59/pop-to-ecx +11313 58/pop-to-eax +11314 # . epilogue +11315 89/<- %esp 5/r32/ebp +11316 5d/pop-to-ebp +11317 c3/return +11318 +11319 append-to-block: # ad: (addr allocation-descriptor), block: (addr block), x: (handle stmt) +11320 # . prologue +11321 55/push-ebp +11322 89/<- %ebp 4/r32/esp +11323 # . save registers +11324 50/push-eax +11325 56/push-esi +11326 # esi = block +11327 8b/-> *(ebp+0xc) 6/r32/esi +11328 # block->stmts = append(x, block->stmts) +11329 8d/copy-address *(esi+4) 0/r32/eax # Block-stmts +11330 (append-list *(ebp+8) *(ebp+0x10) *(ebp+0x14) *(esi+4) *(esi+8) %eax) # ad, x, x, Block-stmts, Block-stmts +11331 $append-to-block:end: +11332 # . restore registers +11333 5e/pop-to-esi +11334 58/pop-to-eax +11335 # . epilogue +11336 89/<- %esp 5/r32/ebp +11337 5d/pop-to-ebp +11338 c3/return +11339 +11340 ## Parsing types +11341 # We need to create metadata on user-defined types, and we need to use this +11342 # metadata as we parse instructions. +11343 # However, we also want to allow types to be used before their definitions. +11344 # This means we can't ever assume any type data structures exist. +11345 +11346 lookup-or-create-constant: # container: (addr stmt-var), field-name: (addr slice), out: (addr handle var) +11347 # . prologue +11348 55/push-ebp +11349 89/<- %ebp 4/r32/esp +11350 # . save registers +11351 50/push-eax +11352 56/push-esi +11353 # var container-type/esi: type-id +11354 (container-type *(ebp+8)) # => eax +11355 89/<- %esi 0/r32/eax +11356 # var tmp/eax: (handle typeinfo) = find-or-create-typeinfo(container-type) +11357 68/push 0/imm32 +11358 68/push 0/imm32 +11359 89/<- %eax 4/r32/esp +11360 (find-or-create-typeinfo %esi %eax) +11361 # var tmp-addr/eax: (addr typeinfo) = lookup(tmp) +11362 (lookup *eax *(eax+4)) # => eax +11363 # result = find-or-create-typeinfo-output-var(typeinfo, field-name) +11364 #? (write-buffered Stderr "constant: ") +11365 #? (write-slice-buffered Stderr *(ebp+0xc)) +11366 #? (write-buffered Stderr Newline) +11367 #? (flush Stderr) +11368 (find-or-create-typeinfo-output-var %eax *(ebp+0xc) *(ebp+0x10)) +11369 #? 8b/-> *(ebp+0x10) 0/r32/eax +11370 #? (write-buffered Stderr "@") +11371 #? (lookup *eax *(eax+4)) +11372 #? (write-int32-hex-buffered Stderr %eax) +11373 #? (lookup *eax *(eax+4)) +11374 #? (write-buffered Stderr %eax) +11375 #? (write-buffered Stderr Newline) +11376 #? (flush Stderr) +11377 #? (write-buffered Stderr "offset: ") +11378 #? 8b/-> *(eax+0x14) 0/r32/eax +11379 #? (write-int32-hex-buffered Stderr %eax) +11380 #? (write-buffered Stderr Newline) +11381 #? (flush Stderr) +11382 $lookup-or-create-constant:end: +11383 # . reclaim locals +11384 81 0/subop/add %esp 8/imm32 +11385 # . restore registers +11386 5e/pop-to-esi +11387 58/pop-to-eax +11388 # . epilogue +11389 89/<- %esp 5/r32/ebp +11390 5d/pop-to-ebp +11391 c3/return +11392 +11393 # if addr var: +11394 # container->var->type->right->left->value +11395 # otherwise +11396 # container->var->type->value +11397 container-type: # container: (addr stmt-var) -> result/eax: type-id +11398 # . prologue +11399 55/push-ebp +11400 89/<- %ebp 4/r32/esp +11401 # +11402 8b/-> *(ebp+8) 0/r32/eax +11403 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +11404 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +11405 { +11406 81 7/subop/compare *(eax+8) 0/imm32 # Type-tree-right +11407 74/jump-if-= break/disp8 +11408 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax +11409 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +11410 } +11411 8b/-> *(eax+4) 0/r32/eax # Type-tree-value +11412 $container-type:end: +11413 # . epilogue +11414 89/<- %esp 5/r32/ebp +11415 5d/pop-to-ebp +11416 c3/return +11417 +11418 is-container?: # t: type-id -> result/eax: boolean +11419 # . prologue +11420 55/push-ebp +11421 89/<- %ebp 4/r32/esp +11422 # +11423 8b/-> *(ebp+8) 0/r32/eax +11424 c1/shift 4/subop/left %eax 2/imm8 +11425 3b/compare 0/r32/eax *Primitive-type-ids +11426 0f 9d/set-if->= %al +11427 81 4/subop/and %eax 0xff/imm32 +11428 $is-container?:end: +11429 # . epilogue +11430 89/<- %esp 5/r32/ebp +11431 5d/pop-to-ebp +11432 c3/return +11433 +11434 find-or-create-typeinfo: # t: type-id, out: (addr handle typeinfo) +11435 # . prologue +11436 55/push-ebp +11437 89/<- %ebp 4/r32/esp +11438 # . save registers +11439 50/push-eax +11440 51/push-ecx +11441 52/push-edx +11442 57/push-edi +11443 # edi = out +11444 8b/-> *(ebp+0xc) 7/r32/edi +11445 # var fields/ecx: (handle table (handle array byte) (handle typeinfo-entry)) +11446 68/push 0/imm32 +11447 68/push 0/imm32 +11448 89/<- %ecx 4/r32/esp +11449 # find-typeinfo(t, out) +11450 (find-typeinfo *(ebp+8) %edi) +11451 { +11452 # if (*out != 0) break +11453 81 7/subop/compare *edi 0/imm32 +11454 0f 85/jump-if-!= break/disp32 +11455 $find-or-create-typeinfo:create: +11456 # *out = allocate +11457 (allocate Heap *Typeinfo-size %edi) +11458 # var tmp/eax: (addr typeinfo) = lookup(*out) +11459 (lookup *edi *(edi+4)) # => eax +11460 #? (write-buffered Stderr "created typeinfo at ") +11461 #? (write-int32-hex-buffered Stderr %eax) +11462 #? (write-buffered Stderr " for type-id ") +11463 #? (write-int32-hex-buffered Stderr *(ebp+8)) +11464 #? (write-buffered Stderr Newline) +11465 #? (flush Stderr) +11466 # tmp->id = t +11467 8b/-> *(ebp+8) 2/r32/edx +11468 89/<- *eax 2/r32/edx # Typeinfo-id +11469 # tmp->fields = new table +11470 # . fields = new table +11471 (new-stream Heap 0x40 *Typeinfo-fields-row-size %ecx) +11472 # . tmp->fields = fields +11473 8b/-> *ecx 2/r32/edx +11474 89/<- *(eax+4) 2/r32/edx # Typeinfo-fields +11475 8b/-> *(ecx+4) 2/r32/edx +11476 89/<- *(eax+8) 2/r32/edx # Typeinfo-fields +11477 # tmp->next = Program->types +11478 8b/-> *_Program-types 1/r32/ecx +11479 89/<- *(eax+0x10) 1/r32/ecx # Typeinfo-next +11480 8b/-> *_Program-types->payload 1/r32/ecx +11481 89/<- *(eax+0x14) 1/r32/ecx # Typeinfo-next +11482 # Program->types = out +11483 8b/-> *edi 1/r32/ecx +11484 89/<- *_Program-types 1/r32/ecx +11485 8b/-> *(edi+4) 1/r32/ecx +11486 89/<- *_Program-types->payload 1/r32/ecx +11487 } +11488 $find-or-create-typeinfo:end: +11489 # . reclaim locals +11490 81 0/subop/add %esp 8/imm32 +11491 # . restore registers +11492 5f/pop-to-edi +11493 5a/pop-to-edx +11494 59/pop-to-ecx +11495 58/pop-to-eax +11496 # . epilogue +11497 89/<- %esp 5/r32/ebp +11498 5d/pop-to-ebp +11499 c3/return +11500 +11501 find-typeinfo: # t: type-id, out: (addr handle typeinfo) +11502 # . prologue +11503 55/push-ebp +11504 89/<- %ebp 4/r32/esp +11505 # . save registers +11506 50/push-eax +11507 51/push-ecx +11508 52/push-edx +11509 57/push-edi +11510 # ecx = t +11511 8b/-> *(ebp+8) 1/r32/ecx +11512 # edi = out +11513 8b/-> *(ebp+0xc) 7/r32/edi +11514 # *out = Program->types +11515 8b/-> *_Program-types 0/r32/eax +11516 89/<- *edi 0/r32/eax +11517 8b/-> *_Program-types->payload 0/r32/eax +11518 89/<- *(edi+4) 0/r32/eax +11519 { +11520 $find-typeinfo:loop: +11521 # if (*out == 0) break +11522 81 7/subop/compare *edi 0/imm32 +11523 74/jump-if-= break/disp8 +11524 $find-typeinfo:check: +11525 # var tmp/eax: (addr typeinfo) = lookup(*out) +11526 (lookup *edi *(edi+4)) # => eax +11527 # if (tmp->id == t) break +11528 39/compare *eax 1/r32/ecx # Typeinfo-id +11529 74/jump-if-= break/disp8 +11530 $find-typeinfo:continue: +11531 # *out = tmp->next +11532 8b/-> *(eax+0x10) 2/r32/edx # Typeinfo-next +11533 89/<- *edi 2/r32/edx +11534 8b/-> *(eax+0x14) 2/r32/edx # Typeinfo-next +11535 89/<- *(edi+4) 2/r32/edx +11536 # +11537 eb/jump loop/disp8 +11538 } +11539 $find-typeinfo:end: +11540 # . restore registers +11541 5f/pop-to-edi +11542 5a/pop-to-edx +11543 59/pop-to-ecx +11544 58/pop-to-eax +11545 # . epilogue +11546 89/<- %esp 5/r32/ebp +11547 5d/pop-to-ebp +11548 c3/return +11549 +11550 find-or-create-typeinfo-output-var: # T: (addr typeinfo), f: (addr slice), out: (addr handle var) +11551 # . prologue +11552 55/push-ebp +11553 89/<- %ebp 4/r32/esp +11554 # . save registers +11555 50/push-eax +11556 52/push-edx +11557 57/push-edi +11558 # var dest/edi: (handle typeinfo-entry) +11559 68/push 0/imm32 +11560 68/push 0/imm32 +11561 89/<- %edi 4/r32/esp +11562 # find-or-create-typeinfo-fields(T, f, dest) +11563 (find-or-create-typeinfo-fields *(ebp+8) *(ebp+0xc) %edi) +11564 # var dest-addr/edi: (addr typeinfo-entry) = lookup(dest) +11565 (lookup *edi *(edi+4)) # => eax +11566 89/<- %edi 0/r32/eax +11567 # if dest-addr->output-var doesn't exist, create it +11568 { +11569 81 7/subop/compare *(edi+0xc) 0/imm32 # Typeinfo-entry-output-var +11570 0f 85/jump-if-!= break/disp32 +11571 # dest-addr->output-var = new var(dummy name, type, -1 offset) +11572 # . var name/eax: (handle array byte) = "field" +11573 68/push 0/imm32 +11574 68/push 0/imm32 +11575 89/<- %eax 4/r32/esp +11576 (slice-to-string Heap *(ebp+0xc) %eax) +11577 # . new var +11578 8d/copy-address *(edi+0xc) 2/r32/edx +11579 (new-var Heap *eax *(eax+4) %edx) +11580 # . reclaim name +11581 81 0/subop/add %esp 8/imm32 +11582 # var result/edx: (addr var) = lookup(dest-addr->output-var) +11583 (lookup *(edi+0xc) *(edi+0x10)) # => eax +11584 89/<- %edx 0/r32/eax +11585 # result->type = new constant type +11586 8d/copy-address *(edx+8) 0/r32/eax # Var-type +11587 (allocate Heap *Type-tree-size %eax) +11588 (lookup *(edx+8) *(edx+0xc)) # => eax +11589 c7 0/subop/copy *eax 1/imm32/true # Type-tree-is-atom +11590 c7 0/subop/copy *(eax+4) 6/imm32/constant # Type-tree-value +11591 c7 0/subop/copy *(eax+8) 0/imm32 # Type-tree-left +11592 c7 0/subop/copy *(eax+0xc) 0/imm32 # Type-tree-right +11593 c7 0/subop/copy *(eax+0x10) 0/imm32 # Type-tree-right +11594 # result->offset isn't filled out yet +11595 c7 0/subop/copy *(edx+0x14) -1/imm32/uninitialized # Var-offset +11596 } +11597 # out = dest-addr->output-var +11598 8b/-> *(ebp+0x10) 2/r32/edx +11599 8b/-> *(edi+0xc) 0/r32/eax # Typeinfo-entry-output-var +11600 89/<- *edx 0/r32/eax +11601 8b/-> *(edi+0x10) 0/r32/eax # Typeinfo-entry-output-var +11602 89/<- *(edx+4) 0/r32/eax +11603 $find-or-create-typeinfo-output-var:end: +11604 # . reclaim locals +11605 81 0/subop/add %esp 8/imm32 +11606 # . restore registers +11607 5f/pop-to-edi +11608 5a/pop-to-edx +11609 58/pop-to-eax +11610 # . epilogue +11611 89/<- %esp 5/r32/ebp +11612 5d/pop-to-ebp +11613 c3/return +11614 +11615 find-or-create-typeinfo-fields: # T: (addr typeinfo), f: (addr slice), out: (addr handle typeinfo-entry) +11616 # . prologue +11617 55/push-ebp +11618 89/<- %ebp 4/r32/esp +11619 # . save registers +11620 50/push-eax +11621 56/push-esi +11622 57/push-edi +11623 # eax = lookup(T->fields) +11624 8b/-> *(ebp+8) 0/r32/eax +11625 (lookup *(eax+4) *(eax+8)) # Typeinfo-fields Typeinfo-fields => eax +11626 # edi = out +11627 8b/-> *(ebp+0x10) 7/r32/edi +11628 # var src/esi: (addr handle typeinfo-entry) = get-or-insert-slice(T->fields, f) +11629 (get-or-insert-slice %eax *(ebp+0xc) *Typeinfo-fields-row-size Heap) # => eax +11630 89/<- %esi 0/r32/eax +11631 # if src doesn't exist, allocate it +11632 { +11633 81 7/subop/compare *esi 0/imm32 +11634 75/jump-if-!= break/disp8 +11635 (allocate Heap *Typeinfo-entry-size %esi) +11636 #? (write-buffered Stderr "handle at ") +11637 #? (write-int32-hex-buffered Stderr %esi) +11638 #? (write-buffered Stderr ": ") +11639 #? (write-int32-hex-buffered Stderr *esi) +11640 #? (write-buffered Stderr " ") +11641 #? (write-int32-hex-buffered Stderr *(esi+4)) +11642 #? (write-buffered Stderr Newline) +11643 #? (flush Stderr) +11644 #? (lookup *esi *(esi+4)) +11645 #? (write-buffered Stderr "created typeinfo fields at ") +11646 #? (write-int32-hex-buffered Stderr %esi) +11647 #? (write-buffered Stderr " for ") +11648 #? (write-int32-hex-buffered Stderr *(ebp+8)) +11649 #? (write-buffered Stderr Newline) +11650 #? (flush Stderr) +11651 } +11652 # *out = src +11653 # . *edi = *src +11654 8b/-> *esi 0/r32/eax +11655 89/<- *edi 0/r32/eax +11656 8b/-> *(esi+4) 0/r32/eax +11657 89/<- *(edi+4) 0/r32/eax +11658 $find-or-create-typeinfo-fields:end: +11659 # . restore registers +11660 5f/pop-to-edi +11661 5e/pop-to-esi +11662 58/pop-to-eax +11663 # . epilogue +11664 89/<- %esp 5/r32/ebp +11665 5d/pop-to-ebp +11666 c3/return +11667 +11668 populate-mu-type: # in: (addr stream byte), t: (addr typeinfo), err: (addr buffered-file), ed: (addr exit-descriptor) +11669 # pseudocode: +11670 # var line: (stream byte 512) +11671 # curr-index = 0 +11672 # while true +11673 # clear-stream(line) +11674 # read-line-buffered(in, line) +11675 # if line->write == 0 +11676 # abort +11677 # word-slice = next-mu-token(line) +11678 # if slice-empty?(word-slice) # end of line +11679 # continue +11680 # if slice-equal?(word-slice, "}") +11681 # break +11682 # var v: (handle var) = parse-var-with-type(word-slice, line) +11683 # var r: (handle typeinfo-fields) = find-or-create-typeinfo-fields(t, word-slice/v->name) +11684 # TODO: ensure that r->first is null +11685 # r->index = curr-index +11686 # curr-index++ +11687 # r->input-var = v +11688 # if r->output-var == 0 +11689 # r->output-var = new literal +11690 # TODO: ensure nothing else in line +11691 # t->total-size-in-bytes = -2 (not yet initialized) +11692 # +11693 # . prologue +11694 55/push-ebp +11695 89/<- %ebp 4/r32/esp +11696 # var curr-index: int at *(ebp-4) +11697 68/push 0/imm32 +11698 # . save registers +11699 50/push-eax +11700 51/push-ecx +11701 52/push-edx +11702 53/push-ebx +11703 56/push-esi +11704 57/push-edi +11705 # edi = t +11706 8b/-> *(ebp+0xc) 7/r32/edi +11707 # var line/ecx: (stream byte 512) +11708 81 5/subop/subtract %esp 0x200/imm32 +11709 68/push 0x200/imm32/size +11710 68/push 0/imm32/read +11711 68/push 0/imm32/write +11712 89/<- %ecx 4/r32/esp +11713 # var word-slice/edx: slice +11714 68/push 0/imm32/end +11715 68/push 0/imm32/start +11716 89/<- %edx 4/r32/esp +11717 # var v/esi: (handle var) +11718 68/push 0/imm32 +11719 68/push 0/imm32 +11720 89/<- %esi 4/r32/esp +11721 # var r/ebx: (handle typeinfo-entry) +11722 68/push 0/imm32 +11723 68/push 0/imm32 +11724 89/<- %ebx 4/r32/esp +11725 { +11726 $populate-mu-type:line-loop: +11727 (clear-stream %ecx) +11728 (read-line-buffered *(ebp+8) %ecx) +11729 # if (line->write == 0) abort +11730 81 7/subop/compare *ecx 0/imm32 +11731 0f 84/jump-if-= $populate-mu-type:error1/disp32 +11732 +-- 6 lines: #? # dump line ------------------------------------------------------------------------------------------------------------------------------------------------------ +11738 (next-mu-token %ecx %edx) +11739 # if slice-empty?(word-slice) continue +11740 (slice-empty? %edx) # => eax +11741 3d/compare-eax-and 0/imm32 +11742 0f 85/jump-if-!= loop/disp32 +11743 # if slice-equal?(word-slice, "}") break +11744 (slice-equal? %edx "}") +11745 3d/compare-eax-and 0/imm32 +11746 0f 85/jump-if-!= break/disp32 +11747 $populate-mu-type:parse-element: +11748 # v = parse-var-with-type(word-slice, first-line) +11749 # must do this first to strip the trailing ':' from word-slice before +11750 # using it in find-or-create-typeinfo-fields below +11751 # TODO: clean up that mutation in parse-var-with-type +11752 (parse-var-with-type %edx %ecx %esi *(ebp+0x10) *(ebp+0x14)) +11753 # if v is an addr, abort +11754 (lookup *esi *(esi+4)) # => eax +11755 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +11756 (is-mu-addr-type? %eax) # => eax +11757 3d/compare-eax-and 0/imm32/false +11758 0f 85/jump-if-!= $populate-mu-type:error2/disp32 +11759 # if v is an array, abort (we could support it, but initialization gets complex) +11760 (lookup *esi *(esi+4)) # => eax +11761 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +11762 (is-mu-array-type? %eax) # => eax +11763 3d/compare-eax-and 0/imm32/false +11764 0f 85/jump-if-!= $populate-mu-type:error3/disp32 +11765 # if v is a byte, abort +11766 (lookup *esi *(esi+4)) # => eax +11767 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +11768 (is-simple-mu-type? %eax 8) # byte => eax +11769 3d/compare-eax-and 0/imm32/false +11770 0f 85/jump-if-!= $populate-mu-type:error4/disp32 +11771 # if v is a slice, abort +11772 (lookup *esi *(esi+4)) # => eax +11773 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +11774 (is-simple-mu-type? %eax 0xc) # slice => eax +11775 3d/compare-eax-and 0/imm32/false +11776 0f 85/jump-if-!= $populate-mu-type:error5/disp32 +11777 # if v is a stream, abort (we could support it, but initialization gets even more complex) +11778 (lookup *esi *(esi+4)) # => eax +11779 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +11780 (is-mu-stream-type? %eax) # => eax +11781 3d/compare-eax-and 0/imm32/false +11782 0f 85/jump-if-!= $populate-mu-type:error6/disp32 +11783 # var tmp/ecx +11784 51/push-ecx +11785 $populate-mu-type:create-typeinfo-fields: +11786 # var r/ebx: (handle typeinfo-entry) +11787 (find-or-create-typeinfo-fields %edi %edx %ebx) +11788 # r->index = curr-index +11789 (lookup *ebx *(ebx+4)) # => eax +11790 8b/-> *(ebp-4) 1/r32/ecx +11791 #? (write-buffered Stderr "saving index ") +11792 #? (write-int32-hex-buffered Stderr %ecx) +11793 #? (write-buffered Stderr " at ") +11794 #? (write-int32-hex-buffered Stderr %edi) +11795 #? (write-buffered Stderr Newline) +11796 #? (flush Stderr) +11797 89/<- *(eax+8) 1/r32/ecx # Typeinfo-entry-index +11798 # ++curr-index +11799 ff 0/subop/increment *(ebp-4) +11800 $populate-mu-type:set-input-type: +11801 # r->input-var = v +11802 8b/-> *esi 1/r32/ecx +11803 89/<- *eax 1/r32/ecx # Typeinfo-entry-input-var +11804 8b/-> *(esi+4) 1/r32/ecx +11805 89/<- *(eax+4) 1/r32/ecx # Typeinfo-entry-input-var +11806 # restore line +11807 59/pop-to-ecx +11808 { +11809 $populate-mu-type:create-output-type: +11810 # if (r->output-var == 0) create a new var with some placeholder data +11811 81 7/subop/compare *(eax+0xc) 0/imm32 # Typeinfo-entry-output-var +11812 75/jump-if-!= break/disp8 +11813 8d/copy-address *(eax+0xc) 0/r32/eax # Typeinfo-entry-output-var +11814 (new-literal Heap %edx %eax) +11815 } +11816 e9/jump loop/disp32 +11817 } +11818 $populate-mu-type:invalidate-total-size-in-bytes: +11819 # Offsets and total size may not be accurate here since we may not yet +11820 # have encountered the element types. +11821 # We'll recompute them separately after parsing the entire program. +11822 c7 0/subop/copy *(edi+0xc) -2/imm32/uninitialized # Typeinfo-total-size-in-bytes +11823 $populate-mu-type:end: +11824 # . reclaim locals +11825 81 0/subop/add %esp 0x224/imm32 +11826 # . restore registers +11827 5f/pop-to-edi +11828 5e/pop-to-esi +11829 5b/pop-to-ebx +11830 5a/pop-to-edx +11831 59/pop-to-ecx +11832 58/pop-to-eax +11833 # reclaim curr-index +11834 81 0/subop/add %esp 4/imm32 +11835 # . epilogue +11836 89/<- %esp 5/r32/ebp +11837 5d/pop-to-ebp +11838 c3/return +11839 +11840 $populate-mu-type:error1: +11841 # error("incomplete type definition '" t->name "'\n") +11842 (write-buffered *(ebp+0x10) "incomplete type definition '") +11843 (type-name *edi) # Typeinfo-id => eax +11844 (write-buffered *(ebp+0x10) %eax) +11845 (write-buffered *(ebp+0x10) "\n") +11846 (flush *(ebp+0x10)) +11847 (stop *(ebp+0x14) 1) +11848 # never gets here +11849 +11850 $populate-mu-type:error2: +11851 (write-buffered *(ebp+0x10) "type ") +11852 (type-name *edi) # Typeinfo-id => eax +11853 (write-buffered *(ebp+0x10) %eax) +11854 (write-buffered *(ebp+0x10) ": 'addr' elements not allowed\n") +11855 (flush *(ebp+0x10)) +11856 (stop *(ebp+0x14) 1) +11857 # never gets here 11858 -11859 check-mu-primitive: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -11860 # . prologue -11861 55/push-ebp -11862 89/<- %ebp 4/r32/esp -11863 # . save registers -11864 50/push-eax -11865 51/push-ecx -11866 # var op/ecx: (addr array byte) = lookup(stmt->operation) -11867 8b/-> *(ebp+8) 0/r32/eax -11868 (lookup *(eax+4) *(eax+8)) # Stmt1-operation Stmt1-operation => eax -11869 89/<- %ecx 0/r32/eax -11870 # if (op == "copy") check-mu-copy-stmt -11871 { -11872 (string-equal? %ecx "copy") # => eax -11873 3d/compare-eax-and 0/imm32/false -11874 74/jump-if-= break/disp8 -11875 (check-mu-copy-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -11876 e9/jump $check-mu-primitive:end/disp32 -11877 } -11878 # if (op == "copy-to") check-mu-copy-to-stmt -11879 { -11880 (string-equal? %ecx "copy-to") # => eax -11881 3d/compare-eax-and 0/imm32/false -11882 74/jump-if-= break/disp8 -11883 (check-mu-copy-to-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -11884 e9/jump $check-mu-primitive:end/disp32 -11885 } -11886 # if (op == "compare") check-mu-compare-stmt -11887 { -11888 (string-equal? %ecx "compare") # => eax -11889 3d/compare-eax-and 0/imm32/false -11890 74/jump-if-= break/disp8 -11891 (check-mu-compare-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -11892 e9/jump $check-mu-primitive:end/disp32 -11893 } -11894 # if (op == "address") check-mu-address-stmt -11895 { -11896 (string-equal? %ecx "address") # => eax -11897 3d/compare-eax-and 0/imm32/false -11898 74/jump-if-= break/disp8 -11899 (check-mu-address-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -11900 e9/jump $check-mu-primitive:end/disp32 -11901 } -11902 # if (op == "get") check-mu-get-stmt -11903 { -11904 (string-equal? %ecx "get") # => eax -11905 3d/compare-eax-and 0/imm32/false -11906 74/jump-if-= break/disp8 -11907 (check-mu-get-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -11908 e9/jump $check-mu-primitive:end/disp32 -11909 } -11910 # if (op == "index") check-mu-index-stmt -11911 { -11912 (string-equal? %ecx "index") # => eax -11913 3d/compare-eax-and 0/imm32/false -11914 74/jump-if-= break/disp8 -11915 (check-mu-index-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -11916 e9/jump $check-mu-primitive:end/disp32 -11917 } -11918 # if (op == "length") check-mu-length-stmt -11919 { -11920 (string-equal? %ecx "length") # => eax -11921 3d/compare-eax-and 0/imm32/false -11922 74/jump-if-= break/disp8 -11923 (check-mu-length-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -11924 e9/jump $check-mu-primitive:end/disp32 -11925 } -11926 # if (op == "compute-offset") check-mu-compute-offset-stmt -11927 { -11928 (string-equal? %ecx "compute-offset") # => eax -11929 3d/compare-eax-and 0/imm32/false -11930 74/jump-if-= break/disp8 -11931 (check-mu-compute-offset-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -11932 e9/jump $check-mu-primitive:end/disp32 -11933 } -11934 # if (op == "allocate") check-mu-allocate-stmt -11935 { -11936 (string-equal? %ecx "allocate") # => eax -11937 3d/compare-eax-and 0/imm32/false -11938 74/jump-if-= break/disp8 -11939 (check-mu-allocate-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -11940 e9/jump $check-mu-primitive:end/disp32 -11941 } -11942 # if (op == "populate") check-mu-populate-stmt -11943 { -11944 (string-equal? %ecx "populate") # => eax -11945 3d/compare-eax-and 0/imm32/false -11946 74/jump-if-= break/disp8 -11947 (check-mu-populate-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -11948 e9/jump $check-mu-primitive:end/disp32 -11949 } -11950 # if (op == "populate-stream") check-mu-populate-stream-stmt -11951 { -11952 (string-equal? %ecx "populate-stream") # => eax -11953 3d/compare-eax-and 0/imm32/false -11954 74/jump-if-= break/disp8 -11955 (check-mu-populate-stream-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -11956 e9/jump $check-mu-primitive:end/disp32 -11957 } -11958 # if (op == "read-from-stream") check-mu-read-from-stream-stmt -11959 { -11960 (string-equal? %ecx "read-from-stream") # => eax -11961 3d/compare-eax-and 0/imm32/false -11962 74/jump-if-= break/disp8 -11963 (check-mu-read-from-stream-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -11964 e9/jump $check-mu-primitive:end/disp32 -11965 } -11966 # if (op == "write-to-stream") check-mu-write-to-stream-stmt -11967 { -11968 (string-equal? %ecx "write-to-stream") # => eax -11969 3d/compare-eax-and 0/imm32/false -11970 74/jump-if-= break/disp8 -11971 (check-mu-write-to-stream-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -11972 e9/jump $check-mu-primitive:end/disp32 -11973 } -11974 # otherwise check-numberlike-stmt -11975 (check-mu-numberlike-primitive *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -11976 $check-mu-primitive:end: -11977 # . restore registers -11978 59/pop-to-ecx -11979 58/pop-to-eax -11980 # . epilogue -11981 89/<- %esp 5/r32/ebp -11982 5d/pop-to-ebp -11983 c3/return -11984 -11985 # by default, Mu primitives should only operate on 'number-like' types -11986 check-mu-numberlike-primitive: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -11987 # . prologue -11988 55/push-ebp -11989 89/<- %ebp 4/r32/esp -11990 # . save registers -11991 50/push-eax -11992 51/push-ecx -11993 56/push-esi -11994 # esi = stmt -11995 8b/-> *(ebp+8) 6/r32/esi -11996 # var gas/ecx: int = 2 -11997 b9/copy-to-ecx 2/imm32 -11998 # - check at most 1 output -11999 # var output/eax: (addr stmt-var) = stmt->outputs -12000 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax -12001 { -12002 3d/compare-eax-and 0/imm32 -12003 74/jump-if-= break/disp8 -12004 $check-mu-numberlike-primitive:output: -12005 (check-mu-numberlike-output %eax *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -12006 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax -12007 3d/compare-eax-and 0/imm32 -12008 0f 85/jump-if-!= $check-mu-numberlike-primitive:error-too-many-outputs/disp32 -12009 # check output is in a register -12010 # --gas -12011 49/decrement-ecx -12012 } -12013 # - check first inout -12014 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax -12015 { -12016 3d/compare-eax-and 0/imm32 -12017 0f 84/jump-if-= $check-mu-numberlike-primitive:end/disp32 -12018 $check-mu-numberlike-primitive:first-inout: -12019 (check-mu-numberlike-arg %eax *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -12020 # --gas -12021 49/decrement-ecx -12022 } -12023 # - check second inout -12024 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax -12025 { -12026 3d/compare-eax-and 0/imm32 -12027 74/jump-if-= $check-mu-numberlike-primitive:end/disp8 -12028 $check-mu-numberlike-primitive:second-inout: -12029 # is a second inout allowed? -12030 81 7/subop/compare %ecx 0/imm32 -12031 0f 84/jump-if-= $check-mu-numberlike-primitive:error-too-many-inouts/disp32 -12032 $check-mu-numberlike-primitive:second-inout-permitted: -12033 (check-mu-numberlike-arg %eax *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -12034 } -12035 $check-mu-numberlike-primitive:third-inout: -12036 # if there's a third arg, raise an error -12037 81 7/subop/compare *(eax+8) 0/imm32 # Stmt-var-next -12038 0f 85/jump-if-!= $check-mu-numberlike-primitive:error-too-many-inouts/disp32 -12039 $check-mu-numberlike-primitive:end: -12040 # . restore registers -12041 5e/pop-to-esi -12042 59/pop-to-ecx -12043 58/pop-to-eax -12044 # . epilogue -12045 89/<- %esp 5/r32/ebp -12046 5d/pop-to-ebp -12047 c3/return -12048 -12049 $check-mu-numberlike-primitive:error-too-many-inouts: -12050 (write-buffered *(ebp+0x10) "fn ") -12051 8b/-> *(ebp+0xc) 0/r32/eax -12052 (lookup *eax *(eax+4)) # Function-name Function-name => eax -12053 (write-buffered *(ebp+0x10) %eax) -12054 (write-buffered *(ebp+0x10) ": stmt ") -12055 (lookup *(esi+4) *(esi+8)) # Stmt1-operation Stmt1-operation => eax -12056 (write-buffered *(ebp+0x10) %eax) -12057 (write-buffered *(ebp+0x10) ": too many inouts; most primitives support at most two arguments, across inouts and outputs\n") -12058 (flush *(ebp+0x10)) -12059 (stop *(ebp+0x14) 1) -12060 # never gets here -12061 -12062 $check-mu-numberlike-primitive:error-too-many-outputs: -12063 (write-buffered *(ebp+0x10) "fn ") -12064 8b/-> *(ebp+0xc) 0/r32/eax -12065 (lookup *eax *(eax+4)) # Function-name Function-name => eax -12066 (write-buffered *(ebp+0x10) %eax) -12067 (write-buffered *(ebp+0x10) ": stmt ") -12068 (lookup *(esi+4) *(esi+8)) # Stmt1-operation Stmt1-operation => eax -12069 (write-buffered *(ebp+0x10) %eax) -12070 (write-buffered *(ebp+0x10) ": too many outputs; most primitives support at most one output\n") -12071 (flush *(ebp+0x10)) -12072 (stop *(ebp+0x14) 1) -12073 # never gets here +11859 $populate-mu-type:error3: +11860 (write-buffered *(ebp+0x10) "type ") +11861 (type-name *edi) # Typeinfo-id => eax +11862 (write-buffered *(ebp+0x10) %eax) +11863 (write-buffered *(ebp+0x10) ": 'array' elements not allowed for now\n") +11864 (flush *(ebp+0x10)) +11865 (stop *(ebp+0x14) 1) +11866 # never gets here +11867 +11868 $populate-mu-type:error4: +11869 (write-buffered *(ebp+0x10) "type ") +11870 (type-name *edi) # Typeinfo-id => eax +11871 (write-buffered *(ebp+0x10) %eax) +11872 (write-buffered *(ebp+0x10) ": 'byte' elements not allowed\n") +11873 (flush *(ebp+0x10)) +11874 (stop *(ebp+0x14) 1) +11875 # never gets here +11876 +11877 $populate-mu-type:error5: +11878 (write-buffered *(ebp+0x10) "type ") +11879 (type-name *edi) # Typeinfo-id => eax +11880 (write-buffered *(ebp+0x10) %eax) +11881 (write-buffered *(ebp+0x10) ": 'slice' elements not allowed\n") +11882 (flush *(ebp+0x10)) +11883 (stop *(ebp+0x14) 1) +11884 # never gets here +11885 +11886 $populate-mu-type:error6: +11887 (write-buffered *(ebp+0x10) "type ") +11888 (type-name *edi) # Typeinfo-id => eax +11889 (write-buffered *(ebp+0x10) %eax) +11890 (write-buffered *(ebp+0x10) ": 'stream' elements not allowed for now\n") +11891 (flush *(ebp+0x10)) +11892 (stop *(ebp+0x14) 1) +11893 # never gets here +11894 +11895 type-name: # index: int -> result/eax: (addr array byte) +11896 # . prologue +11897 55/push-ebp +11898 89/<- %ebp 4/r32/esp +11899 # +11900 (index Type-id *(ebp+8)) +11901 $type-name:end: +11902 # . epilogue +11903 89/<- %esp 5/r32/ebp +11904 5d/pop-to-ebp +11905 c3/return +11906 +11907 index: # arr: (addr stream (handle array byte)), index: int -> result/eax: (addr array byte) +11908 # . prologue +11909 55/push-ebp +11910 89/<- %ebp 4/r32/esp +11911 # . save registers +11912 56/push-esi +11913 # TODO: bounds-check index +11914 # esi = arr +11915 8b/-> *(ebp+8) 6/r32/esi +11916 # eax = index +11917 8b/-> *(ebp+0xc) 0/r32/eax +11918 # eax = *(arr + 12 + index) +11919 8b/-> *(esi+eax<<2+0xc) 0/r32/eax +11920 $index:end: +11921 # . restore registers +11922 5e/pop-to-esi +11923 # . epilogue +11924 89/<- %esp 5/r32/ebp +11925 5d/pop-to-ebp +11926 c3/return +11927 +11928 ####################################################### +11929 # Compute type sizes +11930 ####################################################### +11931 +11932 # Compute the sizes of all user-defined types. +11933 # We'll need the sizes of their elements, which may be other user-defined +11934 # types, which we will compute as needed. +11935 +11936 # Initially, all user-defined types have their sizes set to -2 (invalid) +11937 populate-mu-type-sizes: # err: (addr buffered-file), ed: (addr exit-descriptor) +11938 # . prologue +11939 55/push-ebp +11940 89/<- %ebp 4/r32/esp +11941 $populate-mu-type-sizes:total-sizes: +11942 # var curr/eax: (addr typeinfo) = lookup(Program->types) +11943 (lookup *_Program-types *_Program-types->payload) # => eax +11944 { +11945 # if (curr == null) break +11946 3d/compare-eax-and 0/imm32/null +11947 74/jump-if-= break/disp8 +11948 (populate-mu-type-sizes-in-type %eax *(ebp+8) *(ebp+0xc)) +11949 # curr = lookup(curr->next) +11950 (lookup *(eax+0x10) *(eax+0x14)) # Typeinfo-next Typeinfo-next => eax +11951 eb/jump loop/disp8 +11952 } +11953 $populate-mu-type-sizes:offsets: +11954 # curr = *Program->types +11955 (lookup *_Program-types *_Program-types->payload) # => eax +11956 { +11957 # if (curr == null) break +11958 3d/compare-eax-and 0/imm32/null +11959 74/jump-if-= break/disp8 +11960 (populate-mu-type-offsets %eax *(ebp+8) *(ebp+0xc)) +11961 # curr = curr->next +11962 (lookup *(eax+0x10) *(eax+0x14)) # Typeinfo-next Typeinfo-next => eax +11963 eb/jump loop/disp8 +11964 } +11965 $populate-mu-type-sizes:end: +11966 # . epilogue +11967 89/<- %esp 5/r32/ebp +11968 5d/pop-to-ebp +11969 c3/return +11970 +11971 # compute sizes of all fields, recursing as necessary +11972 # sum up all their sizes to arrive at total size +11973 # fields may be out of order, but that doesn't affect the answer +11974 populate-mu-type-sizes-in-type: # T: (addr typeinfo), err: (addr buffered-file), ed: (addr exit-descriptor) +11975 # . prologue +11976 55/push-ebp +11977 89/<- %ebp 4/r32/esp +11978 # . save registers +11979 50/push-eax +11980 51/push-ecx +11981 52/push-edx +11982 56/push-esi +11983 57/push-edi +11984 # esi = T +11985 8b/-> *(ebp+8) 6/r32/esi +11986 # if T is already computed, return +11987 81 7/subop/compare *(esi+0xc) 0/imm32 # Typeinfo-total-size-in-bytes +11988 0f 8d/jump-if->= $populate-mu-type-sizes-in-type:end/disp32 +11989 # if T is being computed, abort +11990 81 7/subop/compare *(esi+0xc) -1/imm32/being-computed # Typeinfo-total-size-in-bytes +11991 0f 84/jump-if-= $populate-mu-type-sizes-in-type:abort/disp32 +11992 # tag T (-2 to -1) to avoid infinite recursion +11993 c7 0/subop/copy *(esi+0xc) -1/imm32/being-computed # Typeinfo-total-size-in-bytes +11994 # var total-size/edi: int = 0 +11995 bf/copy-to-edi 0/imm32 +11996 # - for every field, if it's a user-defined type, compute its size +11997 # var table/ecx: (addr table (handle array byte) (handle typeinfo-entry)) = lookup(T->fields) +11998 (lookup *(esi+4) *(esi+8)) # Typeinfo-fields Typeinfo-fields => eax +11999 89/<- %ecx 0/r32/eax +12000 # var table-size/edx: int = table->write +12001 8b/-> *ecx 2/r32/edx # stream-write +12002 # var curr/ecx: (addr table_row) = table->data +12003 8d/copy-address *(ecx+0xc) 1/r32/ecx +12004 # var max/edx: (addr table_row) = table->data + table->write +12005 8d/copy-address *(ecx+edx) 2/r32/edx +12006 { +12007 $populate-mu-type-sizes-in-type:loop: +12008 # if (curr >= max) break +12009 39/compare %ecx 2/r32/edx +12010 73/jump-if-addr>= break/disp8 +12011 # var t/eax: (addr typeinfo-entry) = lookup(curr->value) +12012 (lookup *(ecx+8) *(ecx+0xc)) # => eax +12013 # if (t->input-var == 0) silently ignore it; we'll emit a nice error message while type-checking +12014 81 7/subop/compare *eax 0/imm32 # Typeinfo-entry-input-var +12015 74/jump-if-= $populate-mu-type-sizes-in-type:end/disp8 +12016 # compute size of t->input-var +12017 (lookup *eax *(eax+4)) # Typeinfo-entry-input-var Typeinfo-entry-input-var => eax +12018 (compute-size-of-var %eax *(ebp+0xc) *(ebp+0x10)) # => eax +12019 # result += eax +12020 01/add-to %edi 0/r32/eax +12021 # curr += row-size +12022 81 0/subop/add %ecx 0x10/imm32 # Typeinfo-fields-row-size +12023 # +12024 eb/jump loop/disp8 +12025 } +12026 # - save result +12027 89/<- *(esi+0xc) 7/r32/edi # Typeinfo-total-size-in-bytes +12028 $populate-mu-type-sizes-in-type:end: +12029 # . restore registers +12030 5f/pop-to-edi +12031 5e/pop-to-esi +12032 5a/pop-to-edx +12033 59/pop-to-ecx +12034 58/pop-to-eax +12035 # . epilogue +12036 89/<- %esp 5/r32/ebp +12037 5d/pop-to-ebp +12038 c3/return +12039 +12040 $populate-mu-type-sizes-in-type:abort: +12041 (write-buffered *(ebp+0xc) "cycle in type definitions\n") +12042 (flush *(ebp+0xc)) +12043 (stop *(ebp+0x10) 1) +12044 # never gets here +12045 +12046 # Analogous to size-of, except we need to compute what size-of can just read +12047 # off the right data structures. +12048 compute-size-of-var: # in: (addr var), err: (addr buffered-file), ed: (addr exit-descriptor) -> result/eax: int +12049 # . prologue +12050 55/push-ebp +12051 89/<- %ebp 4/r32/esp +12052 # . push registers +12053 51/push-ecx +12054 # var t/ecx: (addr type-tree) = lookup(v->type) +12055 8b/-> *(ebp+8) 1/r32/ecx +12056 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax +12057 89/<- %ecx 0/r32/eax +12058 # if (t->is-atom == false) t = lookup(t->left) +12059 { +12060 81 7/subop/compare *ecx 0/imm32/false # Type-tree-is-atom +12061 75/jump-if-!= break/disp8 +12062 (lookup *(ecx+4) *(ecx+8)) # Type-tree-left Type-tree-left => eax +12063 89/<- %ecx 0/r32/eax +12064 } +12065 # TODO: ensure t is an atom +12066 (compute-size-of-type-id *(ecx+4) *(ebp+0xc) *(ebp+0x10)) # Type-tree-value => eax +12067 $compute-size-of-var:end: +12068 # . restore registers +12069 59/pop-to-ecx +12070 # . epilogue +12071 89/<- %esp 5/r32/ebp +12072 5d/pop-to-ebp +12073 c3/return 12074 -12075 check-mu-numberlike-arg: # v: (addr stmt-var), stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +12075 compute-size-of-type-id: # t: type-id, err: (addr buffered-file), ed: (addr exit-descriptor) -> result/eax: int 12076 # . prologue 12077 55/push-ebp 12078 89/<- %ebp 4/r32/esp 12079 # . save registers -12080 50/push-eax -12081 56/push-esi -12082 # var t/esi: (addr type-tree) = lookup(v->value->type) -12083 8b/-> *(ebp+8) 0/r32/eax -12084 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -12085 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax -12086 89/<- %esi 0/r32/eax -12087 $check-mu-numberlike-arg:check-literal: -12088 # if t is an int, return -12089 (is-simple-mu-type? %esi 0) # literal => eax -12090 3d/compare-eax-and 0/imm32/false -12091 75/jump-if-!= $check-mu-numberlike-arg:end/disp8 -12092 $check-mu-numberlike-arg:check-addr: -12093 # if t is an addr and v is dereferenced, return -12094 { -12095 (is-mu-addr-type? %esi) # => eax -12096 3d/compare-eax-and 0/imm32/false -12097 74/jump-if-= break/disp8 -12098 8b/-> *(ebp+8) 0/r32/eax -12099 8b/-> *(eax+0x10) 0/r32/eax -12100 3d/compare-eax-and 0/imm32/false -12101 75/jump-if-!= $check-mu-numberlike-arg:end/disp8 -12102 } -12103 $check-mu-numberlike-arg:output-checks: -12104 (check-mu-numberlike-output *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14) *(ebp+0x18)) -12105 $check-mu-numberlike-arg:end: -12106 # . restore registers -12107 5e/pop-to-esi -12108 58/pop-to-eax -12109 # . epilogue -12110 89/<- %esp 5/r32/ebp -12111 5d/pop-to-ebp -12112 c3/return -12113 -12114 check-mu-numberlike-output: # v: (addr stmt-var), stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -12115 # . prologue -12116 55/push-ebp -12117 89/<- %ebp 4/r32/esp -12118 # . save registers -12119 50/push-eax -12120 56/push-esi -12121 # var t/esi: (addr type-tree) = lookup(v->value->type) -12122 8b/-> *(ebp+8) 0/r32/eax -12123 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -12124 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax -12125 89/<- %esi 0/r32/eax -12126 $check-mu-numberlike-output:check-int: -12127 # if t is an int, return -12128 (is-simple-mu-type? %esi 1) # int => eax -12129 3d/compare-eax-and 0/imm32/false -12130 75/jump-if-!= $check-mu-numberlike-output:end/disp8 -12131 $check-mu-numberlike-output:check-boolean: -12132 # if t is a boolean, return -12133 (is-simple-mu-type? %esi 5) # boolean => eax -12134 3d/compare-eax-and 0/imm32/false -12135 75/jump-if-!= $check-mu-numberlike-output:end/disp8 -12136 $check-mu-numberlike-output:check-byte: -12137 # if t is a byte, return -12138 (is-simple-mu-type? %esi 8) # byte => eax -12139 3d/compare-eax-and 0/imm32/false -12140 75/jump-if-!= $check-mu-numberlike-output:end/disp8 -12141 e9/jump $check-mu-numberlike-output:fail/disp32 -12142 $check-mu-numberlike-output:end: -12143 # . restore registers -12144 5e/pop-to-esi -12145 58/pop-to-eax -12146 # . epilogue -12147 89/<- %esp 5/r32/ebp -12148 5d/pop-to-ebp -12149 c3/return -12150 -12151 $check-mu-numberlike-output:fail: -12152 # otherwise raise an error -12153 (write-buffered *(ebp+0x14) "fn ") -12154 8b/-> *(ebp+0x10) 0/r32/eax -12155 (lookup *eax *(eax+4)) # Function-name Function-name => eax -12156 (write-buffered *(ebp+0x14) %eax) -12157 (write-buffered *(ebp+0x14) ": stmt ") -12158 8b/-> *(ebp+0xc) 0/r32/eax -12159 (lookup *(eax+4) *(eax+8)) # Stmt1-operation Stmt1-operation => eax -12160 (write-buffered *(ebp+0x14) %eax) -12161 (write-buffered *(ebp+0x14) ": only non-addr scalar args permitted\n") -12162 (flush *(ebp+0x14)) -12163 (stop *(ebp+0x18) 1) -12164 # never gets here -12165 -12166 check-mu-copy-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -12167 # . prologue -12168 55/push-ebp -12169 89/<- %ebp 4/r32/esp -12170 # . save registers -12171 $check-mu-copy-stmt:end: -12172 # . restore registers -12173 # . epilogue -12174 89/<- %esp 5/r32/ebp -12175 5d/pop-to-ebp -12176 c3/return -12177 -12178 check-mu-copy-to-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -12179 # . prologue -12180 55/push-ebp -12181 89/<- %ebp 4/r32/esp -12182 # . save registers -12183 $check-mu-copy-to-stmt:end: -12184 # . restore registers -12185 # . epilogue -12186 89/<- %esp 5/r32/ebp -12187 5d/pop-to-ebp -12188 c3/return -12189 -12190 check-mu-compare-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -12191 # . prologue -12192 55/push-ebp -12193 89/<- %ebp 4/r32/esp -12194 # . save registers -12195 $check-mu-compare-stmt:end: -12196 # . restore registers -12197 # . epilogue -12198 89/<- %esp 5/r32/ebp -12199 5d/pop-to-ebp -12200 c3/return -12201 -12202 check-mu-address-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -12203 # . prologue -12204 55/push-ebp -12205 89/<- %ebp 4/r32/esp -12206 # . save registers -12207 $check-mu-address-stmt:end: -12208 # . restore registers -12209 # . epilogue -12210 89/<- %esp 5/r32/ebp -12211 5d/pop-to-ebp -12212 c3/return -12213 -12214 check-mu-get-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -12215 # . prologue -12216 55/push-ebp -12217 89/<- %ebp 4/r32/esp -12218 # . save registers -12219 50/push-eax -12220 51/push-ecx -12221 52/push-edx -12222 53/push-ebx -12223 56/push-esi -12224 57/push-edi -12225 # esi = stmt -12226 8b/-> *(ebp+8) 6/r32/esi -12227 # - check for 0 inouts -12228 # var base/ecx: (addr var) = stmt->inouts->value -12229 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax -12230 3d/compare-eax-and 0/imm32/false -12231 0f 84/jump-if-= $check-mu-get-stmt:error-too-few-inouts/disp32 -12232 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -12233 89/<- %ecx 0/r32/eax -12234 $check-mu-get-stmt:check-base: -12235 # - check base type -12236 # if it's an 'addr', check that it's in a register -12237 # var base-type/ebx: (addr type-tree) = lookup(base->type) -12238 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax -12239 89/<- %ebx 0/r32/eax -12240 { -12241 81 7/subop/compare *ebx 0/imm32/false # Type-tree-is-atom -12242 0f 85/jump-if-!= break/disp32 -12243 $check-mu-get-stmt:base-is-compound: -12244 # if (type->left != addr) break -12245 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax -12246 (is-simple-mu-type? %eax 2) # => eax -12247 3d/compare-eax-and 0/imm32/false -12248 74/jump-if-= break/disp8 -12249 $check-mu-get-stmt:base-is-addr: -12250 # now check for register -12251 81 7/subop/compare *(ecx+0x18) 0/imm32 # Var-register -12252 0f 84/jump-if-= $check-mu-get-stmt:error-base-type-addr-but-not-register/disp32 -12253 $check-mu-get-stmt:base-is-addr-in-register: -12254 # type->left is now an addr; skip it -12255 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax -12256 81 7/subop/compare *(eax+0xc) 0/imm32 # Type-tree-right -12257 0f 85/jump-if-!= $check-mu-get-stmt:error-bad-base/disp32 -12258 $check-mu-get-stmt:base-is-addr-to-atom-in-register: -12259 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax -12260 89/<- %ebx 0/r32/eax -12261 } -12262 $check-mu-get-stmt:check-base-typeinfo: -12263 # ensure type is a container -12264 # var base-type-id/ebx: type-id = base-type->value -12265 8b/-> *(ebx+4) 3/r32/ebx # Type-tree-value -12266 (is-container? %ebx) # => eax -12267 3d/compare-eax-and 0/imm32/false -12268 0f 84/jump-if-= $check-mu-get-stmt:error-bad-base/disp32 -12269 # var base-typeinfo/edx: (addr typeinfo) = find-typeinfo(base-type-id) -12270 # . var container/ecx: (handle typeinfo) -12271 68/push 0/imm32 -12272 68/push 0/imm32 -12273 89/<- %ecx 4/r32/esp -12274 # . -12275 (find-typeinfo %ebx %ecx) -12276 (lookup *ecx *(ecx+4)) # => eax -12277 # . reclaim container -12278 81 0/subop/add %esp 8/imm32 -12279 # . -12280 89/<- %edx 0/r32/eax -12281 # var offset/ecx: (addr stmt-var) = stmt->inouts->next -12282 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax -12283 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax -12284 89/<- %ecx 0/r32/eax -12285 # - check for 1 inout -12286 3d/compare-eax-and 0/imm32/false -12287 0f 84/jump-if-= $check-mu-get-stmt:error-too-few-inouts/disp32 -12288 # var offset/ecx: (addr var) = lookup(offset->value) -12289 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax -12290 89/<- %ecx 0/r32/eax -12291 # - check for valid field -12292 81 7/subop/compare *(ecx+0x14) -1/imm32/uninitialized # Var-offset -12293 0f 84/jump-if-= $check-mu-get-stmt:error-bad-field/disp32 -12294 # - check for too many inouts -12295 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax -12296 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax -12297 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax -12298 3d/compare-eax-and 0/imm32/false -12299 0f 85/jump-if-!= $check-mu-get-stmt:error-too-many-inouts/disp32 -12300 # var output/edi: (addr var) = stmt->outputs->value -12301 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax -12302 # - check for 0 outputs -12303 3d/compare-eax-and 0/imm32/false -12304 0f 84/jump-if-= $check-mu-get-stmt:error-too-few-outputs/disp32 -12305 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -12306 89/<- %edi 0/r32/eax -12307 $check-mu-get-stmt:check-output-type: -12308 # - check output type -12309 # must be in register -12310 (lookup *(edi+0x18) *(edi+0x1c)) # Var-register Var-register => eax -12311 3d/compare-eax-and 0/imm32 -12312 0f 84/jump-if-= $check-mu-get-stmt:error-output-not-in-register/disp32 -12313 # must have a non-atomic type -12314 (lookup *(edi+8) *(edi+0xc)) # Var-type Var-type => eax -12315 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom -12316 0f 85/jump-if-!= $check-mu-get-stmt:error-output-type-not-address/disp32 -12317 # type must start with (addr ...) -12318 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax -12319 (is-simple-mu-type? %eax 2) # => eax -12320 3d/compare-eax-and 0/imm32/false -12321 0f 84/jump-if-= $check-mu-get-stmt:error-output-type-not-address/disp32 -12322 $check-mu-get-stmt:check-output-type-match: -12323 # payload of addr type must match 'type' definition -12324 (lookup *(edi+8) *(edi+0xc)) # Var-type Var-type => eax -12325 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax -12326 # if (payload->right == null) payload = payload->left -12327 81 7/subop/compare *(eax+0xc) 0/imm32/null # Type-tree-right -12328 { -12329 75/jump-if-!= break/disp8 -12330 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax -12331 } -12332 89/<- %edi 0/r32/eax -12333 # . var output-name/ecx: (addr array byte) -12334 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax -12335 89/<- %ecx 0/r32/eax -12336 # . var base-typeinfo-entry/eax: (addr handle typeinfo-entry) -12337 (lookup *(edx+4) *(edx+8)) # Typeinfo-fields Typeinfo-fields => eax -12338 (get %eax %ecx 0x10) # => eax -12339 # . -12340 (lookup *eax *(eax+4)) # => eax -12341 (lookup *eax *(eax+4)) # Typeinfo-entry-input-var Typeinfo-entry-input-var => eax -12342 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax -12343 # . -12344 (type-equal? %edi %eax) # => eax -12345 3d/compare-eax-and 0/imm32/false -12346 0f 84/jump-if-= $check-mu-get-stmt:error-bad-output-type/disp32 -12347 # - check for too many outputs -12348 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax -12349 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax -12350 3d/compare-eax-and 0/imm32/false -12351 0f 85/jump-if-!= $check-mu-get-stmt:error-too-many-outputs/disp32 -12352 $check-mu-get-stmt:end: -12353 # . restore registers -12354 5f/pop-to-edi -12355 5e/pop-to-esi -12356 5b/pop-to-ebx -12357 5a/pop-to-edx -12358 59/pop-to-ecx -12359 58/pop-to-eax -12360 # . epilogue -12361 89/<- %esp 5/r32/ebp -12362 5d/pop-to-ebp -12363 c3/return -12364 -12365 $check-mu-get-stmt:error-too-few-inouts: -12366 (write-buffered *(ebp+0x10) "fn ") -12367 8b/-> *(ebp+0xc) 0/r32/eax -12368 (lookup *eax *(eax+4)) # Function-name Function-name => eax -12369 (write-buffered *(ebp+0x10) %eax) -12370 (write-buffered *(ebp+0x10) ": stmt get: too few inouts (2 required)\n") -12371 (flush *(ebp+0x10)) -12372 (stop *(ebp+0x14) 1) -12373 # never gets here -12374 -12375 $check-mu-get-stmt:error-too-many-inouts: -12376 (write-buffered *(ebp+0x10) "fn ") -12377 8b/-> *(ebp+0xc) 0/r32/eax -12378 (lookup *eax *(eax+4)) # Function-name Function-name => eax -12379 (write-buffered *(ebp+0x10) %eax) -12380 (write-buffered *(ebp+0x10) ": stmt get: too many inouts (2 required)\n") -12381 (flush *(ebp+0x10)) -12382 (stop *(ebp+0x14) 1) -12383 # never gets here -12384 -12385 $check-mu-get-stmt:error-too-few-outputs: -12386 (write-buffered *(ebp+0x10) "fn ") -12387 8b/-> *(ebp+0xc) 0/r32/eax -12388 (lookup *eax *(eax+4)) # Function-name Function-name => eax -12389 (write-buffered *(ebp+0x10) %eax) -12390 (write-buffered *(ebp+0x10) ": stmt get: must have an output\n") -12391 (flush *(ebp+0x10)) -12392 (stop *(ebp+0x14) 1) -12393 # never gets here -12394 -12395 $check-mu-get-stmt:error-too-many-outputs: -12396 (write-buffered *(ebp+0x10) "fn ") -12397 8b/-> *(ebp+0xc) 0/r32/eax -12398 (lookup *eax *(eax+4)) # Function-name Function-name => eax -12399 (write-buffered *(ebp+0x10) %eax) -12400 (write-buffered *(ebp+0x10) ": stmt get: too many outputs (1 required)\n") -12401 (flush *(ebp+0x10)) -12402 (stop *(ebp+0x14) 1) -12403 # never gets here -12404 -12405 $check-mu-get-stmt:error-bad-base: -12406 # error("fn " fn ": stmt get: var '" base->name "' must have a 'type' definition\n") -12407 (write-buffered *(ebp+0x10) "fn ") -12408 8b/-> *(ebp+0xc) 0/r32/eax -12409 (lookup *eax *(eax+4)) # Function-name Function-name => eax -12410 (write-buffered *(ebp+0x10) %eax) -12411 (write-buffered *(ebp+0x10) ": stmt get: var '") -12412 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax -12413 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -12414 (lookup *eax *(eax+4)) # Var-name Var-name => eax -12415 (write-buffered *(ebp+0x10) %eax) -12416 (write-buffered *(ebp+0x10) "' must have a 'type' definition\n") -12417 (flush *(ebp+0x10)) -12418 (stop *(ebp+0x14) 1) -12419 # never gets here -12420 -12421 $check-mu-get-stmt:error-base-type-addr-but-not-register: -12422 (write-buffered *(ebp+0x10) "fn ") -12423 8b/-> *(ebp+0xc) 0/r32/eax -12424 (lookup *eax *(eax+4)) # Function-name Function-name => eax -12425 (write-buffered *(ebp+0x10) %eax) -12426 (write-buffered *(ebp+0x10) ": stmt get: var '") -12427 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax -12428 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -12429 (lookup *eax *(eax+4)) # Var-name Var-name => eax -12430 (write-buffered *(ebp+0x10) %eax) -12431 (write-buffered *(ebp+0x10) "' is an 'addr' type, and so must live in a register\n") -12432 (flush *(ebp+0x10)) -12433 (stop *(ebp+0x14) 1) -12434 # never gets here -12435 -12436 $check-mu-get-stmt:error-bad-field: -12437 # error("fn " fn ": stmt get: type " type " has no member called '" curr->name "'\n") -12438 (write-buffered *(ebp+0x10) "fn ") -12439 8b/-> *(ebp+0xc) 0/r32/eax -12440 (lookup *eax *(eax+4)) # Function-name Function-name => eax -12441 (write-buffered *(ebp+0x10) %eax) -12442 (write-buffered *(ebp+0x10) ": stmt get: type '") -12443 # . write(Type-id->data[tmp]) -12444 bf/copy-to-edi Type-id/imm32 -12445 (write-buffered *(ebp+0x10) *(edi+ebx<<2+0xc)) -12446 # . -12447 (write-buffered *(ebp+0x10) "' has no member called '") -12448 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax -12449 (write-buffered *(ebp+0x10) %eax) -12450 (write-buffered *(ebp+0x10) "'\n") -12451 (flush *(ebp+0x10)) -12452 (stop *(ebp+0x14) 1) -12453 # never gets here -12454 -12455 $check-mu-get-stmt:error-output-not-in-register: -12456 (write-buffered *(ebp+0x10) "fn ") -12457 8b/-> *(ebp+0xc) 0/r32/eax -12458 (lookup *eax *(eax+4)) # Function-name Function-name => eax -12459 (write-buffered *(ebp+0x10) %eax) -12460 (write-buffered *(ebp+0x10) ": stmt get: output '") -12461 (lookup *edi *(edi+4)) # Var-name Var-name => eax -12462 (write-buffered *(ebp+0x10) %eax) -12463 (write-buffered *(ebp+0x10) "' is not in a register\n") -12464 (flush *(ebp+0x10)) -12465 (stop *(ebp+0x14) 1) -12466 # never gets here -12467 -12468 $check-mu-get-stmt:error-output-type-not-address: -12469 (write-buffered *(ebp+0x10) "fn ") -12470 8b/-> *(ebp+0xc) 0/r32/eax -12471 (lookup *eax *(eax+4)) # Function-name Function-name => eax -12472 (write-buffered *(ebp+0x10) %eax) -12473 (write-buffered *(ebp+0x10) ": stmt get: output must be an address\n") -12474 (flush *(ebp+0x10)) -12475 (stop *(ebp+0x14) 1) -12476 # never gets here -12477 -12478 $check-mu-get-stmt:error-bad-output-type: -12479 (write-buffered *(ebp+0x10) "fn ") -12480 8b/-> *(ebp+0xc) 0/r32/eax -12481 (lookup *eax *(eax+4)) # Function-name Function-name => eax -12482 (write-buffered *(ebp+0x10) %eax) -12483 (write-buffered *(ebp+0x10) ": stmt get: wrong output type for member '") -12484 (write-buffered *(ebp+0x10) %ecx) -12485 (write-buffered *(ebp+0x10) "' of type '") -12486 bf/copy-to-edi Type-id/imm32 -12487 (write-buffered *(ebp+0x10) *(edi+ebx<<2+0xc)) -12488 (write-buffered *(ebp+0x10) "'\n") -12489 (flush *(ebp+0x10)) -12490 (stop *(ebp+0x14) 1) -12491 # never gets here -12492 -12493 check-mu-index-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -12494 # . prologue -12495 55/push-ebp -12496 89/<- %ebp 4/r32/esp -12497 # . save registers -12498 $check-mu-index-stmt:end: -12499 # . restore registers -12500 # . epilogue -12501 89/<- %esp 5/r32/ebp -12502 5d/pop-to-ebp -12503 c3/return -12504 -12505 check-mu-length-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -12506 # . prologue -12507 55/push-ebp -12508 89/<- %ebp 4/r32/esp -12509 # . save registers -12510 $check-mu-length-stmt:end: -12511 # . restore registers -12512 # . epilogue -12513 89/<- %esp 5/r32/ebp -12514 5d/pop-to-ebp -12515 c3/return -12516 -12517 check-mu-compute-offset-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -12518 # . prologue -12519 55/push-ebp -12520 89/<- %ebp 4/r32/esp -12521 # . save registers -12522 $check-mu-compute-offset-stmt:end: -12523 # . restore registers -12524 # . epilogue -12525 89/<- %esp 5/r32/ebp -12526 5d/pop-to-ebp -12527 c3/return -12528 -12529 check-mu-allocate-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -12530 # . prologue -12531 55/push-ebp -12532 89/<- %ebp 4/r32/esp -12533 # . save registers -12534 $check-mu-allocate-stmt:end: -12535 # . restore registers -12536 # . epilogue -12537 89/<- %esp 5/r32/ebp -12538 5d/pop-to-ebp -12539 c3/return -12540 -12541 check-mu-populate-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -12542 # . prologue -12543 55/push-ebp -12544 89/<- %ebp 4/r32/esp -12545 # . save registers -12546 $check-mu-populate-stmt:end: -12547 # . restore registers -12548 # . epilogue -12549 89/<- %esp 5/r32/ebp -12550 5d/pop-to-ebp -12551 c3/return -12552 -12553 check-mu-populate-stream-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -12554 # . prologue -12555 55/push-ebp -12556 89/<- %ebp 4/r32/esp -12557 # . save registers -12558 $check-mu-populate-stream-stmt:end: -12559 # . restore registers -12560 # . epilogue -12561 89/<- %esp 5/r32/ebp -12562 5d/pop-to-ebp -12563 c3/return -12564 -12565 check-mu-read-from-stream-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -12566 # . prologue -12567 55/push-ebp -12568 89/<- %ebp 4/r32/esp -12569 # . save registers -12570 $check-mu-read-from-stream-stmt:end: -12571 # . restore registers -12572 # . epilogue -12573 89/<- %esp 5/r32/ebp -12574 5d/pop-to-ebp -12575 c3/return -12576 -12577 check-mu-write-to-stream-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -12578 # . prologue -12579 55/push-ebp -12580 89/<- %ebp 4/r32/esp -12581 # . save registers -12582 $check-mu-write-to-stream-stmt:end: -12583 # . restore registers -12584 # . epilogue -12585 89/<- %esp 5/r32/ebp -12586 5d/pop-to-ebp -12587 c3/return -12588 -12589 check-mu-call: # stmt: (addr stmt), callee: (addr function), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -12590 # . prologue -12591 55/push-ebp -12592 89/<- %ebp 4/r32/esp -12593 # var type-parameters: (addr table (handle array byte) (addr type-tree) 8) -12594 68/push 0/imm32 -12595 # var type-parameters-storage: (table (handle array byte) (addr type-tree) 8) -12596 81 5/subop/subtract %esp 0x60/imm32 -12597 68/push 0x60/imm32/size -12598 68/push 0/imm32/read -12599 68/push 0/imm32/write -12600 # save a pointer to type-parameters-storage at type-parameters -12601 89/<- *(ebp-4) 4/r32/esp -12602 (clear-stream *(ebp-4)) -12603 # . save registers -12604 50/push-eax -12605 51/push-ecx -12606 52/push-edx -12607 53/push-ebx -12608 56/push-esi -12609 57/push-edi -12610 # esi = stmt -12611 8b/-> *(ebp+8) 6/r32/esi -12612 # edi = callee -12613 8b/-> *(ebp+0xc) 7/r32/edi -12614 # var inouts/ecx: (addr stmt-var) = lookup(stmt->inouts) -12615 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax -12616 89/<- %ecx 0/r32/eax -12617 # var expected/edx: (addr list var) = lookup(f->inouts) -12618 (lookup *(edi+8) *(edi+0xc)) # Function-inouts Function-inouts => eax -12619 89/<- %edx 0/r32/eax -12620 { -12621 $check-mu-call:check-for-inouts: -12622 # if (inouts == 0) break -12623 81 7/subop/compare %ecx 0/imm32 -12624 0f 84/jump-if-= break/disp32 -12625 # if (expected == 0) error -12626 81 7/subop/compare %edx 0/imm32 -12627 0f 84/jump-if-= break/disp32 -12628 $check-mu-call:check-inout-type: -12629 # var v/eax: (addr v) = lookup(inouts->value) -12630 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax -12631 # var t/ebx: (addr type-tree) = lookup(v->type) -12632 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax -12633 89/<- %ebx 0/r32/eax -12634 # if (inouts->is-deref?) t = t->right # TODO: check that t->left is an addr -12635 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref -12636 { -12637 74/jump-if-= break/disp8 -12638 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax -12639 89/<- %ebx 0/r32/eax -12640 # if t->right is null, t = t->left -12641 81 7/subop/compare *(ebx+0xc) 0/imm32 # Type-tree-right -12642 75/jump-if-!= break/disp8 -12643 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax -12644 89/<- %ebx 0/r32/eax -12645 } -12646 # var v2/eax: (addr v) = lookup(expected->value) -12647 (lookup *edx *(edx+4)) # List-value List-value => eax -12648 # var t2/eax: (addr type-tree) = lookup(v2->type) -12649 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax -12650 # if (t != t2) error -12651 (type-match? %eax %ebx *(ebp-4)) # => eax -12652 3d/compare-eax-and 0/imm32/false -12653 { -12654 0f 85/jump-if-!= break/disp32 -12655 (write-buffered *(ebp+0x14) "fn ") -12656 8b/-> *(ebp+0x10) 0/r32/eax -12657 (lookup *eax *(eax+4)) # Function-name Function-name => eax -12658 (write-buffered *(ebp+0x14) %eax) -12659 (write-buffered *(ebp+0x14) ": call ") -12660 (lookup *edi *(edi+4)) # Function-name Function-name => eax -12661 (write-buffered *(ebp+0x14) %eax) -12662 (write-buffered *(ebp+0x14) ": type for inout '") -12663 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax -12664 (lookup *eax *(eax+4)) # Var-name Var-name => eax -12665 (write-buffered *(ebp+0x14) %eax) -12666 (write-buffered *(ebp+0x14) "' is not right\n") -12667 (flush *(ebp+0x14)) -12668 (stop *(ebp+0x18) 1) -12669 } -12670 $check-mu-call:continue-to-next-inout: -12671 # inouts = lookup(inouts->next) -12672 (lookup *(ecx+8) *(ecx+0xc)) # Stmt-var-next Stmt-var-next => eax -12673 89/<- %ecx 0/r32/eax -12674 # expected = lookup(expected->next) -12675 (lookup *(edx+8) *(edx+0xc)) # List-next List-next => eax -12676 89/<- %edx 0/r32/eax -12677 # -12678 e9/jump loop/disp32 -12679 } -12680 $check-mu-call:check-inout-count: -12681 # if (inouts == expected) proceed -12682 39/compare %ecx 2/r32/edx -12683 { -12684 0f 84/jump-if-= break/disp32 -12685 # exactly one of the two is null -12686 # if (inouts == 0) error("too many inouts") -12687 { -12688 81 7/subop/compare %ecx 0/imm32 -12689 0f 84/jump-if-= break/disp32 -12690 (write-buffered *(ebp+0x14) "fn ") -12691 8b/-> *(ebp+0x10) 0/r32/eax -12692 (lookup *eax *(eax+4)) # Function-name Function-name => eax -12693 (write-buffered *(ebp+0x14) %eax) -12694 (write-buffered *(ebp+0x14) ": call ") -12695 (lookup *edi *(edi+4)) # Function-name Function-name => eax -12696 (write-buffered *(ebp+0x14) %eax) -12697 (write-buffered *(ebp+0x14) ": too many inouts\n") -12698 (flush *(ebp+0x14)) -12699 (stop *(ebp+0x18) 1) -12700 } -12701 # if (expected == 0) error("too few inouts") -12702 { -12703 81 7/subop/compare %edx 0/imm32 -12704 0f 84/jump-if-= break/disp32 -12705 (write-buffered *(ebp+0x14) "fn ") -12706 8b/-> *(ebp+0x10) 0/r32/eax -12707 (lookup *eax *(eax+4)) # Function-name Function-name => eax -12708 (write-buffered *(ebp+0x14) %eax) -12709 (write-buffered *(ebp+0x14) ": call ") -12710 (lookup *edi *(edi+4)) # Function-name Function-name => eax -12711 (write-buffered *(ebp+0x14) %eax) -12712 (write-buffered *(ebp+0x14) ": too few inouts\n") -12713 (flush *(ebp+0x14)) -12714 (stop *(ebp+0x18) 1) -12715 } -12716 } -12717 $check-mu-call:check-outputs: -12718 # var outputs/ecx: (addr stmt-var) = lookup(stmt->outputs) -12719 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax -12720 89/<- %ecx 0/r32/eax -12721 # var expected/edx: (addr list var) = lookup(f->outputs) -12722 (lookup *(edi+0x10) *(edi+0x14)) # Function-outputs Function-outputs => eax -12723 89/<- %edx 0/r32/eax -12724 { -12725 $check-mu-call:check-for-outputs: -12726 # if (outputs == 0) break -12727 81 7/subop/compare %ecx 0/imm32 -12728 0f 84/jump-if-= break/disp32 -12729 # if (expected == 0) error -12730 81 7/subop/compare %edx 0/imm32 -12731 0f 84/jump-if-= break/disp32 -12732 $check-mu-call:check-output-type: -12733 # var v/eax: (addr v) = lookup(outputs->value) -12734 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax -12735 # var t/ebx: (addr type-tree) = lookup(v->type) -12736 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax -12737 89/<- %ebx 0/r32/eax -12738 # if (outputs->is-deref?) t = t->right # TODO: check that t->left is an addr -12739 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref -12740 { -12741 74/jump-if-= break/disp8 -12742 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax -12743 89/<- %ebx 0/r32/eax -12744 } -12745 # var v2/eax: (addr v) = lookup(expected->value) -12746 (lookup *edx *(edx+4)) # List-value List-value => eax -12747 # var t2/eax: (addr type-tree) = lookup(v2->type) -12748 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax -12749 # if (t != t2) error -12750 (type-match? %eax %ebx *(ebp-4)) # => eax -12751 3d/compare-eax-and 0/imm32/false -12752 { -12753 0f 85/jump-if-!= break/disp32 -12754 (write-buffered *(ebp+0x14) "fn ") -12755 8b/-> *(ebp+0x10) 0/r32/eax -12756 (lookup *eax *(eax+4)) # Function-name Function-name => eax -12757 (write-buffered *(ebp+0x14) %eax) -12758 (write-buffered *(ebp+0x14) ": call ") -12759 (lookup *edi *(edi+4)) # Function-name Function-name => eax -12760 (write-buffered *(ebp+0x14) %eax) -12761 (write-buffered *(ebp+0x14) ": type for output '") -12762 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax -12763 (lookup *eax *(eax+4)) # Var-name Var-name => eax -12764 (write-buffered *(ebp+0x14) %eax) -12765 (write-buffered *(ebp+0x14) "' is not right\n") -12766 (flush *(ebp+0x14)) -12767 (stop *(ebp+0x18) 1) -12768 } -12769 $check-mu-call:check-output-register: -12770 # var v/eax: (addr v) = lookup(outputs->value) -12771 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax -12772 # var r/ebx: (addr array byte) = lookup(v->register) -12773 (lookup *(eax+18) *(eax+0x1c)) # Var-register Var-register => eax -12774 89/<- %ebx 0/r32/eax -12775 # var v2/eax: (addr v) = lookup(expected->value) -12776 (lookup *edx *(edx+4)) # Stmt-var-value Stmt-var-value => eax -12777 # var r2/eax: (addr array byte) = lookup(v2->register) -12778 (lookup *(eax+18) *(eax+0x1c)) # Var-register Var-register => eax -12779 # if (r != r2) error -12780 (string-equal? %eax %ebx) # => eax -12781 3d/compare-eax-and 0/imm32/false -12782 { -12783 0f 85/jump-if-!= break/disp32 -12784 (write-buffered *(ebp+0x14) "fn ") -12785 8b/-> *(ebp+0x10) 0/r32/eax -12786 (lookup *eax *(eax+4)) # Function-name Function-name => eax -12787 (write-buffered *(ebp+0x14) %eax) -12788 (write-buffered *(ebp+0x14) ": call ") -12789 (lookup *edi *(edi+4)) # Function-name Function-name => eax -12790 (write-buffered *(ebp+0x14) %eax) -12791 (write-buffered *(ebp+0x14) ": register for output '") -12792 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax -12793 (lookup *eax *(eax+4)) # Var-name Var-name => eax -12794 (write-buffered *(ebp+0x14) %eax) -12795 (write-buffered *(ebp+0x14) "' is not right\n") -12796 (flush *(ebp+0x14)) -12797 (stop *(ebp+0x18) 1) -12798 } -12799 $check-mu-call:continue-to-next-output: -12800 # outputs = lookup(outputs->next) -12801 (lookup *(ecx+8) *(ecx+0xc)) # Stmt-var-next Stmt-var-next => eax -12802 89/<- %ecx 0/r32/eax -12803 # expected = lookup(expected->next) -12804 (lookup *(edx+8) *(edx+0xc)) # List-next List-next => eax -12805 89/<- %edx 0/r32/eax -12806 # -12807 e9/jump loop/disp32 -12808 } -12809 $check-mu-call:check-output-count: -12810 # if (outputs == expected) proceed -12811 39/compare %ecx 2/r32/edx -12812 { -12813 0f 84/jump-if-= break/disp32 -12814 # exactly one of the two is null -12815 # if (outputs == 0) error("too many outputs") -12816 { -12817 81 7/subop/compare %ecx 0/imm32 -12818 0f 84/jump-if-= break/disp32 -12819 (write-buffered *(ebp+0x14) "fn ") -12820 8b/-> *(ebp+0x10) 0/r32/eax -12821 (lookup *eax *(eax+4)) # Function-name Function-name => eax -12822 (write-buffered *(ebp+0x14) %eax) -12823 (write-buffered *(ebp+0x14) ": call ") -12824 (lookup *edi *(edi+4)) # Function-name Function-name => eax -12825 (write-buffered *(ebp+0x14) %eax) -12826 (write-buffered *(ebp+0x14) ": too many outputs\n") -12827 (flush *(ebp+0x14)) -12828 (stop *(ebp+0x18) 1) -12829 } -12830 # if (expected == 0) error("too few outputs") -12831 { -12832 81 7/subop/compare %edx 0/imm32 -12833 0f 84/jump-if-= break/disp32 -12834 (write-buffered *(ebp+0x14) "fn ") -12835 8b/-> *(ebp+0x10) 0/r32/eax -12836 (lookup *eax *(eax+4)) # Function-name Function-name => eax -12837 (write-buffered *(ebp+0x14) %eax) -12838 (write-buffered *(ebp+0x14) ": call ") -12839 (lookup *edi *(edi+4)) # Function-name Function-name => eax -12840 (write-buffered *(ebp+0x14) %eax) -12841 (write-buffered *(ebp+0x14) ": too few outputs\n") -12842 (flush *(ebp+0x14)) -12843 (stop *(ebp+0x18) 1) -12844 } -12845 } -12846 $check-mu-call:end: -12847 # . restore registers -12848 5f/pop-to-edi -12849 5e/pop-to-esi -12850 5b/pop-to-ebx -12851 5a/pop-to-edx -12852 59/pop-to-ecx -12853 58/pop-to-eax -12854 # . reclaim locals exclusively on the stack -12855 81 0/subop/add %esp 0x70/imm32 -12856 # . epilogue -12857 89/<- %esp 5/r32/ebp -12858 5d/pop-to-ebp -12859 c3/return -12860 -12861 # like type-equal? but takes literals into account -12862 type-match?: # def: (addr type-tree), call: (addr type-tree), type-parameters: (addr table (handle array byte) (addr type-tree)) -> result/eax: boolean -12863 # . prologue -12864 55/push-ebp -12865 89/<- %ebp 4/r32/esp -12866 # if (call == literal) return true # TODO: more precise -12867 (is-simple-mu-type? *(ebp+0xc) 0) # literal => eax -12868 3d/compare-eax-and 0/imm32/false -12869 b8/copy-to-eax 1/imm32/true -12870 75/jump-if-!= $type-match?:end/disp8 -12871 $type-match?:baseline: -12872 # otherwise fall back -12873 (type-component-match? *(ebp+8) *(ebp+0xc) *(ebp+0x10)) # => eax -12874 $type-match?:end: -12875 # . epilogue -12876 89/<- %esp 5/r32/ebp -12877 5d/pop-to-ebp -12878 c3/return -12879 -12880 type-component-match?: # def: (addr type-tree), call: (addr type-tree), type-parameters: (addr table (handle array byte) (addr type-tree)) -> result/eax: boolean -12881 # . prologue -12882 55/push-ebp -12883 89/<- %ebp 4/r32/esp -12884 # . save registers -12885 51/push-ecx -12886 52/push-edx -12887 53/push-ebx -12888 # ecx = def -12889 8b/-> *(ebp+8) 1/r32/ecx -12890 # edx = call -12891 8b/-> *(ebp+0xc) 2/r32/edx -12892 $type-component-match?:compare-addr: -12893 # if (def == call) return true -12894 8b/-> %ecx 0/r32/eax # Var-type -12895 39/compare %edx 0/r32/eax # Var-type -12896 b8/copy-to-eax 1/imm32/true -12897 0f 84/jump-if-= $type-component-match?:end/disp32 -12898 # if (def == 0) return false -12899 b8/copy-to-eax 0/imm32/false -12900 81 7/subop/compare %ecx 0/imm32 # Type-tree-is-atom -12901 0f 84/jump-if-= $type-component-match?:end/disp32 -12902 # if (call == 0) return false -12903 81 7/subop/compare %edx 0/imm32 # Type-tree-is-atom -12904 0f 84/jump-if-= $type-component-match?:end/disp32 -12905 # if def is a type parameter, just check in type-parameters -12906 { -12907 $type-component-match?:check-type-parameter: -12908 81 7/subop/compare *ecx 0/imm32/false # Type-tree-is-atom -12909 74/jump-if-= break/disp8 -12910 81 7/subop/compare *(ecx+4) 0xa/imm32/type-parameter # Type-tree-value -12911 75/jump-if-!= break/disp8 -12912 $type-component-match?:type-parameter: -12913 (type-parameter-match? *(ecx+8) *(ecx+0xc) %edx *(ebp+0x10)) # => eax -12914 e9/jump $type-component-match?:end/disp32 -12915 } -12916 # if def is a list containing just a type parameter, just check in type-parameters -12917 { -12918 $type-component-match?:check-list-type-parameter: -12919 # if def is a list.. -12920 81 7/subop/compare *ecx 0/imm32/false # Type-tree-is-atom -12921 75/jump-if-!= break/disp8 -12922 # ..that's a singleton -12923 81 7/subop/compare *(ecx+0xc) 0/imm32 # Type-tree-left -12924 75/jump-if-!= break/disp8 -12925 # ..and whose head is a type parameter -12926 (lookup *(ecx+4) *(ecx+8)) # Type-tree-left Type-tree-left => eax -12927 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom -12928 74/jump-if-= break/disp8 -12929 81 7/subop/compare *(eax+4) 0xa/imm32/type-parameter # Type-tree-value -12930 75/jump-if-!= break/disp8 -12931 $type-component-match?:list-type-parameter: -12932 (type-parameter-match? *(eax+8) *(eax+0xc) %edx *(ebp+0x10)) # => eax -12933 e9/jump $type-component-match?:end/disp32 -12934 } -12935 $type-component-match?:compare-atom-state: -12936 # if (def->is-atom? != call->is-atom?) return false -12937 8b/-> *ecx 3/r32/ebx # Type-tree-is-atom -12938 39/compare *edx 3/r32/ebx # Type-tree-is-atom -12939 b8/copy-to-eax 0/imm32/false -12940 0f 85/jump-if-!= $type-component-match?:end/disp32 -12941 # if def->is-atom? return (def->value == call->value) -12942 { -12943 $type-component-match?:check-atom: -12944 81 7/subop/compare %ebx 0/imm32/false -12945 74/jump-if-= break/disp8 -12946 $type-component-match?:is-atom: -12947 8b/-> *(ecx+4) 0/r32/eax # Type-tree-value -12948 39/compare *(edx+4) 0/r32/eax # Type-tree-value -12949 0f 94/set-if-= %al -12950 81 4/subop/and %eax 0xff/imm32 -12951 e9/jump $type-component-match?:end/disp32 -12952 } -12953 $type-component-match?:check-left: -12954 # if (!type-component-match?(def->left, call->left)) return false -12955 (lookup *(ecx+4) *(ecx+8)) # Type-tree-left Type-tree-left => eax -12956 89/<- %ebx 0/r32/eax -12957 (lookup *(edx+4) *(edx+8)) # Type-tree-left Type-tree-left => eax -12958 (type-component-match? %ebx %eax *(ebp+0x10)) # => eax -12959 3d/compare-eax-and 0/imm32/false -12960 74/jump-if-= $type-component-match?:end/disp8 -12961 $type-component-match?:check-right: -12962 # return type-component-match?(def->right, call->right) -12963 (lookup *(ecx+0xc) *(ecx+0x10)) # Type-tree-right Type-tree-right => eax -12964 89/<- %ebx 0/r32/eax -12965 (lookup *(edx+0xc) *(edx+0x10)) # Type-tree-right Type-tree-right => eax -12966 (type-component-match? %ebx %eax *(ebp+0x10)) # => eax -12967 $type-component-match?:end: -12968 # . restore registers -12969 5b/pop-to-ebx -12970 5a/pop-to-edx -12971 59/pop-to-ecx -12972 # . epilogue -12973 89/<- %esp 5/r32/ebp -12974 5d/pop-to-ebp -12975 c3/return -12976 -12977 type-parameter-match?: # type-parameter-name: (handle array byte), type: (addr type-tree), type-parameters: (addr table (handle array byte) (addr type-tree)) -> result/eax: boolean -12978 # . prologue -12979 55/push-ebp -12980 89/<- %ebp 4/r32/esp -12981 # . save registers -12982 51/push-ecx -12983 # -12984 (get-or-insert-handle *(ebp+0x14) *(ebp+8) *(ebp+0xc) 0xc) # => eax -12985 # if parameter wasn't saved, save it -12986 { -12987 81 7/subop/compare *eax 0/imm32 -12988 75/jump-if-!= break/disp8 -12989 8b/-> *(ebp+0x10) 1/r32/ecx -12990 89/<- *eax 1/r32/ecx -12991 } -12992 # -12993 (type-equal? *(ebp+0x10) *eax) # => eax -12994 $type-parameter-match?:end: -12995 # . restore registers -12996 59/pop-to-ecx -12997 # . epilogue -12998 89/<- %esp 5/r32/ebp -12999 5d/pop-to-ebp -13000 c3/return -13001 -13002 size-of: # v: (addr var) -> result/eax: int -13003 # . prologue -13004 55/push-ebp -13005 89/<- %ebp 4/r32/esp -13006 # . save registers -13007 51/push-ecx -13008 # var t/ecx: (addr type-tree) = lookup(v->type) -13009 8b/-> *(ebp+8) 1/r32/ecx -13010 #? (write-buffered Stderr "size-of ") -13011 #? (write-int32-hex-buffered Stderr %ecx) -13012 #? (write-buffered Stderr Newline) -13013 #? (write-buffered Stderr "type allocid: ") -13014 #? (write-int32-hex-buffered Stderr *(ecx+8)) -13015 #? (write-buffered Stderr Newline) -13016 #? (flush Stderr) -13017 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax -13018 89/<- %ecx 0/r32/eax -13019 # if is-mu-array?(t) return size-of-array(t) -13020 { -13021 (is-mu-array? %ecx) # => eax -13022 3d/compare-eax-and 0/imm32/false -13023 74/jump-if-= break/disp8 -13024 (size-of-array %ecx) # => eax -13025 eb/jump $size-of:end/disp8 -13026 } -13027 # if is-mu-stream?(t) return size-of-stream(t) -13028 { -13029 (is-mu-stream? %ecx) # => eax -13030 3d/compare-eax-and 0/imm32/false -13031 74/jump-if-= break/disp8 -13032 (size-of-stream %ecx) # => eax -13033 eb/jump $size-of:end/disp8 -13034 } -13035 # if (!t->is-atom?) t = lookup(t->left) -13036 { -13037 81 7/subop/compare *ecx 0/imm32/false # Type-tree-is-atom -13038 75/jump-if-!= break/disp8 -13039 (lookup *(ecx+4) *(ecx+8)) # Type-tree-left Type-tree-left => eax -13040 89/<- %ecx 0/r32/eax -13041 } -13042 # TODO: assert t->is-atom? -13043 (size-of-type-id *(ecx+4)) # Type-tree-value => eax -13044 $size-of:end: -13045 # . restore registers -13046 59/pop-to-ecx -13047 # . epilogue -13048 89/<- %esp 5/r32/ebp -13049 5d/pop-to-ebp -13050 c3/return -13051 -13052 size-of-deref: # v: (addr var) -> result/eax: int -13053 # . prologue -13054 55/push-ebp -13055 89/<- %ebp 4/r32/esp -13056 # . save registers -13057 51/push-ecx -13058 # var t/ecx: (addr type-tree) = lookup(v->type) -13059 8b/-> *(ebp+8) 1/r32/ecx -13060 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax -13061 89/<- %ecx 0/r32/eax -13062 # TODO: assert(t is an addr) -13063 # t = lookup(t->right) -13064 (lookup *(ecx+0xc) *(ecx+0x10)) # Type-tree-right Type-tree-right => eax -13065 89/<- %ecx 0/r32/eax -13066 # if is-mu-array?(t) return size-of-array(t) -13067 { -13068 (is-mu-array? %ecx) # => eax -13069 3d/compare-eax-and 0/imm32/false -13070 74/jump-if-= break/disp8 -13071 (size-of-array %ecx) # => eax -13072 eb/jump $size-of-deref:end/disp8 -13073 } -13074 # if is-mu-stream?(t) return size-of-stream(t) -13075 { -13076 (is-mu-stream? %ecx) # => eax -13077 3d/compare-eax-and 0/imm32/false -13078 74/jump-if-= break/disp8 -13079 (size-of-stream %ecx) # => eax -13080 eb/jump $size-of-deref:end/disp8 -13081 } -13082 # if (!t->is-atom?) t = lookup(t->left) -13083 { -13084 81 7/subop/compare *ecx 0/imm32/false # Type-tree-is-atom -13085 75/jump-if-!= break/disp8 -13086 (lookup *(ecx+4) *(ecx+8)) # Type-tree-left Type-tree-left => eax -13087 89/<- %ecx 0/r32/eax -13088 } -13089 # TODO: assert t->is-atom? -13090 (size-of-type-id *(ecx+4)) # Type-tree-value => eax -13091 $size-of-deref:end: -13092 # . restore registers -13093 59/pop-to-ecx -13094 # . epilogue -13095 89/<- %esp 5/r32/ebp -13096 5d/pop-to-ebp -13097 c3/return -13098 -13099 is-mu-array?: # t: (addr type-tree) -> result/eax: boolean -13100 # . prologue -13101 55/push-ebp -13102 89/<- %ebp 4/r32/esp -13103 # . save registers -13104 51/push-ecx -13105 # ecx = t -13106 8b/-> *(ebp+8) 1/r32/ecx -13107 # if t->is-atom?, return false -13108 81 7/subop/compare *ecx 0/imm32/false # Type-tree-is-atom -13109 75/jump-if-!= $is-mu-array?:return-false/disp8 -13110 # if !t->left->is-atom?, return false -13111 (lookup *(ecx+4) *(ecx+8)) # Type-tree-left Type-tree-left => eax -13112 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom -13113 74/jump-if-= $is-mu-array?:return-false/disp8 -13114 # return t->left->value == array -13115 81 7/subop/compare *(eax+4) 3/imm32/array-type-id # Type-tree-value -13116 0f 94/set-if-= %al -13117 81 4/subop/and %eax 0xff/imm32 -13118 eb/jump $is-mu-array?:end/disp8 -13119 $is-mu-array?:return-false: -13120 b8/copy-to-eax 0/imm32/false -13121 $is-mu-array?:end: -13122 # . restore registers -13123 59/pop-to-ecx -13124 # . epilogue -13125 89/<- %esp 5/r32/ebp -13126 5d/pop-to-ebp -13127 c3/return -13128 -13129 # size of a statically allocated array where the size is part of the type expression -13130 size-of-array: # a: (addr type-tree) -> result/eax: int -13131 # . prologue -13132 55/push-ebp -13133 89/<- %ebp 4/r32/esp -13134 # . save registers -13135 51/push-ecx -13136 52/push-edx -13137 # -13138 8b/-> *(ebp+8) 1/r32/ecx -13139 # TODO: assert that a->left is 'array' -13140 (lookup *(ecx+0xc) *(ecx+0x10)) # Type-tree-right Type-tree-right => eax -13141 89/<- %ecx 0/r32/eax -13142 # var elem-type/edx: type-id = a->right->left->value -13143 (lookup *(ecx+4) *(ecx+8)) # Type-tree-left Type-tree-left => eax -13144 8b/-> *(eax+4) 2/r32/edx # Type-tree-value -13145 # TODO: assert that a->right->right->left->value == size -13146 # var array-size/ecx: int = a->right->right->left->value-size -13147 (lookup *(ecx+0xc) *(ecx+0x10)) # Type-tree-right Type-tree-right => eax -13148 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax -13149 8b/-> *(eax+8) 1/r32/ecx # Type-tree-value-size -13150 # return 4 + array-size * size-of(elem-type) -13151 (size-of-type-id-as-array-element %edx) # => eax -13152 f7 4/subop/multiply-into-eax %ecx -13153 05/add-to-eax 4/imm32 # for array size -13154 $size-of-array:end: -13155 # . restore registers -13156 5a/pop-to-edx -13157 59/pop-to-ecx -13158 # . epilogue -13159 89/<- %esp 5/r32/ebp -13160 5d/pop-to-ebp -13161 c3/return -13162 -13163 is-mu-stream?: # t: (addr type-tree) -> result/eax: boolean -13164 # . prologue -13165 55/push-ebp -13166 89/<- %ebp 4/r32/esp -13167 # . save registers -13168 51/push-ecx -13169 # ecx = t -13170 8b/-> *(ebp+8) 1/r32/ecx -13171 # if t->is-atom?, return false -13172 81 7/subop/compare *ecx 0/imm32/false # Type-tree-is-atom -13173 75/jump-if-!= $is-mu-stream?:return-false/disp8 -13174 # if !t->left->is-atom?, return false -13175 (lookup *(ecx+4) *(ecx+8)) # Type-tree-left Type-tree-left => eax -13176 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom -13177 74/jump-if-= $is-mu-stream?:return-false/disp8 -13178 # return t->left->value == stream -13179 81 7/subop/compare *(eax+4) 0xb/imm32/stream-type-id # Type-tree-value -13180 0f 94/set-if-= %al -13181 81 4/subop/and %eax 0xff/imm32 -13182 eb/jump $is-mu-stream?:end/disp8 -13183 $is-mu-stream?:return-false: -13184 b8/copy-to-eax 0/imm32/false -13185 $is-mu-stream?:end: -13186 # . restore registers -13187 59/pop-to-ecx -13188 # . epilogue -13189 89/<- %esp 5/r32/ebp -13190 5d/pop-to-ebp -13191 c3/return -13192 -13193 # size of a statically allocated stream where the size is part of the type expression -13194 size-of-stream: # a: (addr type-tree) -> result/eax: int -13195 # . prologue -13196 55/push-ebp -13197 89/<- %ebp 4/r32/esp -13198 # -13199 (size-of-array *(ebp+8)) # assumes we ignore the actual type name 'array' in the type -13200 05/add-to-eax 8/imm32 # for read/write pointers -13201 $size-of-stream:end: -13202 # . epilogue -13203 89/<- %esp 5/r32/ebp -13204 5d/pop-to-ebp -13205 c3/return -13206 -13207 size-of-type-id: # t: type-id -> result/eax: int -13208 # . prologue -13209 55/push-ebp -13210 89/<- %ebp 4/r32/esp -13211 # . save registers -13212 51/push-ecx -13213 # var out/ecx: (handle typeinfo) -13214 68/push 0/imm32 -13215 68/push 0/imm32 -13216 89/<- %ecx 4/r32/esp -13217 # eax = t -13218 8b/-> *(ebp+8) 0/r32/eax -13219 # if t is a literal, return 0 -13220 3d/compare-eax-and 0/imm32 -13221 0f 84/jump-if-= $size-of-type-id:end/disp32 # eax changes type from type-id to int -13222 # if t is a byte, return 4 (because we don't really support non-multiples of 4) -13223 3d/compare-eax-and 8/imm32/byte -13224 { -13225 75/jump-if-!= break/disp8 -13226 b8/copy-to-eax 4/imm32 -13227 eb/jump $size-of-type-id:end/disp8 -13228 } -13229 # if t is a handle, return 8 -13230 3d/compare-eax-and 4/imm32/handle -13231 { -13232 75/jump-if-!= break/disp8 -13233 b8/copy-to-eax 8/imm32 -13234 eb/jump $size-of-type-id:end/disp8 # eax changes type from type-id to int -13235 } -13236 # if t is a user-defined type, return its size -13237 # TODO: support non-atom type -13238 (find-typeinfo %eax %ecx) -13239 { -13240 81 7/subop/compare *ecx 0/imm32 -13241 74/jump-if-= break/disp8 -13242 $size-of-type-id:user-defined: -13243 (lookup *ecx *(ecx+4)) # => eax -13244 8b/-> *(eax+0xc) 0/r32/eax # Typeinfo-total-size-in-bytes -13245 eb/jump $size-of-type-id:end/disp8 -13246 } -13247 # otherwise return the word size -13248 b8/copy-to-eax 4/imm32 -13249 $size-of-type-id:end: -13250 # . reclaim locals -13251 81 0/subop/add %esp 8/imm32 -13252 # . restore registers -13253 59/pop-to-ecx -13254 # . epilogue -13255 89/<- %esp 5/r32/ebp -13256 5d/pop-to-ebp -13257 c3/return -13258 -13259 type-equal?: # a: (addr type-tree), b: (addr type-tree) -> result/eax: boolean -13260 # . prologue -13261 55/push-ebp -13262 89/<- %ebp 4/r32/esp -13263 # . save registers -13264 51/push-ecx -13265 52/push-edx -13266 53/push-ebx -13267 # ecx = a -13268 8b/-> *(ebp+8) 1/r32/ecx -13269 # edx = b -13270 8b/-> *(ebp+0xc) 2/r32/edx -13271 $type-equal?:compare-addr: -13272 # if (a == b) return true -13273 8b/-> %ecx 0/r32/eax # Var-type -13274 39/compare %edx 0/r32/eax # Var-type -13275 b8/copy-to-eax 1/imm32/true -13276 0f 84/jump-if-= $type-equal?:end/disp32 -13277 $type-equal?:compare-atom-state: -13278 # if (a->is-atom? != b->is-atom?) return false -13279 8b/-> *ecx 3/r32/ebx # Type-tree-is-atom -13280 39/compare *edx 3/r32/ebx # Type-tree-is-atom -13281 b8/copy-to-eax 0/imm32/false -13282 0f 85/jump-if-!= $type-equal?:end/disp32 -13283 # if a->is-atom? return (a->value == b->value) -13284 { -13285 $type-equal?:check-atom: -13286 81 7/subop/compare %ebx 0/imm32/false -13287 74/jump-if-= break/disp8 -13288 $type-equal?:is-atom: -13289 8b/-> *(ecx+4) 0/r32/eax # Type-tree-value -13290 39/compare *(edx+4) 0/r32/eax # Type-tree-value -13291 0f 94/set-if-= %al -13292 81 4/subop/and %eax 0xff/imm32 -13293 e9/jump $type-equal?:end/disp32 -13294 } -13295 $type-equal?:check-left: -13296 # if (!type-equal?(a->left, b->left)) return false -13297 (lookup *(ecx+4) *(ecx+8)) # Type-tree-left Type-tree-left => eax -13298 89/<- %ebx 0/r32/eax -13299 (lookup *(edx+4) *(edx+8)) # Type-tree-left Type-tree-left => eax -13300 (type-equal? %eax %ebx) # => eax -13301 3d/compare-eax-and 0/imm32/false -13302 74/jump-if-= $type-equal?:end/disp8 -13303 $type-equal?:check-right: -13304 # return type-equal?(a->right, b->right) -13305 (lookup *(ecx+0xc) *(ecx+0x10)) # Type-tree-right Type-tree-right => eax -13306 89/<- %ebx 0/r32/eax -13307 (lookup *(edx+0xc) *(edx+0x10)) # Type-tree-right Type-tree-right => eax -13308 (type-equal? %eax %ebx) # => eax -13309 $type-equal?:end: -13310 # . restore registers -13311 5b/pop-to-ebx -13312 5a/pop-to-edx -13313 59/pop-to-ecx -13314 # . epilogue -13315 89/<- %esp 5/r32/ebp -13316 5d/pop-to-ebp -13317 c3/return -13318 -13319 ####################################################### -13320 # Code-generation -13321 ####################################################### -13322 -13323 == data -13324 -13325 # Global state added to each var record when performing code-generation. -13326 Curr-local-stack-offset: # (addr int) -13327 0/imm32 -13328 -13329 == code -13330 -13331 emit-subx: # out: (addr buffered-file), err: (addr buffered-file), ed: (addr exit-descriptor) -13332 # . prologue -13333 55/push-ebp -13334 89/<- %ebp 4/r32/esp -13335 # . save registers -13336 50/push-eax -13337 # var curr/eax: (addr function) = *Program->functions -13338 (lookup *_Program-functions *_Program-functions->payload) # => eax -13339 { -13340 # if (curr == null) break -13341 3d/compare-eax-and 0/imm32 -13342 0f 84/jump-if-= break/disp32 -13343 (emit-subx-function *(ebp+8) %eax *(ebp+0xc) *(ebp+0x10)) -13344 # curr = lookup(curr->next) -13345 (lookup *(eax+0x20) *(eax+0x24)) # Function-next Function-next => eax -13346 e9/jump loop/disp32 -13347 } -13348 $emit-subx:end: -13349 # . restore registers -13350 58/pop-to-eax -13351 # . epilogue -13352 89/<- %esp 5/r32/ebp -13353 5d/pop-to-ebp -13354 c3/return -13355 -13356 emit-subx-function: # out: (addr buffered-file), f: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -13357 # . prologue -13358 55/push-ebp -13359 89/<- %ebp 4/r32/esp -13360 # some preprocessing -13361 (populate-mu-type-offsets-in-inouts *(ebp+0xc)) -13362 # . save registers -13363 50/push-eax -13364 51/push-ecx -13365 52/push-edx -13366 # initialize some global state -13367 c7 0/subop/copy *Curr-block-depth 1/imm32 # Important: keep this in sync with the parse phase -13368 c7 0/subop/copy *Curr-local-stack-offset 0/imm32 -13369 # ecx = f -13370 8b/-> *(ebp+0xc) 1/r32/ecx -13371 # var vars/edx: (stack (addr var) 256) -13372 81 5/subop/subtract %esp 0xc00/imm32 -13373 68/push 0xc00/imm32/size -13374 68/push 0/imm32/top -13375 89/<- %edx 4/r32/esp -13376 # var name/eax: (addr array byte) = lookup(f->name) -13377 (lookup *ecx *(ecx+4)) # Function-name Function-name => eax -13378 # -13379 (write-buffered *(ebp+8) %eax) -13380 (write-buffered *(ebp+8) ":\n") -13381 (emit-subx-prologue *(ebp+8)) -13382 # var body/eax: (addr block) = lookup(f->body) -13383 (lookup *(ecx+0x18) *(ecx+0x1c)) # Function-body Function-body => eax -13384 # -13385 (emit-subx-block *(ebp+8) %eax %edx *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -13386 (emit-subx-epilogue *(ebp+8)) -13387 # TODO: validate that *Curr-block-depth and *Curr-local-stack-offset have -13388 # been cleaned up -13389 $emit-subx-function:end: -13390 # . reclaim locals -13391 81 0/subop/add %esp 0xc08/imm32 -13392 # . restore registers -13393 5a/pop-to-edx -13394 59/pop-to-ecx -13395 58/pop-to-eax -13396 # . epilogue -13397 89/<- %esp 5/r32/ebp -13398 5d/pop-to-ebp -13399 c3/return -13400 -13401 populate-mu-type-offsets-in-inouts: # f: (addr function) -13402 # . prologue -13403 55/push-ebp -13404 89/<- %ebp 4/r32/esp -13405 # . save registers -13406 50/push-eax -13407 51/push-ecx -13408 52/push-edx -13409 53/push-ebx -13410 57/push-edi -13411 # var next-offset/edx: int = 8 -13412 ba/copy-to-edx 8/imm32 -13413 # var curr/ecx: (addr list var) = lookup(f->inouts) -13414 8b/-> *(ebp+8) 1/r32/ecx -13415 (lookup *(ecx+8) *(ecx+0xc)) # Function-inouts Function-inouts => eax -13416 89/<- %ecx 0/r32/eax -13417 { -13418 $populate-mu-type-offsets-in-inouts:loop: -13419 81 7/subop/compare %ecx 0/imm32 -13420 74/jump-if-= break/disp8 -13421 # var v/ebx: (addr var) = lookup(curr->value) -13422 (lookup *ecx *(ecx+4)) # List-value List-value => eax -13423 89/<- %ebx 0/r32/eax -13424 #? (lookup *ebx *(ebx+4)) -13425 #? (write-buffered Stderr "setting offset of fn inout ") -13426 #? (write-buffered Stderr %eax) -13427 #? (write-buffered Stderr "@") -13428 #? (write-int32-hex-buffered Stderr %ebx) -13429 #? (write-buffered Stderr " to ") -13430 #? (write-int32-hex-buffered Stderr %edx) -13431 #? (write-buffered Stderr Newline) -13432 #? (flush Stderr) -13433 # v->offset = next-offset -13434 89/<- *(ebx+0x14) 2/r32/edx # Var-offset -13435 # next-offset += size-of(v) -13436 (size-of %ebx) # => eax -13437 01/add-to %edx 0/r32/eax -13438 # curr = lookup(curr->next) -13439 (lookup *(ecx+8) *(ecx+0xc)) # List-next List-next => eax -13440 89/<- %ecx 0/r32/eax -13441 # -13442 eb/jump loop/disp8 -13443 } -13444 $populate-mu-type-offsets-in-inouts:end: -13445 # . restore registers -13446 5f/pop-to-edi -13447 5b/pop-to-ebx -13448 5a/pop-to-edx -13449 59/pop-to-ecx -13450 58/pop-to-eax -13451 # . epilogue -13452 89/<- %esp 5/r32/ebp -13453 5d/pop-to-ebp -13454 c3/return -13455 -13456 emit-subx-stmt-list: # out: (addr buffered-file), stmts: (addr list stmt), vars: (addr stack live-var), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -13457 # . prologue -13458 55/push-ebp -13459 89/<- %ebp 4/r32/esp -13460 # . save registers -13461 50/push-eax -13462 51/push-ecx -13463 53/push-ebx -13464 56/push-esi -13465 # esi = stmts -13466 8b/-> *(ebp+0xc) 6/r32/esi -13467 # -13468 { -13469 $emit-subx-stmt-list:loop: -13470 81 7/subop/compare %esi 0/imm32 -13471 0f 84/jump-if-= break/disp32 -13472 # var curr-stmt/ecx: (addr stmt) = lookup(stmts->value) -13473 (lookup *esi *(esi+4)) # List-value List-value => eax -13474 89/<- %ecx 0/r32/eax -13475 { -13476 $emit-subx-stmt-list:check-for-block: -13477 81 7/subop/compare *ecx 0/imm32/block # Stmt-tag -13478 75/jump-if-!= break/disp8 -13479 $emit-subx-stmt-list:block: -13480 (emit-subx-block *(ebp+8) %ecx *(ebp+0x10) *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c)) -13481 } -13482 { -13483 $emit-subx-stmt-list:check-for-stmt: -13484 81 7/subop/compare *ecx 1/imm32/stmt1 # Stmt-tag -13485 0f 85/jump-if-!= break/disp32 -13486 $emit-subx-stmt-list:stmt1: -13487 { -13488 (is-mu-branch? %ecx) # => eax -13489 3d/compare-eax-and 0/imm32/false -13490 0f 84/jump-if-= break/disp32 -13491 $emit-subx-stmt-list:branch-stmt: -13492 +-- 27 lines: # unconditional loops ----------------------------------------------------------------------------------------------------------------------------------------------------- -13519 +-- 16 lines: # unconditional breaks ---------------------------------------------------------------------------------------------------------------------------------------------------- -13535 +-- 38 lines: # simple conditional branches without a target ---------------------------------------------------------------------------------------------------------------------------- -13573 +-- 19 lines: # conditional branches with an explicit target ---------------------------------------------------------------------------------------------------------------------------- -13592 } -13593 $emit-subx-stmt-list:1-to-1: -13594 (emit-subx-stmt *(ebp+8) %ecx Primitives *(ebp+0x18) *(ebp+0x1c)) -13595 e9/jump $emit-subx-stmt-list:continue/disp32 -13596 } -13597 { -13598 $emit-subx-stmt-list:check-for-var-def: -13599 81 7/subop/compare *ecx 2/imm32/var-def # Stmt-tag -13600 75/jump-if-!= break/disp8 -13601 $emit-subx-stmt-list:var-def: -13602 (emit-subx-var-def *(ebp+8) %ecx) -13603 (push *(ebp+0x10) *(ecx+4)) # Vardef-var -13604 (push *(ebp+0x10) *(ecx+8)) # Vardef-var -13605 (push *(ebp+0x10) 0) # Live-var-register-spilled = 0 for vars on the stack -13606 # -13607 eb/jump $emit-subx-stmt-list:continue/disp8 -13608 } -13609 { -13610 $emit-subx-stmt-list:check-for-reg-var-def: -13611 81 7/subop/compare *ecx 3/imm32/reg-var-def # Stmt-tag -13612 0f 85/jump-if-!= break/disp32 -13613 $emit-subx-stmt-list:reg-var-def: -13614 # TODO: ensure that there's exactly one output -13615 (push-output-and-maybe-emit-spill *(ebp+8) %ecx *(ebp+0x10) %esi *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c)) -13616 # emit the instruction as usual -13617 (emit-subx-stmt *(ebp+8) %ecx Primitives *(ebp+0x18) *(ebp+0x1c)) -13618 # -13619 eb/jump $emit-subx-stmt-list:continue/disp8 -13620 } -13621 $emit-subx-stmt-list:continue: -13622 # TODO: raise an error on unrecognized Stmt-tag -13623 (lookup *(esi+8) *(esi+0xc)) # List-next List-next => eax -13624 89/<- %esi 0/r32/eax -13625 e9/jump loop/disp32 -13626 } -13627 $emit-subx-stmt-list:emit-cleanup: -13628 (emit-cleanup-code-until-depth *(ebp+8) *(ebp+0x10) *Curr-block-depth) -13629 $emit-subx-stmt-list:clean-up: -13630 (clean-up-blocks *(ebp+0x10) *Curr-block-depth *(ebp+0x14)) -13631 $emit-subx-stmt-list:end: -13632 # . restore registers -13633 5e/pop-to-esi -13634 5b/pop-to-ebx -13635 59/pop-to-ecx -13636 58/pop-to-eax -13637 # . epilogue -13638 89/<- %esp 5/r32/ebp -13639 5d/pop-to-ebp -13640 c3/return -13641 -13642 # 'later-stmts' includes 'stmt', but will behave the same even without it; reg-var-def stmts are guaranteed not to write to function outputs. -13643 push-output-and-maybe-emit-spill: # out: (addr buffered-file), stmt: (addr reg-var-def), vars: (addr stack (handle var)), later-stmts: (addr list stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -13644 # . prologue -13645 55/push-ebp -13646 89/<- %ebp 4/r32/esp -13647 # . save registers -13648 50/push-eax -13649 51/push-ecx -13650 52/push-edx -13651 # ecx = stmt -13652 8b/-> *(ebp+0xc) 1/r32/ecx -13653 # var sv/eax: (addr stmt-var) = lookup(curr-stmt->outputs) -13654 (lookup *(ecx+0x14) *(ecx+0x18)) # Regvardef-outputs Regvardef-outputs => eax -13655 # TODO: assert !sv->is-deref? -13656 # var v/ecx: (addr var) = lookup(sv->value) -13657 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -13658 89/<- %ecx 0/r32/eax -13659 # v->block-depth = *Curr-block-depth -13660 8b/-> *Curr-block-depth 0/r32/eax -13661 89/<- *(ecx+0x10) 0/r32/eax # Var-block-depth -13662 #? (write-buffered Stderr "var ") -13663 #? (lookup *ecx *(ecx+4)) -13664 #? (write-buffered Stderr %eax) -13665 #? (write-buffered Stderr " at depth ") -13666 #? (write-int32-hex-buffered Stderr *(ecx+0x10)) -13667 #? (write-buffered Stderr Newline) -13668 #? (flush Stderr) -13669 # ensure that v is in a register -13670 81 7/subop/compare *(ecx+0x18) 0/imm32 # Var-register -13671 0f 84/jump-if-= $push-output-and-maybe-emit-spill:abort/disp32 -13672 # var emit-spill?/edx: boolean = not-yet-spilled-this-block? && will-not-write-some-register?(fn) -13673 (not-yet-spilled-this-block? %ecx *(ebp+0x10)) # => eax -13674 89/<- %edx 0/r32/eax -13675 3d/compare-eax-and 0/imm32/false -13676 0f 84/jump-if-= $push-output-and-maybe-emit-spill:push/disp32 -13677 (will-not-write-some-register? %ecx *(ebp+0x14) *(ebp+0x18)) # => eax -13678 89/<- %edx 0/r32/eax -13679 # check emit-spill? -13680 3d/compare-eax-and 0/imm32/false -13681 0f 84/jump-if-= $push-output-and-maybe-emit-spill:push/disp32 -13682 # TODO: assert(size-of(output) == 4) -13683 # *Curr-local-stack-offset -= 4 -13684 81 5/subop/subtract *Curr-local-stack-offset 4/imm32 -13685 # emit spill -13686 (emit-indent *(ebp+8) *Curr-block-depth) -13687 (write-buffered *(ebp+8) "ff 6/subop/push %") -13688 (lookup *(ecx+0x18) *(ecx+0x1c)) # Var-register Var-register => eax -13689 (write-buffered *(ebp+8) %eax) -13690 (write-buffered *(ebp+8) Newline) -13691 $push-output-and-maybe-emit-spill:push: -13692 8b/-> *(ebp+0xc) 1/r32/ecx -13693 (lookup *(ecx+0x14) *(ecx+0x18)) # Regvardef-outputs Regvardef-outputs => eax -13694 # push(vars, {sv->value, emit-spill?}) -13695 (push *(ebp+0x10) *eax) # Stmt-var-value -13696 (push *(ebp+0x10) *(eax+4)) # Stmt-var-value -13697 (push *(ebp+0x10) %edx) -13698 $push-output-and-maybe-emit-spill:end: -13699 # . restore registers -13700 5a/pop-to-edx -13701 59/pop-to-ecx -13702 58/pop-to-eax -13703 # . epilogue -13704 89/<- %esp 5/r32/ebp -13705 5d/pop-to-ebp -13706 c3/return +12080 51/push-ecx +12081 # var out/ecx: (handle typeinfo) +12082 68/push 0/imm32 +12083 68/push 0/imm32 +12084 89/<- %ecx 4/r32/esp +12085 # eax = t +12086 8b/-> *(ebp+8) 0/r32/eax +12087 # if t is a literal, return 0 +12088 3d/compare-eax-and 0/imm32/literal +12089 0f 84/jump-if-= $compute-size-of-type-id:end/disp32 # eax changes type from type-id to int +12090 # if t is a byte, return 4 (because we don't really support non-multiples of 4) +12091 3d/compare-eax-and 8/imm32/byte +12092 { +12093 75/jump-if-!= break/disp8 +12094 b8/copy-to-eax 4/imm32 +12095 eb/jump $compute-size-of-type-id:end/disp8 +12096 } +12097 # if t is a handle, return 8 +12098 3d/compare-eax-and 4/imm32/handle +12099 { +12100 75/jump-if-!= break/disp8 +12101 b8/copy-to-eax 8/imm32 +12102 eb/jump $compute-size-of-type-id:end/disp8 # eax changes type from type-id to int +12103 } +12104 # if t is a slice, return 8 +12105 3d/compare-eax-and 0xc/imm32/slice +12106 { +12107 75/jump-if-!= break/disp8 +12108 b8/copy-to-eax 8/imm32 +12109 eb/jump $compute-size-of-type-id:end/disp8 # eax changes type from type-id to int +12110 } +12111 # if t is a user-defined type, compute its size +12112 # TODO: support non-atom type +12113 (find-typeinfo %eax %ecx) +12114 { +12115 81 7/subop/compare *ecx 0/imm32 +12116 74/jump-if-= break/disp8 +12117 $compute-size-of-type-id:user-defined: +12118 (lookup *ecx *(ecx+4)) # => eax +12119 (populate-mu-type-sizes-in-type %eax *(ebp+0xc) *(ebp+0x10)) +12120 8b/-> *(eax+0xc) 0/r32/eax # Typeinfo-total-size-in-bytes +12121 eb/jump $compute-size-of-type-id:end/disp8 +12122 } +12123 # otherwise return the word size +12124 b8/copy-to-eax 4/imm32 +12125 $compute-size-of-type-id:end: +12126 # . reclaim locals +12127 81 0/subop/add %esp 8/imm32 +12128 # . restore registers +12129 59/pop-to-ecx +12130 # . epilogue +12131 89/<- %esp 5/r32/ebp +12132 5d/pop-to-ebp +12133 c3/return +12134 +12135 # at this point we have total sizes for all user-defined types +12136 # compute offsets for each element +12137 # complication: fields may be out of order +12138 populate-mu-type-offsets: # in: (addr typeinfo), err: (addr buffered-file), ed: (addr exit-descriptor) +12139 # . prologue +12140 55/push-ebp +12141 89/<- %ebp 4/r32/esp +12142 # . save registers +12143 50/push-eax +12144 51/push-ecx +12145 52/push-edx +12146 53/push-ebx +12147 56/push-esi +12148 57/push-edi +12149 #? (dump-typeinfos "aaa\n") +12150 # var curr-offset/edi: int = 0 +12151 bf/copy-to-edi 0/imm32 +12152 # var table/ecx: (addr table string_key (handle typeinfo-entry)) = lookup(in->fields) +12153 8b/-> *(ebp+8) 1/r32/ecx +12154 (lookup *(ecx+4) *(ecx+8)) # Typeinfo-fields Typeinfo-fields => eax +12155 89/<- %ecx 0/r32/eax +12156 # var num-elems/edx: int = table->write / Typeinfo-fields-row-size +12157 8b/-> *ecx 2/r32/edx # stream-write +12158 c1 5/subop/shift-right-logical %edx 4/imm8 +12159 # var i/ebx: int = 0 +12160 bb/copy-to-ebx 0/imm32 +12161 { +12162 $populate-mu-type-offsets:loop: +12163 39/compare %ebx 2/r32/edx +12164 0f 8d/jump-if->= break/disp32 +12165 #? (write-buffered Stderr "looking up index ") +12166 #? (write-int32-hex-buffered Stderr %ebx) +12167 #? (write-buffered Stderr " in ") +12168 #? (write-int32-hex-buffered Stderr *(ebp+8)) +12169 #? (write-buffered Stderr Newline) +12170 #? (flush Stderr) +12171 # var v/esi: (addr typeinfo-entry) +12172 (locate-typeinfo-entry-with-index %ecx %ebx *(ebp+0xc) *(ebp+0x10)) # => eax +12173 89/<- %esi 0/r32/eax +12174 # if v is null, silently move on; we'll emit a nice error message while type-checking +12175 81 7/subop/compare %esi 0/imm32 # Typeinfo-entry-input-var +12176 74/jump-if-= $populate-mu-type-offsets:end/disp8 +12177 # if (v->input-var == 0) silently ignore v; we'll emit a nice error message while type-checking +12178 81 7/subop/compare *esi 0/imm32 # Typeinfo-entry-input-var +12179 74/jump-if-= $populate-mu-type-offsets:end/disp8 +12180 # v->output-var->offset = curr-offset +12181 # . eax: (addr var) +12182 (lookup *(esi+0xc) *(esi+0x10)) # Typeinfo-entry-output-var Typeinfo-entry-output-var => eax +12183 89/<- *(eax+0x14) 7/r32/edi # Var-offset +12184 # curr-offset += size-of(v->input-var) +12185 (lookup *esi *(esi+4)) # Typeinfo-entry-input-var Typeinfo-entry-input-var => eax +12186 (size-of %eax) # => eax +12187 01/add-to %edi 0/r32/eax +12188 # ++i +12189 43/increment-ebx +12190 e9/jump loop/disp32 +12191 } +12192 $populate-mu-type-offsets:end: +12193 # . restore registers +12194 5f/pop-to-edi +12195 5e/pop-to-esi +12196 5b/pop-to-ebx +12197 5a/pop-to-edx +12198 59/pop-to-ecx +12199 58/pop-to-eax +12200 # . epilogue +12201 89/<- %esp 5/r32/ebp +12202 5d/pop-to-ebp +12203 c3/return +12204 +12205 locate-typeinfo-entry-with-index: # table: (addr table (handle array byte) (handle typeinfo-entry)), idx: int, err: (addr buffered-file), ed: (addr exit-descriptor) -> result/eax: (addr typeinfo-entry) +12206 # . prologue +12207 55/push-ebp +12208 89/<- %ebp 4/r32/esp +12209 # . save registers +12210 51/push-ecx +12211 52/push-edx +12212 53/push-ebx +12213 56/push-esi +12214 57/push-edi +12215 # esi = table +12216 8b/-> *(ebp+8) 6/r32/esi +12217 # var curr/ecx: (addr row (handle array byte) (handle typeinfo-entry)) = table->data +12218 8d/copy-address *(esi+0xc) 1/r32/ecx +12219 # var max/edx: (addr byte) = &table->data[table->write] +12220 8b/-> *esi 2/r32/edx +12221 8d/copy-address *(ecx+edx) 2/r32/edx +12222 { +12223 $locate-typeinfo-entry-with-index:loop: +12224 39/compare %ecx 2/r32/edx +12225 73/jump-if-addr>= break/disp8 +12226 # var v/eax: (addr typeinfo-entry) +12227 (lookup *(ecx+8) *(ecx+0xc)) # => eax +12228 # if (v->index == idx) return v +12229 8b/-> *(eax+8) 3/r32/ebx # Typeinfo-entry-index +12230 #? (write-buffered Stderr "comparing ") +12231 #? (write-int32-hex-buffered Stderr %ebx) +12232 #? (write-buffered Stderr " and ") +12233 #? (write-int32-hex-buffered Stderr *(ebp+0xc)) +12234 #? (write-buffered Stderr Newline) +12235 #? (flush Stderr) +12236 39/compare *(ebp+0xc) 3/r32/ebx +12237 74/jump-if-= $locate-typeinfo-entry-with-index:end/disp8 +12238 # curr += Typeinfo-entry-size +12239 81 0/subop/add %ecx 0x10/imm32 # Typeinfo-entry-size +12240 # +12241 eb/jump loop/disp8 +12242 } +12243 # return 0 +12244 b8/copy-to-eax 0/imm32 +12245 $locate-typeinfo-entry-with-index:end: +12246 #? (write-buffered Stderr "returning ") +12247 #? (write-int32-hex-buffered Stderr %eax) +12248 #? (write-buffered Stderr Newline) +12249 #? (flush Stderr) +12250 # . restore registers +12251 5f/pop-to-edi +12252 5e/pop-to-esi +12253 5b/pop-to-ebx +12254 5a/pop-to-edx +12255 59/pop-to-ecx +12256 # . epilogue +12257 89/<- %esp 5/r32/ebp +12258 5d/pop-to-ebp +12259 c3/return +12260 +12261 dump-typeinfos: # hdr: (addr array byte) +12262 # . prologue +12263 55/push-ebp +12264 89/<- %ebp 4/r32/esp +12265 # . save registers +12266 50/push-eax +12267 # +12268 (write-buffered Stderr *(ebp+8)) +12269 (flush Stderr) +12270 # var curr/eax: (addr typeinfo) = lookup(Program->types) +12271 (lookup *_Program-types *_Program-types->payload) # => eax +12272 { +12273 # if (curr == null) break +12274 3d/compare-eax-and 0/imm32 +12275 74/jump-if-= break/disp8 +12276 (write-buffered Stderr "---\n") +12277 (flush Stderr) +12278 (dump-typeinfo %eax) +12279 # curr = lookup(curr->next) +12280 (lookup *(eax+0x10) *(eax+0x14)) # Typeinfo-next Typeinfo-next => eax +12281 eb/jump loop/disp8 +12282 } +12283 $dump-typeinfos:end: +12284 # . restore registers +12285 58/pop-to-eax +12286 # . epilogue +12287 89/<- %esp 5/r32/ebp +12288 5d/pop-to-ebp +12289 c3/return +12290 +12291 dump-typeinfo: # in: (addr typeinfo) +12292 # . prologue +12293 55/push-ebp +12294 89/<- %ebp 4/r32/esp +12295 # . save registers +12296 50/push-eax +12297 51/push-ecx +12298 52/push-edx +12299 53/push-ebx +12300 56/push-esi +12301 57/push-edi +12302 # esi = in +12303 8b/-> *(ebp+8) 6/r32/esi +12304 # var table/ecx: (addr table (handle array byte) (handle typeinfo-entry)) = lookup(T->fields) +12305 (lookup *(esi+4) *(esi+8)) # Typeinfo-fields Typeinfo-fields => eax +12306 89/<- %ecx 0/r32/eax +12307 (write-buffered Stderr "id:") +12308 (write-int32-hex-buffered Stderr *esi) +12309 (write-buffered Stderr "\n") +12310 (write-buffered Stderr "fields @ ") +12311 (write-int32-hex-buffered Stderr %ecx) +12312 (write-buffered Stderr Newline) +12313 (flush Stderr) +12314 (write-buffered Stderr " write: ") +12315 (write-int32-hex-buffered Stderr *ecx) +12316 (write-buffered Stderr Newline) +12317 (flush Stderr) +12318 (write-buffered Stderr " read: ") +12319 (write-int32-hex-buffered Stderr *(ecx+4)) +12320 (write-buffered Stderr Newline) +12321 (flush Stderr) +12322 (write-buffered Stderr " size: ") +12323 (write-int32-hex-buffered Stderr *(ecx+8)) +12324 (write-buffered Stderr Newline) +12325 (flush Stderr) +12326 # var table-size/edx: int = table->write +12327 8b/-> *ecx 2/r32/edx # stream-write +12328 # var curr/ecx: (addr table_row) = table->data +12329 8d/copy-address *(ecx+0xc) 1/r32/ecx +12330 # var max/edx: (addr table_row) = table->data + table->write +12331 8d/copy-address *(ecx+edx) 2/r32/edx +12332 { +12333 $dump-typeinfo:loop: +12334 # if (curr >= max) break +12335 39/compare %ecx 2/r32/edx +12336 0f 83/jump-if-addr>= break/disp32 +12337 (write-buffered Stderr " row:\n") +12338 (write-buffered Stderr " key: ") +12339 (write-int32-hex-buffered Stderr *ecx) +12340 (write-buffered Stderr ",") +12341 (write-int32-hex-buffered Stderr *(ecx+4)) +12342 (write-buffered Stderr " = '") +12343 (lookup *ecx *(ecx+4)) +12344 (write-buffered Stderr %eax) +12345 (write-buffered Stderr "' @ ") +12346 (write-int32-hex-buffered Stderr %eax) +12347 (write-buffered Stderr Newline) +12348 (flush Stderr) +12349 (write-buffered Stderr " value: ") +12350 (write-int32-hex-buffered Stderr *(ecx+8)) +12351 (write-buffered Stderr ",") +12352 (write-int32-hex-buffered Stderr *(ecx+0xc)) +12353 (write-buffered Stderr " = typeinfo-entry@") +12354 (lookup *(ecx+8) *(ecx+0xc)) +12355 (write-int32-hex-buffered Stderr %eax) +12356 (write-buffered Stderr Newline) +12357 (flush Stderr) +12358 (write-buffered Stderr " input var@") +12359 (dump-var 5 %eax) +12360 (lookup *(ecx+8) *(ecx+0xc)) +12361 (write-buffered Stderr " index: ") +12362 (write-int32-hex-buffered Stderr *(eax+8)) +12363 (write-buffered Stderr Newline) +12364 (flush Stderr) +12365 (write-buffered Stderr " output var@") +12366 8d/copy-address *(eax+0xc) 0/r32/eax # Typeinfo-entry-output-var +12367 (dump-var 5 %eax) +12368 (flush Stderr) +12369 # curr += row-size +12370 81 0/subop/add %ecx 0x10/imm32 # Typeinfo-fields-row-size +12371 # +12372 e9/jump loop/disp32 +12373 } +12374 $dump-typeinfo:end: +12375 # . restore registers +12376 5f/pop-to-edi +12377 5e/pop-to-esi +12378 5b/pop-to-ebx +12379 5a/pop-to-edx +12380 59/pop-to-ecx +12381 58/pop-to-eax +12382 # . epilogue +12383 89/<- %esp 5/r32/ebp +12384 5d/pop-to-ebp +12385 c3/return +12386 +12387 dump-var: # indent: int, v: (addr handle var) +12388 # . prologue +12389 55/push-ebp +12390 89/<- %ebp 4/r32/esp +12391 # . save registers +12392 50/push-eax +12393 53/push-ebx +12394 # eax = v +12395 8b/-> *(ebp+0xc) 0/r32/eax +12396 # +12397 (write-int32-hex-buffered Stderr *eax) +12398 (write-buffered Stderr ",") +12399 (write-int32-hex-buffered Stderr *(eax+4)) +12400 (write-buffered Stderr "->") +12401 (lookup *eax *(eax+4)) +12402 (write-int32-hex-buffered Stderr %eax) +12403 (write-buffered Stderr Newline) +12404 (flush Stderr) +12405 { +12406 3d/compare-eax-and 0/imm32 +12407 0f 84/jump-if-= break/disp32 +12408 (emit-indent Stderr *(ebp+8)) +12409 (write-buffered Stderr "name: ") +12410 89/<- %ebx 0/r32/eax +12411 (write-int32-hex-buffered Stderr *ebx) # Var-name +12412 (write-buffered Stderr ",") +12413 (write-int32-hex-buffered Stderr *(ebx+4)) # Var-name +12414 (write-buffered Stderr "->") +12415 (lookup *ebx *(ebx+4)) # Var-name +12416 (write-int32-hex-buffered Stderr %eax) +12417 { +12418 3d/compare-eax-and 0/imm32 +12419 74/jump-if-= break/disp8 +12420 (write-buffered Stderr Space) +12421 (write-buffered Stderr %eax) +12422 } +12423 (write-buffered Stderr Newline) +12424 (flush Stderr) +12425 (emit-indent Stderr *(ebp+8)) +12426 (write-buffered Stderr "block depth: ") +12427 (write-int32-hex-buffered Stderr *(ebx+0x10)) # Var-block-depth +12428 (write-buffered Stderr Newline) +12429 (flush Stderr) +12430 (emit-indent Stderr *(ebp+8)) +12431 (write-buffered Stderr "stack offset: ") +12432 (write-int32-hex-buffered Stderr *(ebx+0x14)) # Var-offset +12433 (write-buffered Stderr Newline) +12434 (flush Stderr) +12435 (emit-indent Stderr *(ebp+8)) +12436 (write-buffered Stderr "reg: ") +12437 (write-int32-hex-buffered Stderr *(ebx+0x18)) # Var-register +12438 (write-buffered Stderr ",") +12439 (write-int32-hex-buffered Stderr *(ebx+0x1c)) # Var-register +12440 (write-buffered Stderr "->") +12441 (flush Stderr) +12442 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register +12443 (write-int32-hex-buffered Stderr %eax) +12444 { +12445 3d/compare-eax-and 0/imm32 +12446 74/jump-if-= break/disp8 +12447 (write-buffered Stderr Space) +12448 (write-buffered Stderr %eax) +12449 } +12450 (write-buffered Stderr Newline) +12451 (flush Stderr) +12452 } +12453 $dump-var:end: +12454 # . restore registers +12455 5b/pop-to-ebx +12456 58/pop-to-eax +12457 # . epilogue +12458 89/<- %esp 5/r32/ebp +12459 5d/pop-to-ebp +12460 c3/return +12461 +12462 ####################################################### +12463 # Type-checking +12464 ####################################################### +12465 +12466 check-mu-types: # err: (addr buffered-file), ed: (addr exit-descriptor) +12467 # . prologue +12468 55/push-ebp +12469 89/<- %ebp 4/r32/esp +12470 # . save registers +12471 50/push-eax +12472 # var curr/eax: (addr function) = lookup(Program->functions) +12473 (lookup *_Program-functions *_Program-functions->payload) # => eax +12474 { +12475 $check-mu-types:loop: +12476 # if (curr == null) break +12477 3d/compare-eax-and 0/imm32 +12478 0f 84/jump-if-= break/disp32 +12479 +-- 8 lines: #? # dump curr->name ------------------------------------------------------------------------------------------------------------------------------------------------ +12487 (check-mu-function %eax *(ebp+8) *(ebp+0xc)) +12488 # curr = lookup(curr->next) +12489 (lookup *(eax+0x20) *(eax+0x24)) # Function-next Function-next => eax +12490 e9/jump loop/disp32 +12491 } +12492 $check-mu-types:end: +12493 # . restore registers +12494 58/pop-to-eax +12495 # . epilogue +12496 89/<- %esp 5/r32/ebp +12497 5d/pop-to-ebp +12498 c3/return +12499 +12500 check-mu-function: # fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +12501 # . prologue +12502 55/push-ebp +12503 89/<- %ebp 4/r32/esp +12504 # . save registers +12505 50/push-eax +12506 # eax = f +12507 8b/-> *(ebp+8) 0/r32/eax +12508 # TODO: anything to check in header? +12509 # var body/eax: (addr block) = lookup(f->body) +12510 (lookup *(eax+0x18) *(eax+0x1c)) # Function-body Function-body => eax +12511 (check-mu-block %eax *(ebp+8) *(ebp+0xc) *(ebp+0x10)) +12512 $check-mu-function:end: +12513 # . restore registers +12514 58/pop-to-eax +12515 # . epilogue +12516 89/<- %esp 5/r32/ebp +12517 5d/pop-to-ebp +12518 c3/return +12519 +12520 check-mu-block: # block: (addr block), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +12521 # . prologue +12522 55/push-ebp +12523 89/<- %ebp 4/r32/esp +12524 # . save registers +12525 50/push-eax +12526 # eax = block +12527 8b/-> *(ebp+8) 0/r32/eax +12528 # var stmts/eax: (addr list stmt) = lookup(block->statements) +12529 (lookup *(eax+4) *(eax+8)) # Block-stmts Block-stmts => eax +12530 # +12531 { +12532 $check-mu-block:check-empty: +12533 3d/compare-eax-and 0/imm32 +12534 0f 84/jump-if-= break/disp32 +12535 # emit block->statements +12536 (check-mu-stmt-list %eax *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +12537 } +12538 $check-mu-block:end: +12539 # . restore registers +12540 58/pop-to-eax +12541 # . epilogue +12542 89/<- %esp 5/r32/ebp +12543 5d/pop-to-ebp +12544 c3/return +12545 +12546 check-mu-stmt-list: # stmts: (addr list stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +12547 # . prologue +12548 55/push-ebp +12549 89/<- %ebp 4/r32/esp +12550 # . save registers +12551 50/push-eax +12552 56/push-esi +12553 # esi = stmts +12554 8b/-> *(ebp+8) 6/r32/esi +12555 { +12556 $check-mu-stmt-list:loop: +12557 81 7/subop/compare %esi 0/imm32 +12558 0f 84/jump-if-= break/disp32 +12559 # var curr-stmt/eax: (addr stmt) = lookup(stmts->value) +12560 (lookup *esi *(esi+4)) # List-value List-value => eax +12561 { +12562 $check-mu-stmt-list:check-for-block: +12563 81 7/subop/compare *eax 0/imm32/block # Stmt-tag +12564 75/jump-if-!= break/disp8 +12565 $check-mu-stmt-list:block: +12566 (check-mu-block %eax *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +12567 eb/jump $check-mu-stmt-list:continue/disp8 +12568 } +12569 { +12570 $check-mu-stmt-list:check-for-stmt1: +12571 81 7/subop/compare *eax 1/imm32/stmt1 # Stmt-tag +12572 0f 85/jump-if-!= break/disp32 +12573 $check-mu-stmt-list:stmt1: +12574 (check-mu-stmt %eax *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +12575 eb/jump $check-mu-stmt-list:continue/disp8 +12576 } +12577 { +12578 $check-mu-stmt-list:check-for-reg-var-def: +12579 81 7/subop/compare *eax 3/imm32/reg-var-def # Stmt-tag +12580 0f 85/jump-if-!= break/disp32 +12581 $check-mu-stmt-list:reg-var-def: +12582 (check-mu-stmt %eax *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +12583 eb/jump $check-mu-stmt-list:continue/disp8 +12584 } +12585 $check-mu-stmt-list:continue: +12586 # TODO: raise an error on unrecognized Stmt-tag +12587 (lookup *(esi+8) *(esi+0xc)) # List-next List-next => eax +12588 89/<- %esi 0/r32/eax +12589 e9/jump loop/disp32 +12590 } +12591 $check-mu-stmt-list:end: +12592 # . restore registers +12593 5e/pop-to-esi +12594 58/pop-to-eax +12595 # . epilogue +12596 89/<- %esp 5/r32/ebp +12597 5d/pop-to-ebp +12598 c3/return +12599 +12600 check-mu-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +12601 # . prologue +12602 55/push-ebp +12603 89/<- %ebp 4/r32/esp +12604 # . save registers +12605 50/push-eax +12606 # - if stmt's operation matches a primitive, check against it +12607 (has-primitive-name? *(ebp+8)) # => eax +12608 3d/compare-eax-and 0/imm32/false +12609 { +12610 74/jump-if-= break/disp8 +12611 (check-mu-primitive *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +12612 e9/jump $check-mu-stmt:end/disp32 +12613 } +12614 # - otherwise find a function to check against +12615 # var f/eax: (addr function) = lookup(*Program->functions) +12616 (lookup *_Program-functions *_Program-functions->payload) # => eax +12617 (find-matching-function %eax *(ebp+8)) # => eax +12618 3d/compare-eax-and 0/imm32 +12619 { +12620 74/jump-if-= break/disp8 +12621 (check-mu-call *(ebp+8) %eax *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +12622 eb/jump $check-mu-stmt:end/disp8 +12623 } +12624 # var f/eax: (addr function) = lookup(*Program->signatures) +12625 (lookup *_Program-signatures *_Program-signatures->payload) # => eax +12626 (find-matching-function %eax *(ebp+8)) # => eax +12627 3d/compare-eax-and 0/imm32 +12628 { +12629 74/jump-if-= break/disp8 +12630 (check-mu-call *(ebp+8) %eax *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +12631 eb/jump $check-mu-stmt:end/disp8 +12632 } +12633 # - otherwise abort +12634 e9/jump $check-mu-stmt:unknown-call/disp32 +12635 $check-mu-stmt:end: +12636 # . restore registers +12637 58/pop-to-eax +12638 # . epilogue +12639 89/<- %esp 5/r32/ebp +12640 5d/pop-to-ebp +12641 c3/return +12642 +12643 $check-mu-stmt:unknown-call: +12644 (write-buffered *(ebp+0x10) "unknown function '") +12645 8b/-> *(ebp+8) 0/r32/eax +12646 (lookup *(eax+4) *(eax+8)) # Stmt1-operation Stmt1-operation => eax +12647 (write-buffered *(ebp+0x10) %eax) +12648 (write-buffered *(ebp+0x10) "'\n") +12649 (flush *(ebp+0x10)) +12650 (stop *(ebp+0x14) 1) +12651 # never gets here +12652 +12653 has-primitive-name?: # stmt: (addr stmt) -> result/eax: boolean +12654 # . prologue +12655 55/push-ebp +12656 89/<- %ebp 4/r32/esp +12657 # . save registers +12658 51/push-ecx +12659 56/push-esi +12660 # var name/esi: (addr array byte) = lookup(stmt->operation) +12661 8b/-> *(ebp+8) 6/r32/esi +12662 (lookup *(esi+4) *(esi+8)) # Stmt1-operation Stmt1-operation => eax +12663 89/<- %esi 0/r32/eax +12664 # if (name == "get") return true +12665 (string-equal? %esi "get") # => eax +12666 3d/compare-eax-and 0/imm32/false +12667 0f 85/jump-if-!= $has-primitive-name?:end/disp32 +12668 # if (name == "index") return true +12669 (string-equal? %esi "index") # => eax +12670 3d/compare-eax-and 0/imm32/false +12671 0f 85/jump-if-!= $has-primitive-name?:end/disp32 +12672 # if (name == "length") return true +12673 (string-equal? %esi "length") # => eax +12674 3d/compare-eax-and 0/imm32/false +12675 0f 85/jump-if-!= $has-primitive-name?:end/disp32 +12676 # if (name == "compute-offset") return true +12677 (string-equal? %esi "compute-offset") # => eax +12678 3d/compare-eax-and 0/imm32/false +12679 0f 85/jump-if-!= $has-primitive-name?:end/disp32 +12680 # if (name == "allocate") return true +12681 (string-equal? %esi "allocate") # => eax +12682 3d/compare-eax-and 0/imm32/false +12683 0f 85/jump-if-!= $has-primitive-name?:end/disp32 +12684 # if (name == "populate") return true +12685 (string-equal? %esi "populate") # => eax +12686 3d/compare-eax-and 0/imm32/false +12687 0f 85/jump-if-!= $has-primitive-name?:end/disp32 +12688 # if (name == "populate-stream") return true +12689 (string-equal? %esi "populate-stream") # => eax +12690 3d/compare-eax-and 0/imm32/false +12691 0f 85/jump-if-!= $has-primitive-name?:end/disp32 +12692 # if (name == "read-from-stream") return true +12693 (string-equal? %esi "read-from-stream") # => eax +12694 3d/compare-eax-and 0/imm32/false +12695 0f 85/jump-if-!= $has-primitive-name?:end/disp32 +12696 # if (name == "write-to-stream") return true +12697 (string-equal? %esi "write-to-stream") # => eax +12698 3d/compare-eax-and 0/imm32/false +12699 0f 85/jump-if-!= $has-primitive-name?:end/disp32 +12700 # var curr/ecx: (addr primitive) = Primitives +12701 b9/copy-to-ecx Primitives/imm32 +12702 { +12703 $has-primitive-name?:loop: +12704 # if (curr == null) break +12705 81 7/subop/compare %ecx 0/imm32 +12706 74/jump-if-= break/disp8 +12707 # if (primitive->name == name) return true +12708 (lookup *ecx *(ecx+4)) # Primitive-name Primitive-name => eax +12709 (string-equal? %esi %eax) # => eax +12710 3d/compare-eax-and 0/imm32/false +12711 75/jump-if-!= $has-primitive-name?:end/disp8 +12712 $has-primitive-name?:next-primitive: +12713 # curr = curr->next +12714 (lookup *(ecx+0x38) *(ecx+0x3c)) # Primitive-next Primitive-next => eax +12715 89/<- %ecx 0/r32/eax +12716 # +12717 e9/jump loop/disp32 +12718 } +12719 # return null +12720 b8/copy-to-eax 0/imm32 +12721 $has-primitive-name?:end: +12722 # . restore registers +12723 5e/pop-to-esi +12724 59/pop-to-ecx +12725 # . epilogue +12726 89/<- %esp 5/r32/ebp +12727 5d/pop-to-ebp +12728 c3/return +12729 +12730 check-mu-primitive: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +12731 # . prologue +12732 55/push-ebp +12733 89/<- %ebp 4/r32/esp +12734 # . save registers +12735 50/push-eax +12736 51/push-ecx +12737 # var op/ecx: (addr array byte) = lookup(stmt->operation) +12738 8b/-> *(ebp+8) 0/r32/eax +12739 (lookup *(eax+4) *(eax+8)) # Stmt1-operation Stmt1-operation => eax +12740 89/<- %ecx 0/r32/eax +12741 # if (op == "copy") check-mu-copy-stmt +12742 { +12743 (string-equal? %ecx "copy") # => eax +12744 3d/compare-eax-and 0/imm32/false +12745 74/jump-if-= break/disp8 +12746 (check-mu-copy-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +12747 e9/jump $check-mu-primitive:end/disp32 +12748 } +12749 # if (op == "copy-to") check-mu-copy-to-stmt +12750 { +12751 (string-equal? %ecx "copy-to") # => eax +12752 3d/compare-eax-and 0/imm32/false +12753 74/jump-if-= break/disp8 +12754 (check-mu-copy-to-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +12755 e9/jump $check-mu-primitive:end/disp32 +12756 } +12757 # if (op == "compare") check-mu-compare-stmt +12758 { +12759 (string-equal? %ecx "compare") # => eax +12760 3d/compare-eax-and 0/imm32/false +12761 74/jump-if-= break/disp8 +12762 (check-mu-compare-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +12763 e9/jump $check-mu-primitive:end/disp32 +12764 } +12765 # if (op == "address") check-mu-address-stmt +12766 { +12767 (string-equal? %ecx "address") # => eax +12768 3d/compare-eax-and 0/imm32/false +12769 74/jump-if-= break/disp8 +12770 (check-mu-address-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +12771 e9/jump $check-mu-primitive:end/disp32 +12772 } +12773 # if (op == "get") check-mu-get-stmt +12774 { +12775 (string-equal? %ecx "get") # => eax +12776 3d/compare-eax-and 0/imm32/false +12777 74/jump-if-= break/disp8 +12778 (check-mu-get-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +12779 e9/jump $check-mu-primitive:end/disp32 +12780 } +12781 # if (op == "index") check-mu-index-stmt +12782 { +12783 (string-equal? %ecx "index") # => eax +12784 3d/compare-eax-and 0/imm32/false +12785 74/jump-if-= break/disp8 +12786 (check-mu-index-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +12787 e9/jump $check-mu-primitive:end/disp32 +12788 } +12789 # if (op == "length") check-mu-length-stmt +12790 { +12791 (string-equal? %ecx "length") # => eax +12792 3d/compare-eax-and 0/imm32/false +12793 74/jump-if-= break/disp8 +12794 (check-mu-length-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +12795 e9/jump $check-mu-primitive:end/disp32 +12796 } +12797 # if (op == "compute-offset") check-mu-compute-offset-stmt +12798 { +12799 (string-equal? %ecx "compute-offset") # => eax +12800 3d/compare-eax-and 0/imm32/false +12801 74/jump-if-= break/disp8 +12802 (check-mu-compute-offset-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +12803 e9/jump $check-mu-primitive:end/disp32 +12804 } +12805 # if (op == "allocate") check-mu-allocate-stmt +12806 { +12807 (string-equal? %ecx "allocate") # => eax +12808 3d/compare-eax-and 0/imm32/false +12809 74/jump-if-= break/disp8 +12810 (check-mu-allocate-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +12811 e9/jump $check-mu-primitive:end/disp32 +12812 } +12813 # if (op == "populate") check-mu-populate-stmt +12814 { +12815 (string-equal? %ecx "populate") # => eax +12816 3d/compare-eax-and 0/imm32/false +12817 74/jump-if-= break/disp8 +12818 (check-mu-populate-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +12819 e9/jump $check-mu-primitive:end/disp32 +12820 } +12821 # if (op == "populate-stream") check-mu-populate-stream-stmt +12822 { +12823 (string-equal? %ecx "populate-stream") # => eax +12824 3d/compare-eax-and 0/imm32/false +12825 74/jump-if-= break/disp8 +12826 (check-mu-populate-stream-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +12827 e9/jump $check-mu-primitive:end/disp32 +12828 } +12829 # if (op == "read-from-stream") check-mu-read-from-stream-stmt +12830 { +12831 (string-equal? %ecx "read-from-stream") # => eax +12832 3d/compare-eax-and 0/imm32/false +12833 74/jump-if-= break/disp8 +12834 (check-mu-read-from-stream-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +12835 e9/jump $check-mu-primitive:end/disp32 +12836 } +12837 # if (op == "write-to-stream") check-mu-write-to-stream-stmt +12838 { +12839 (string-equal? %ecx "write-to-stream") # => eax +12840 3d/compare-eax-and 0/imm32/false +12841 74/jump-if-= break/disp8 +12842 (check-mu-write-to-stream-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +12843 e9/jump $check-mu-primitive:end/disp32 +12844 } +12845 # otherwise check-numberlike-stmt +12846 (check-mu-numberlike-primitive *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +12847 $check-mu-primitive:end: +12848 # . restore registers +12849 59/pop-to-ecx +12850 58/pop-to-eax +12851 # . epilogue +12852 89/<- %esp 5/r32/ebp +12853 5d/pop-to-ebp +12854 c3/return +12855 +12856 # by default, Mu primitives should only operate on 'number-like' types +12857 check-mu-numberlike-primitive: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +12858 # . prologue +12859 55/push-ebp +12860 89/<- %ebp 4/r32/esp +12861 # . save registers +12862 50/push-eax +12863 51/push-ecx +12864 56/push-esi +12865 # esi = stmt +12866 8b/-> *(ebp+8) 6/r32/esi +12867 # var gas/ecx: int = 2 +12868 b9/copy-to-ecx 2/imm32 +12869 # - check at most 1 output +12870 # var output/eax: (addr stmt-var) = stmt->outputs +12871 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax +12872 { +12873 3d/compare-eax-and 0/imm32 +12874 74/jump-if-= break/disp8 +12875 $check-mu-numberlike-primitive:output: +12876 (check-mu-numberlike-output %eax *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +12877 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax +12878 3d/compare-eax-and 0/imm32 +12879 0f 85/jump-if-!= $check-mu-numberlike-primitive:error-too-many-outputs/disp32 +12880 # check output is in a register +12881 # --gas +12882 49/decrement-ecx +12883 } +12884 # - check first inout +12885 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax +12886 { +12887 3d/compare-eax-and 0/imm32 +12888 0f 84/jump-if-= $check-mu-numberlike-primitive:end/disp32 +12889 $check-mu-numberlike-primitive:first-inout: +12890 (check-mu-numberlike-arg %eax *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +12891 # --gas +12892 49/decrement-ecx +12893 } +12894 # - check second inout +12895 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax +12896 { +12897 3d/compare-eax-and 0/imm32 +12898 74/jump-if-= $check-mu-numberlike-primitive:end/disp8 +12899 $check-mu-numberlike-primitive:second-inout: +12900 # is a second inout allowed? +12901 81 7/subop/compare %ecx 0/imm32 +12902 0f 84/jump-if-= $check-mu-numberlike-primitive:error-too-many-inouts/disp32 +12903 $check-mu-numberlike-primitive:second-inout-permitted: +12904 (check-mu-numberlike-arg %eax *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +12905 } +12906 $check-mu-numberlike-primitive:third-inout: +12907 # if there's a third arg, raise an error +12908 81 7/subop/compare *(eax+8) 0/imm32 # Stmt-var-next +12909 0f 85/jump-if-!= $check-mu-numberlike-primitive:error-too-many-inouts/disp32 +12910 $check-mu-numberlike-primitive:end: +12911 # . restore registers +12912 5e/pop-to-esi +12913 59/pop-to-ecx +12914 58/pop-to-eax +12915 # . epilogue +12916 89/<- %esp 5/r32/ebp +12917 5d/pop-to-ebp +12918 c3/return +12919 +12920 $check-mu-numberlike-primitive:error-too-many-inouts: +12921 (write-buffered *(ebp+0x10) "fn ") +12922 8b/-> *(ebp+0xc) 0/r32/eax +12923 (lookup *eax *(eax+4)) # Function-name Function-name => eax +12924 (write-buffered *(ebp+0x10) %eax) +12925 (write-buffered *(ebp+0x10) ": stmt ") +12926 (lookup *(esi+4) *(esi+8)) # Stmt1-operation Stmt1-operation => eax +12927 (write-buffered *(ebp+0x10) %eax) +12928 (write-buffered *(ebp+0x10) ": too many inouts; most primitives support at most two arguments, across inouts and outputs\n") +12929 (flush *(ebp+0x10)) +12930 (stop *(ebp+0x14) 1) +12931 # never gets here +12932 +12933 $check-mu-numberlike-primitive:error-too-many-outputs: +12934 (write-buffered *(ebp+0x10) "fn ") +12935 8b/-> *(ebp+0xc) 0/r32/eax +12936 (lookup *eax *(eax+4)) # Function-name Function-name => eax +12937 (write-buffered *(ebp+0x10) %eax) +12938 (write-buffered *(ebp+0x10) ": stmt ") +12939 (lookup *(esi+4) *(esi+8)) # Stmt1-operation Stmt1-operation => eax +12940 (write-buffered *(ebp+0x10) %eax) +12941 (write-buffered *(ebp+0x10) ": too many outputs; most primitives support at most one output\n") +12942 (flush *(ebp+0x10)) +12943 (stop *(ebp+0x14) 1) +12944 # never gets here +12945 +12946 check-mu-numberlike-arg: # v: (addr stmt-var), stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +12947 # . prologue +12948 55/push-ebp +12949 89/<- %ebp 4/r32/esp +12950 # . save registers +12951 50/push-eax +12952 56/push-esi +12953 # var t/esi: (addr type-tree) = lookup(v->value->type) +12954 8b/-> *(ebp+8) 0/r32/eax +12955 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +12956 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +12957 89/<- %esi 0/r32/eax +12958 $check-mu-numberlike-arg:check-literal: +12959 # if t is an int, return +12960 (is-simple-mu-type? %esi 0) # literal => eax +12961 3d/compare-eax-and 0/imm32/false +12962 75/jump-if-!= $check-mu-numberlike-arg:end/disp8 +12963 $check-mu-numberlike-arg:check-addr: +12964 # if t is an addr and v is dereferenced, return +12965 { +12966 (is-mu-addr-type? %esi) # => eax +12967 3d/compare-eax-and 0/imm32/false +12968 74/jump-if-= break/disp8 +12969 8b/-> *(ebp+8) 0/r32/eax +12970 8b/-> *(eax+0x10) 0/r32/eax +12971 3d/compare-eax-and 0/imm32/false +12972 75/jump-if-!= $check-mu-numberlike-arg:end/disp8 +12973 } +12974 $check-mu-numberlike-arg:output-checks: +12975 (check-mu-numberlike-output *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14) *(ebp+0x18)) +12976 $check-mu-numberlike-arg:end: +12977 # . restore registers +12978 5e/pop-to-esi +12979 58/pop-to-eax +12980 # . epilogue +12981 89/<- %esp 5/r32/ebp +12982 5d/pop-to-ebp +12983 c3/return +12984 +12985 check-mu-numberlike-output: # v: (addr stmt-var), stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +12986 # . prologue +12987 55/push-ebp +12988 89/<- %ebp 4/r32/esp +12989 # . save registers +12990 50/push-eax +12991 56/push-esi +12992 # var t/esi: (addr type-tree) = lookup(v->value->type) +12993 8b/-> *(ebp+8) 0/r32/eax +12994 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +12995 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +12996 89/<- %esi 0/r32/eax +12997 $check-mu-numberlike-output:check-int: +12998 # if t is an int, return +12999 (is-simple-mu-type? %esi 1) # int => eax +13000 3d/compare-eax-and 0/imm32/false +13001 75/jump-if-!= $check-mu-numberlike-output:end/disp8 +13002 $check-mu-numberlike-output:check-boolean: +13003 # if t is a boolean, return +13004 (is-simple-mu-type? %esi 5) # boolean => eax +13005 3d/compare-eax-and 0/imm32/false +13006 75/jump-if-!= $check-mu-numberlike-output:end/disp8 +13007 $check-mu-numberlike-output:check-byte: +13008 # if t is a byte, return +13009 (is-simple-mu-type? %esi 8) # byte => eax +13010 3d/compare-eax-and 0/imm32/false +13011 75/jump-if-!= $check-mu-numberlike-output:end/disp8 +13012 e9/jump $check-mu-numberlike-output:fail/disp32 +13013 $check-mu-numberlike-output:end: +13014 # . restore registers +13015 5e/pop-to-esi +13016 58/pop-to-eax +13017 # . epilogue +13018 89/<- %esp 5/r32/ebp +13019 5d/pop-to-ebp +13020 c3/return +13021 +13022 $check-mu-numberlike-output:fail: +13023 # otherwise raise an error +13024 (write-buffered *(ebp+0x14) "fn ") +13025 8b/-> *(ebp+0x10) 0/r32/eax +13026 (lookup *eax *(eax+4)) # Function-name Function-name => eax +13027 (write-buffered *(ebp+0x14) %eax) +13028 (write-buffered *(ebp+0x14) ": stmt ") +13029 8b/-> *(ebp+0xc) 0/r32/eax +13030 (lookup *(eax+4) *(eax+8)) # Stmt1-operation Stmt1-operation => eax +13031 (write-buffered *(ebp+0x14) %eax) +13032 (write-buffered *(ebp+0x14) ": only non-addr scalar args permitted\n") +13033 (flush *(ebp+0x14)) +13034 (stop *(ebp+0x18) 1) +13035 # never gets here +13036 +13037 check-mu-copy-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +13038 # . prologue +13039 55/push-ebp +13040 89/<- %ebp 4/r32/esp +13041 # . save registers +13042 $check-mu-copy-stmt:end: +13043 # . restore registers +13044 # . epilogue +13045 89/<- %esp 5/r32/ebp +13046 5d/pop-to-ebp +13047 c3/return +13048 +13049 check-mu-copy-to-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +13050 # . prologue +13051 55/push-ebp +13052 89/<- %ebp 4/r32/esp +13053 # . save registers +13054 $check-mu-copy-to-stmt:end: +13055 # . restore registers +13056 # . epilogue +13057 89/<- %esp 5/r32/ebp +13058 5d/pop-to-ebp +13059 c3/return +13060 +13061 check-mu-compare-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +13062 # . prologue +13063 55/push-ebp +13064 89/<- %ebp 4/r32/esp +13065 # . save registers +13066 $check-mu-compare-stmt:end: +13067 # . restore registers +13068 # . epilogue +13069 89/<- %esp 5/r32/ebp +13070 5d/pop-to-ebp +13071 c3/return +13072 +13073 check-mu-address-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +13074 # . prologue +13075 55/push-ebp +13076 89/<- %ebp 4/r32/esp +13077 # . save registers +13078 $check-mu-address-stmt:end: +13079 # . restore registers +13080 # . epilogue +13081 89/<- %esp 5/r32/ebp +13082 5d/pop-to-ebp +13083 c3/return +13084 +13085 check-mu-get-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +13086 # . prologue +13087 55/push-ebp +13088 89/<- %ebp 4/r32/esp +13089 # . save registers +13090 50/push-eax +13091 51/push-ecx +13092 52/push-edx +13093 53/push-ebx +13094 56/push-esi +13095 57/push-edi +13096 # esi = stmt +13097 8b/-> *(ebp+8) 6/r32/esi +13098 # - check for 0 inouts +13099 # var base/ecx: (addr var) = stmt->inouts->value +13100 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax +13101 3d/compare-eax-and 0/imm32/false +13102 0f 84/jump-if-= $check-mu-get-stmt:error-too-few-inouts/disp32 +13103 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +13104 89/<- %ecx 0/r32/eax +13105 $check-mu-get-stmt:check-base: +13106 # - check base type +13107 # if it's an 'addr', check that it's in a register +13108 # var base-type/ebx: (addr type-tree) = lookup(base->type) +13109 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax +13110 89/<- %ebx 0/r32/eax +13111 { +13112 81 7/subop/compare *ebx 0/imm32/false # Type-tree-is-atom +13113 0f 85/jump-if-!= break/disp32 +13114 $check-mu-get-stmt:base-is-compound: +13115 # if (type->left != addr) break +13116 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax +13117 (is-simple-mu-type? %eax 2) # addr => eax +13118 3d/compare-eax-and 0/imm32/false +13119 74/jump-if-= break/disp8 +13120 $check-mu-get-stmt:base-is-addr: +13121 # now check for register +13122 81 7/subop/compare *(ecx+0x18) 0/imm32 # Var-register +13123 0f 84/jump-if-= $check-mu-get-stmt:error-base-type-addr-but-not-register/disp32 +13124 $check-mu-get-stmt:base-is-addr-in-register: +13125 # type->left is now an addr; skip it +13126 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax +13127 81 7/subop/compare *(eax+0xc) 0/imm32 # Type-tree-right +13128 0f 85/jump-if-!= $check-mu-get-stmt:error-bad-base/disp32 +13129 $check-mu-get-stmt:base-is-addr-to-atom-in-register: +13130 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +13131 89/<- %ebx 0/r32/eax +13132 } +13133 $check-mu-get-stmt:check-base-typeinfo: +13134 # ensure type is a container +13135 # var base-type-id/ebx: type-id = base-type->value +13136 8b/-> *(ebx+4) 3/r32/ebx # Type-tree-value +13137 (is-container? %ebx) # => eax +13138 3d/compare-eax-and 0/imm32/false +13139 0f 84/jump-if-= $check-mu-get-stmt:error-bad-base/disp32 +13140 # var base-typeinfo/edx: (addr typeinfo) = find-typeinfo(base-type-id) +13141 # . var container/ecx: (handle typeinfo) +13142 68/push 0/imm32 +13143 68/push 0/imm32 +13144 89/<- %ecx 4/r32/esp +13145 # . +13146 (find-typeinfo %ebx %ecx) +13147 (lookup *ecx *(ecx+4)) # => eax +13148 # . reclaim container +13149 81 0/subop/add %esp 8/imm32 +13150 # . +13151 89/<- %edx 0/r32/eax +13152 # var offset/ecx: (addr stmt-var) = stmt->inouts->next +13153 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax +13154 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax +13155 89/<- %ecx 0/r32/eax +13156 # - check for 1 inout +13157 3d/compare-eax-and 0/imm32/false +13158 0f 84/jump-if-= $check-mu-get-stmt:error-too-few-inouts/disp32 +13159 # var offset/ecx: (addr var) = lookup(offset->value) +13160 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax +13161 89/<- %ecx 0/r32/eax +13162 # - check for valid field +13163 81 7/subop/compare *(ecx+0x14) -1/imm32/uninitialized # Var-offset +13164 0f 84/jump-if-= $check-mu-get-stmt:error-bad-field/disp32 +13165 # - check for too many inouts +13166 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax +13167 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax +13168 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax +13169 3d/compare-eax-and 0/imm32/false +13170 0f 85/jump-if-!= $check-mu-get-stmt:error-too-many-inouts/disp32 +13171 # var output/edi: (addr var) = stmt->outputs->value +13172 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax +13173 # - check for 0 outputs +13174 3d/compare-eax-and 0/imm32/false +13175 0f 84/jump-if-= $check-mu-get-stmt:error-too-few-outputs/disp32 +13176 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +13177 89/<- %edi 0/r32/eax +13178 $check-mu-get-stmt:check-output-type: +13179 # - check output type +13180 # must be in register +13181 (lookup *(edi+0x18) *(edi+0x1c)) # Var-register Var-register => eax +13182 3d/compare-eax-and 0/imm32 +13183 0f 84/jump-if-= $check-mu-get-stmt:error-output-not-in-register/disp32 +13184 # must have a non-atomic type +13185 (lookup *(edi+8) *(edi+0xc)) # Var-type Var-type => eax +13186 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom +13187 0f 85/jump-if-!= $check-mu-get-stmt:error-output-type-not-address/disp32 +13188 # type must start with (addr ...) +13189 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +13190 (is-simple-mu-type? %eax 2) # => eax +13191 3d/compare-eax-and 0/imm32/false +13192 0f 84/jump-if-= $check-mu-get-stmt:error-output-type-not-address/disp32 +13193 $check-mu-get-stmt:check-output-type-match: +13194 # payload of addr type must match 'type' definition +13195 (lookup *(edi+8) *(edi+0xc)) # Var-type Var-type => eax +13196 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax +13197 # if (payload->right == null) payload = payload->left +13198 81 7/subop/compare *(eax+0xc) 0/imm32/null # Type-tree-right +13199 { +13200 75/jump-if-!= break/disp8 +13201 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +13202 } +13203 89/<- %edi 0/r32/eax +13204 # . var output-name/ecx: (addr array byte) +13205 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax +13206 89/<- %ecx 0/r32/eax +13207 # . var base-typeinfo-entry/eax: (addr handle typeinfo-entry) +13208 (lookup *(edx+4) *(edx+8)) # Typeinfo-fields Typeinfo-fields => eax +13209 (get %eax %ecx 0x10) # => eax +13210 # . +13211 (lookup *eax *(eax+4)) # => eax +13212 (lookup *eax *(eax+4)) # Typeinfo-entry-input-var Typeinfo-entry-input-var => eax +13213 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +13214 # . +13215 (type-equal? %edi %eax) # => eax +13216 3d/compare-eax-and 0/imm32/false +13217 0f 84/jump-if-= $check-mu-get-stmt:error-bad-output-type/disp32 +13218 # - check for too many outputs +13219 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax +13220 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax +13221 3d/compare-eax-and 0/imm32/false +13222 0f 85/jump-if-!= $check-mu-get-stmt:error-too-many-outputs/disp32 +13223 $check-mu-get-stmt:end: +13224 # . restore registers +13225 5f/pop-to-edi +13226 5e/pop-to-esi +13227 5b/pop-to-ebx +13228 5a/pop-to-edx +13229 59/pop-to-ecx +13230 58/pop-to-eax +13231 # . epilogue +13232 89/<- %esp 5/r32/ebp +13233 5d/pop-to-ebp +13234 c3/return +13235 +13236 $check-mu-get-stmt:error-too-few-inouts: +13237 (write-buffered *(ebp+0x10) "fn ") +13238 8b/-> *(ebp+0xc) 0/r32/eax +13239 (lookup *eax *(eax+4)) # Function-name Function-name => eax +13240 (write-buffered *(ebp+0x10) %eax) +13241 (write-buffered *(ebp+0x10) ": stmt get: too few inouts (2 required)\n") +13242 (flush *(ebp+0x10)) +13243 (stop *(ebp+0x14) 1) +13244 # never gets here +13245 +13246 $check-mu-get-stmt:error-too-many-inouts: +13247 (write-buffered *(ebp+0x10) "fn ") +13248 8b/-> *(ebp+0xc) 0/r32/eax +13249 (lookup *eax *(eax+4)) # Function-name Function-name => eax +13250 (write-buffered *(ebp+0x10) %eax) +13251 (write-buffered *(ebp+0x10) ": stmt get: too many inouts (2 required)\n") +13252 (flush *(ebp+0x10)) +13253 (stop *(ebp+0x14) 1) +13254 # never gets here +13255 +13256 $check-mu-get-stmt:error-too-few-outputs: +13257 (write-buffered *(ebp+0x10) "fn ") +13258 8b/-> *(ebp+0xc) 0/r32/eax +13259 (lookup *eax *(eax+4)) # Function-name Function-name => eax +13260 (write-buffered *(ebp+0x10) %eax) +13261 (write-buffered *(ebp+0x10) ": stmt get: must have an output\n") +13262 (flush *(ebp+0x10)) +13263 (stop *(ebp+0x14) 1) +13264 # never gets here +13265 +13266 $check-mu-get-stmt:error-too-many-outputs: +13267 (write-buffered *(ebp+0x10) "fn ") +13268 8b/-> *(ebp+0xc) 0/r32/eax +13269 (lookup *eax *(eax+4)) # Function-name Function-name => eax +13270 (write-buffered *(ebp+0x10) %eax) +13271 (write-buffered *(ebp+0x10) ": stmt get: too many outputs (1 required)\n") +13272 (flush *(ebp+0x10)) +13273 (stop *(ebp+0x14) 1) +13274 # never gets here +13275 +13276 $check-mu-get-stmt:error-bad-base: +13277 # error("fn " fn ": stmt get: var '" base->name "' must have a 'type' definition\n") +13278 (write-buffered *(ebp+0x10) "fn ") +13279 8b/-> *(ebp+0xc) 0/r32/eax +13280 (lookup *eax *(eax+4)) # Function-name Function-name => eax +13281 (write-buffered *(ebp+0x10) %eax) +13282 (write-buffered *(ebp+0x10) ": stmt get: var '") +13283 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax +13284 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +13285 (lookup *eax *(eax+4)) # Var-name Var-name => eax +13286 (write-buffered *(ebp+0x10) %eax) +13287 (write-buffered *(ebp+0x10) "' must have a 'type' definition\n") +13288 (flush *(ebp+0x10)) +13289 (stop *(ebp+0x14) 1) +13290 # never gets here +13291 +13292 $check-mu-get-stmt:error-base-type-addr-but-not-register: +13293 (write-buffered *(ebp+0x10) "fn ") +13294 8b/-> *(ebp+0xc) 0/r32/eax +13295 (lookup *eax *(eax+4)) # Function-name Function-name => eax +13296 (write-buffered *(ebp+0x10) %eax) +13297 (write-buffered *(ebp+0x10) ": stmt get: var '") +13298 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax +13299 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +13300 (lookup *eax *(eax+4)) # Var-name Var-name => eax +13301 (write-buffered *(ebp+0x10) %eax) +13302 (write-buffered *(ebp+0x10) "' is an 'addr' type, and so must live in a register\n") +13303 (flush *(ebp+0x10)) +13304 (stop *(ebp+0x14) 1) +13305 # never gets here +13306 +13307 $check-mu-get-stmt:error-bad-field: +13308 # error("fn " fn ": stmt get: type " type " has no member called '" curr->name "'\n") +13309 (write-buffered *(ebp+0x10) "fn ") +13310 8b/-> *(ebp+0xc) 0/r32/eax +13311 (lookup *eax *(eax+4)) # Function-name Function-name => eax +13312 (write-buffered *(ebp+0x10) %eax) +13313 (write-buffered *(ebp+0x10) ": stmt get: type '") +13314 # . write(Type-id->data[tmp]) +13315 bf/copy-to-edi Type-id/imm32 +13316 (write-buffered *(ebp+0x10) *(edi+ebx<<2+0xc)) +13317 # . +13318 (write-buffered *(ebp+0x10) "' has no member called '") +13319 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax +13320 (write-buffered *(ebp+0x10) %eax) +13321 (write-buffered *(ebp+0x10) "'\n") +13322 (flush *(ebp+0x10)) +13323 (stop *(ebp+0x14) 1) +13324 # never gets here +13325 +13326 $check-mu-get-stmt:error-output-not-in-register: +13327 (write-buffered *(ebp+0x10) "fn ") +13328 8b/-> *(ebp+0xc) 0/r32/eax +13329 (lookup *eax *(eax+4)) # Function-name Function-name => eax +13330 (write-buffered *(ebp+0x10) %eax) +13331 (write-buffered *(ebp+0x10) ": stmt get: output '") +13332 (lookup *edi *(edi+4)) # Var-name Var-name => eax +13333 (write-buffered *(ebp+0x10) %eax) +13334 (write-buffered *(ebp+0x10) "' is not in a register\n") +13335 (flush *(ebp+0x10)) +13336 (stop *(ebp+0x14) 1) +13337 # never gets here +13338 +13339 $check-mu-get-stmt:error-output-type-not-address: +13340 (write-buffered *(ebp+0x10) "fn ") +13341 8b/-> *(ebp+0xc) 0/r32/eax +13342 (lookup *eax *(eax+4)) # Function-name Function-name => eax +13343 (write-buffered *(ebp+0x10) %eax) +13344 (write-buffered *(ebp+0x10) ": stmt get: output must be an address\n") +13345 (flush *(ebp+0x10)) +13346 (stop *(ebp+0x14) 1) +13347 # never gets here +13348 +13349 $check-mu-get-stmt:error-bad-output-type: +13350 (write-buffered *(ebp+0x10) "fn ") +13351 8b/-> *(ebp+0xc) 0/r32/eax +13352 (lookup *eax *(eax+4)) # Function-name Function-name => eax +13353 (write-buffered *(ebp+0x10) %eax) +13354 (write-buffered *(ebp+0x10) ": stmt get: wrong output type for member '") +13355 (write-buffered *(ebp+0x10) %ecx) +13356 (write-buffered *(ebp+0x10) "' of type '") +13357 bf/copy-to-edi Type-id/imm32 +13358 (write-buffered *(ebp+0x10) *(edi+ebx<<2+0xc)) +13359 (write-buffered *(ebp+0x10) "'\n") +13360 (flush *(ebp+0x10)) +13361 (stop *(ebp+0x14) 1) +13362 # never gets here +13363 +13364 check-mu-index-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +13365 # . prologue +13366 55/push-ebp +13367 89/<- %ebp 4/r32/esp +13368 # . save registers +13369 50/push-eax +13370 51/push-ecx +13371 52/push-edx +13372 53/push-ebx +13373 56/push-esi +13374 57/push-edi +13375 # esi = stmt +13376 8b/-> *(ebp+8) 6/r32/esi +13377 # - check for 0 inouts +13378 # var base/ecx: (addr var) = stmt->inouts->value +13379 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax +13380 $check-mu-index-stmt:check-no-inouts: +13381 3d/compare-eax-and 0/imm32 +13382 0f 84/jump-if-= $check-mu-index-stmt:error-too-few-inouts/disp32 +13383 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +13384 89/<- %ecx 0/r32/eax +13385 # - check base type is either (addr array ...) in register or (array ...) on stack +13386 # var base-type/ebx: (addr type-tree) = lookup(base->type) +13387 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax +13388 89/<- %ebx 0/r32/eax +13389 # if base-type is an atom, abort with a precise error +13390 81 7/subop/compare *ebx 0/imm32/false # Type-tree-is-atom +13391 { +13392 74/jump-if-= break/disp8 +13393 (is-simple-mu-type? %ebx 3) # array => eax +13394 3d/compare-eax-and 0/imm32/false +13395 0f 85/jump-if-!= $check-mu-index-stmt:error-base-array-atom-type/disp32 +13396 0f 84/jump-if-= $check-mu-index-stmt:error-base-non-array-type/disp32 +13397 } +13398 $check-mu-index-stmt:base-is-compound: +13399 # if type->left not addr or array, abort +13400 { +13401 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax +13402 (is-simple-mu-type? %eax 2) # addr => eax +13403 3d/compare-eax-and 0/imm32/false +13404 75/jump-if-!= break/disp8 +13405 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax +13406 (is-simple-mu-type? %eax 3) # array => eax +13407 3d/compare-eax-and 0/imm32/false +13408 75/jump-if-!= break/disp8 +13409 e9/jump $check-mu-index-stmt:error-base-non-array-type/disp32 +13410 } +13411 # if (type->left == addr) ensure type->right->left == array and type->register exists +13412 { +13413 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax +13414 (is-simple-mu-type? %eax 2) # addr => eax +13415 3d/compare-eax-and 0/imm32/false +13416 74/jump-if-= break/disp8 +13417 $check-mu-index-stmt:base-is-addr: +13418 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax +13419 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +13420 (is-simple-mu-type? %eax 3) # array => eax +13421 3d/compare-eax-and 0/imm32/false +13422 0f 84/jump-if-= $check-mu-index-stmt:error-base-non-array-type/disp32 +13423 $check-mu-index-stmt:check-base-addr-is-register: +13424 81 7/subop/compare *(ecx+0x18) 0/imm32 # Var-register +13425 0f 84/jump-if-= $check-mu-index-stmt:error-base-address-array-type-on-stack/disp32 +13426 } +13427 # if (type->left == array) ensure type->register doesn't exist +13428 { +13429 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax +13430 (is-simple-mu-type? %eax 3) # array => eax +13431 3d/compare-eax-and 0/imm32/false +13432 74/jump-if-= break/disp8 +13433 $check-mu-index-stmt:base-is-array: +13434 81 7/subop/compare *(ecx+0x18) 0/imm32 # Var-register +13435 0f 85/jump-if-!= $check-mu-index-stmt:error-base-array-type-in-register/disp32 +13436 } +13437 # if (base-type->left == addr) base-type = base-type->right +13438 { +13439 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax +13440 (is-simple-mu-type? %eax 2) # addr => eax +13441 3d/compare-eax-and 0/imm32/false +13442 74/jump-if-= break/disp8 +13443 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax +13444 89/<- %ebx 0/r32/eax +13445 } +13446 # - check for 1 inout +13447 # var index/ecx: (addr stmt-var) = stmt->inouts->next->value +13448 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax +13449 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax +13450 $check-mu-index-stmt:check-single-inout: +13451 3d/compare-eax-and 0/imm32 +13452 0f 84/jump-if-= $check-mu-index-stmt:error-too-few-inouts/disp32 +13453 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +13454 89/<- %ecx 0/r32/eax +13455 # - check index is either a literal or register +13456 # var index-type/edx: (addr type-tree) +13457 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax +13458 89/<- %edx 0/r32/eax +13459 # if index type is an atom, it must be a literal or int +13460 81 7/subop/compare *edx 0/imm32/false # Type-tree-is-atom +13461 { +13462 74/jump-if-= break/disp8 +13463 $check-mu-index-stmt:index-type-is-atom: +13464 (is-simple-mu-type? %edx 0) # literal => eax +13465 3d/compare-eax-and 0/imm32/false +13466 75/jump-if-!= $check-mu-index-stmt:index-type-done/disp8 +13467 (is-simple-mu-type? %edx 1) # int => eax +13468 3d/compare-eax-and 0/imm32/false +13469 75/jump-if-!= $check-mu-index-stmt:index-type-done/disp8 +13470 (is-simple-mu-type? %edx 7) # offset => eax +13471 3d/compare-eax-and 0/imm32/false +13472 0f 85/jump-if-!= $check-mu-index-stmt:error-index-offset-atom-type/disp32 +13473 e9/jump $check-mu-index-stmt:error-invalid-index-type/disp32 +13474 } +13475 # if index type is a non-atom: it must be an offset +13476 { +13477 75/jump-if-!= break/disp8 +13478 $check-mu-index-stmt:index-type-is-non-atom: +13479 (lookup *(edx+4) *(edx+8)) # Type-tree-left Type-tree-left => eax +13480 (is-simple-mu-type? %eax 7) # offset => eax +13481 3d/compare-eax-and 0/imm32/false +13482 0f 84/jump-if-= $check-mu-index-stmt:error-invalid-index-type/disp32 +13483 } +13484 $check-mu-index-stmt:index-type-done: +13485 # check index is either a literal or in a register +13486 { +13487 (is-simple-mu-type? %edx 0) # literal => eax +13488 3d/compare-eax-and 0/imm32/false +13489 75/jump-if-!= break/disp8 +13490 $check-mu-index-stmt:check-index-in-register: +13491 81 7/subop/compare *(ecx+0x18) 0/imm32 # Var-register +13492 0f 84/jump-if-= $check-mu-index-stmt:error-index-on-stack/disp32 +13493 } +13494 # - if index is an 'int', check that element type of base has size 1, 2, 4 or 8 bytes. +13495 { +13496 (is-simple-mu-type? %edx 1) # int => eax +13497 3d/compare-eax-and 0/imm32/false +13498 74/jump-if-= break/disp8 +13499 $check-mu-index-stmt:check-index-can-be-int: +13500 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax +13501 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +13502 (array-element-size %eax) # => eax +13503 3d/compare-eax-and 1/imm32 +13504 74/jump-if-= break/disp8 +13505 3d/compare-eax-and 2/imm32 +13506 74/jump-if-= break/disp8 +13507 3d/compare-eax-and 4/imm32 +13508 74/jump-if-= break/disp8 +13509 3d/compare-eax-and 8/imm32 +13510 74/jump-if-= break/disp8 +13511 e9/jump $check-mu-index-stmt:error-index-needs-offset/disp32 +13512 } +13513 # - check for too many inouts +13514 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax +13515 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax +13516 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax +13517 3d/compare-eax-and 0/imm32/false +13518 0f 85/jump-if-!= $check-mu-index-stmt:error-too-many-inouts/disp32 +13519 # - check for 0 outputs +13520 # var output/edi: (addr var) = stmt->outputs->value +13521 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax +13522 3d/compare-eax-and 0/imm32/false +13523 0f 84/jump-if-= $check-mu-index-stmt:error-too-few-outputs/disp32 +13524 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +13525 89/<- %edi 0/r32/eax +13526 # - check output type +13527 # must have a non-atomic type +13528 (lookup *(edi+8) *(edi+0xc)) # Var-type Var-type => eax +13529 89/<- %edx 0/r32/eax +13530 81 7/subop/compare *edx 0/imm32/false # Type-tree-is-atom +13531 0f 85/jump-if-!= $check-mu-index-stmt:error-output-type-not-address/disp32 +13532 # type must start with (addr ...) +13533 (lookup *(edx+4) *(edx+8)) # Type-tree-left Type-tree-left => eax +13534 (is-simple-mu-type? %eax 2) # addr => eax +13535 3d/compare-eax-and 0/imm32/false +13536 0f 84/jump-if-= $check-mu-index-stmt:error-output-type-not-address/disp32 +13537 # if tail(base-type) != tail(output-type) abort +13538 (type-tail %ebx) # => eax +13539 89/<- %ebx 0/r32/eax +13540 (type-tail %edx) # => eax +13541 (type-equal? %ebx %eax) # => eax +13542 3d/compare-eax-and 0/imm32/false +13543 0f 84/jump-if-= $check-mu-index-stmt:error-bad-output-type/disp32 +13544 # - check for too many outputs +13545 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax +13546 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax +13547 3d/compare-eax-and 0/imm32/false +13548 0f 85/jump-if-!= $check-mu-index-stmt:error-too-many-outputs/disp32 +13549 $check-mu-index-stmt:end: +13550 # . restore registers +13551 5f/pop-to-edi +13552 5e/pop-to-esi +13553 5b/pop-to-ebx +13554 5a/pop-to-edx +13555 59/pop-to-ecx +13556 58/pop-to-eax +13557 # . epilogue +13558 89/<- %esp 5/r32/ebp +13559 5d/pop-to-ebp +13560 c3/return +13561 +13562 $check-mu-index-stmt:error-base-non-array-type: +13563 (write-buffered *(ebp+0x10) "fn ") +13564 8b/-> *(ebp+0xc) 0/r32/eax +13565 (lookup *eax *(eax+4)) # Function-name Function-name => eax +13566 (write-buffered *(ebp+0x10) %eax) +13567 (write-buffered *(ebp+0x10) ": stmt index: var '") +13568 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax +13569 (write-buffered *(ebp+0x10) %eax) +13570 (write-buffered *(ebp+0x10) "' is not an array\n") +13571 (flush *(ebp+0x10)) +13572 (stop *(ebp+0x14) 1) +13573 # never gets here +13574 +13575 $check-mu-index-stmt:error-base-array-atom-type: +13576 (write-buffered *(ebp+0x10) "fn ") +13577 8b/-> *(ebp+0xc) 0/r32/eax +13578 (lookup *eax *(eax+4)) # Function-name Function-name => eax +13579 (write-buffered *(ebp+0x10) %eax) +13580 (write-buffered *(ebp+0x10) ": stmt index: array '") +13581 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax +13582 (write-buffered *(ebp+0x10) %eax) +13583 (write-buffered *(ebp+0x10) "' must specify the type of its elements\n") +13584 (flush *(ebp+0x10)) +13585 (stop *(ebp+0x14) 1) +13586 # never gets here +13587 +13588 $check-mu-index-stmt:error-base-address-array-type-on-stack: +13589 (write-buffered *(ebp+0x10) "fn ") +13590 8b/-> *(ebp+0xc) 0/r32/eax +13591 (lookup *eax *(eax+4)) # Function-name Function-name => eax +13592 (write-buffered *(ebp+0x10) %eax) +13593 (write-buffered *(ebp+0x10) ": stmt index: var '") +13594 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax +13595 (write-buffered *(ebp+0x10) %eax) +13596 (write-buffered *(ebp+0x10) "' is an addr to an array, and so must live in a register\n") +13597 (flush *(ebp+0x10)) +13598 (stop *(ebp+0x14) 1) +13599 # never gets here +13600 +13601 $check-mu-index-stmt:error-base-array-type-in-register: +13602 (write-buffered *(ebp+0x10) "fn ") +13603 8b/-> *(ebp+0xc) 0/r32/eax +13604 (lookup *eax *(eax+4)) # Function-name Function-name => eax +13605 (write-buffered *(ebp+0x10) %eax) +13606 (write-buffered *(ebp+0x10) ": stmt index: var '") +13607 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax +13608 (write-buffered *(ebp+0x10) %eax) +13609 (write-buffered *(ebp+0x10) "' is an array, and so must live on the stack\n") +13610 (flush *(ebp+0x10)) +13611 (stop *(ebp+0x14) 1) +13612 # never gets here +13613 +13614 $check-mu-index-stmt:error-too-few-inouts: +13615 (write-buffered *(ebp+0x10) "fn ") +13616 8b/-> *(ebp+0xc) 0/r32/eax +13617 (lookup *eax *(eax+4)) # Function-name Function-name => eax +13618 (write-buffered *(ebp+0x10) %eax) +13619 (write-buffered *(ebp+0x10) ": stmt index: too few inouts (2 required)\n") +13620 (flush *(ebp+0x10)) +13621 (stop *(ebp+0x14) 1) +13622 # never gets here +13623 +13624 $check-mu-index-stmt:error-invalid-index-type: +13625 (write-buffered *(ebp+0x10) "fn ") +13626 8b/-> *(ebp+0xc) 0/r32/eax +13627 (lookup *eax *(eax+4)) # Function-name Function-name => eax +13628 (write-buffered *(ebp+0x10) %eax) +13629 (write-buffered *(ebp+0x10) ": stmt index: second argument '") +13630 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax +13631 (write-buffered *(ebp+0x10) %eax) +13632 (write-buffered *(ebp+0x10) "' must be an int or offset\n") +13633 (flush *(ebp+0x10)) +13634 (stop *(ebp+0x14) 1) +13635 # never gets here +13636 +13637 $check-mu-index-stmt:error-index-offset-atom-type: +13638 (write-buffered *(ebp+0x10) "fn ") +13639 8b/-> *(ebp+0xc) 0/r32/eax +13640 (lookup *eax *(eax+4)) # Function-name Function-name => eax +13641 (write-buffered *(ebp+0x10) %eax) +13642 (write-buffered *(ebp+0x10) ": stmt index: offset '") +13643 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax +13644 (write-buffered *(ebp+0x10) %eax) +13645 (write-buffered *(ebp+0x10) "' must specify the type of array elements\n") +13646 (flush *(ebp+0x10)) +13647 (stop *(ebp+0x14) 1) +13648 # never gets here +13649 +13650 $check-mu-index-stmt:error-index-on-stack: +13651 (write-buffered *(ebp+0x10) "fn ") +13652 8b/-> *(ebp+0xc) 0/r32/eax +13653 (lookup *eax *(eax+4)) # Function-name Function-name => eax +13654 (write-buffered *(ebp+0x10) %eax) +13655 (write-buffered *(ebp+0x10) ": stmt index: second argument '") +13656 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax +13657 (write-buffered *(ebp+0x10) %eax) +13658 (write-buffered *(ebp+0x10) "' must be in a register\n") +13659 (flush *(ebp+0x10)) +13660 (stop *(ebp+0x14) 1) +13661 # never gets here +13662 +13663 $check-mu-index-stmt:error-index-needs-offset: +13664 (write-buffered *(ebp+0x10) "fn ") +13665 8b/-> *(ebp+0xc) 0/r32/eax +13666 (lookup *eax *(eax+4)) # Function-name Function-name => eax +13667 (write-buffered *(ebp+0x10) %eax) +13668 (write-buffered *(ebp+0x10) ": stmt index: cannot take an int for array '") +13669 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax +13670 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +13671 (lookup *eax *(eax+4)) # Var-name Var-name => eax +13672 (write-buffered *(ebp+0x10) %eax) +13673 (write-buffered *(ebp+0x10) "'; create an offset instead. See mu_summary for details.\n") +13674 (flush *(ebp+0x10)) +13675 (stop *(ebp+0x14) 1) +13676 # never gets here +13677 +13678 $check-mu-index-stmt:error-too-many-inouts: +13679 (write-buffered *(ebp+0x10) "fn ") +13680 8b/-> *(ebp+0xc) 0/r32/eax +13681 (lookup *eax *(eax+4)) # Function-name Function-name => eax +13682 (write-buffered *(ebp+0x10) %eax) +13683 (write-buffered *(ebp+0x10) ": stmt index: too many inouts (2 required)\n") +13684 (flush *(ebp+0x10)) +13685 (stop *(ebp+0x14) 1) +13686 # never gets here +13687 +13688 $check-mu-index-stmt:error-too-few-outputs: +13689 (write-buffered *(ebp+0x10) "fn ") +13690 8b/-> *(ebp+0xc) 0/r32/eax +13691 (lookup *eax *(eax+4)) # Function-name Function-name => eax +13692 (write-buffered *(ebp+0x10) %eax) +13693 (write-buffered *(ebp+0x10) ": stmt index: must have an output\n") +13694 (flush *(ebp+0x10)) +13695 (stop *(ebp+0x14) 1) +13696 # never gets here +13697 +13698 $check-mu-index-stmt:error-too-many-outputs: +13699 (write-buffered *(ebp+0x10) "fn ") +13700 8b/-> *(ebp+0xc) 0/r32/eax +13701 (lookup *eax *(eax+4)) # Function-name Function-name => eax +13702 (write-buffered *(ebp+0x10) %eax) +13703 (write-buffered *(ebp+0x10) ": stmt index: too many outputs (1 required)\n") +13704 (flush *(ebp+0x10)) +13705 (stop *(ebp+0x14) 1) +13706 # never gets here 13707 -13708 $push-output-and-maybe-emit-spill:abort: -13709 # error("var '" var->name "' initialized from an instruction must live in a register\n") -13710 (write-buffered *(ebp+0x1c) "var '") -13711 (write-buffered *(ebp+0x1c) *eax) # Var-name -13712 (write-buffered *(ebp+0x1c) "' initialized from an instruction must live in a register\n") -13713 (flush *(ebp+0x1c)) -13714 (stop *(ebp+0x20) 1) -13715 # never gets here -13716 -13717 emit-subx-cleanup-and-unconditional-nonlocal-branch: # out: (addr buffered-file), stmt: (addr stmt1), vars: (addr stack live-var) -13718 # . prologue -13719 55/push-ebp -13720 89/<- %ebp 4/r32/esp -13721 # . save registers -13722 50/push-eax -13723 51/push-ecx -13724 # ecx = stmt -13725 8b/-> *(ebp+0xc) 1/r32/ecx -13726 # var target/eax: (addr array byte) = curr-stmt->inouts->value->name -13727 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax -13728 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -13729 (lookup *eax *(eax+4)) # Var-name Var-name => eax -13730 # clean up until target block -13731 (emit-cleanup-code-until-target *(ebp+8) *(ebp+0x10) %eax) -13732 # emit jump to target block -13733 (emit-indent *(ebp+8) *Curr-block-depth) -13734 (write-buffered *(ebp+8) "e9/jump ") -13735 (write-buffered *(ebp+8) %eax) -13736 (lookup *(ecx+4) *(ecx+8)) # Stmt1-operation Stmt1-operation => eax -13737 (string-starts-with? %eax "break") -13738 3d/compare-eax-and 0/imm32/false -13739 { -13740 74/jump-if-= break/disp8 -13741 (write-buffered *(ebp+8) ":break/disp32\n") -13742 } -13743 3d/compare-eax-and 0/imm32/false # just in case the function call modified flags -13744 { -13745 75/jump-if-!= break/disp8 -13746 (write-buffered *(ebp+8) ":loop/disp32\n") -13747 } -13748 $emit-subx-cleanup-and-unconditional-nonlocal-branch:end: -13749 # . restore registers -13750 59/pop-to-ecx -13751 58/pop-to-eax -13752 # . epilogue -13753 89/<- %esp 5/r32/ebp -13754 5d/pop-to-ebp -13755 c3/return -13756 -13757 is-mu-branch?: # stmt: (addr stmt1) -> result/eax: boolean -13758 # . prologue -13759 55/push-ebp -13760 89/<- %ebp 4/r32/esp -13761 # . save registers -13762 51/push-ecx -13763 # ecx = lookup(stmt->operation) -13764 8b/-> *(ebp+8) 1/r32/ecx -13765 (lookup *(ecx+4) *(ecx+8)) # Stmt1-operation Stmt1-operation => eax -13766 89/<- %ecx 0/r32/eax -13767 # if (stmt->operation starts with "loop") return true -13768 (string-starts-with? %ecx "loop") # => eax -13769 3d/compare-eax-and 0/imm32/false -13770 75/jump-if-not-equal $is-mu-branch?:end/disp8 -13771 # otherwise return (stmt->operation starts with "break") -13772 (string-starts-with? %ecx "break") # => eax -13773 $is-mu-branch?:end: -13774 # . restore registers -13775 59/pop-to-ecx -13776 # . epilogue -13777 89/<- %esp 5/r32/ebp -13778 5d/pop-to-ebp -13779 c3/return -13780 -13781 emit-reverse-break: # out: (addr buffered-file), stmt: (addr stmt1) -13782 # . prologue -13783 55/push-ebp -13784 89/<- %ebp 4/r32/esp -13785 # . save registers -13786 50/push-eax -13787 # eax = stmt -13788 8b/-> *(ebp+0xc) 0/r32/eax -13789 # -13790 (lookup *(eax+4) *(eax+8)) # Stmt1-operation Stmt1-operation => eax -13791 (get Reverse-branch %eax 0x10 "reverse-branch: ") # => eax: (addr handle array byte) -13792 (emit-indent *(ebp+8) *Curr-block-depth) -13793 (lookup *eax *(eax+4)) # => eax -13794 (write-buffered *(ebp+8) %eax) -13795 (write-buffered *(ebp+8) " break/disp32\n") -13796 $emit-reverse-break:end: -13797 # . restore registers -13798 58/pop-to-eax -13799 # . epilogue -13800 89/<- %esp 5/r32/ebp -13801 5d/pop-to-ebp -13802 c3/return -13803 -13804 == data -13805 -13806 # Table from Mu branch instructions to the reverse SubX opcodes for them. -13807 Reverse-branch: # (table (handle array byte) (handle array byte)) -13808 # a table is a stream -13809 0x140/imm32/write -13810 0/imm32/read -13811 0x140/imm32/size -13812 # data -13813 0x11/imm32/alloc-id _string-break-if-=/imm32 0x11/imm32/alloc-id _string_0f_85_jump_label/imm32 -13814 0x11/imm32/alloc-id _string-loop-if-=/imm32 0x11/imm32/alloc-id _string_0f_85_jump_label/imm32 -13815 0x11/imm32/alloc-id _string-break-if-!=/imm32 0x11/imm32/alloc-id _string_0f_84_jump_label/imm32 -13816 0x11/imm32/alloc-id _string-loop-if-!=/imm32 0x11/imm32/alloc-id _string_0f_84_jump_label/imm32 -13817 0x11/imm32/alloc-id _string-break-if-</imm32 0x11/imm32/alloc-id _string_0f_8d_jump_label/imm32 -13818 0x11/imm32/alloc-id _string-loop-if-</imm32 0x11/imm32/alloc-id _string_0f_8d_jump_label/imm32 -13819 0x11/imm32/alloc-id _string-break-if->/imm32 0x11/imm32/alloc-id _string_0f_8e_jump_label/imm32 -13820 0x11/imm32/alloc-id _string-loop-if->/imm32 0x11/imm32/alloc-id _string_0f_8e_jump_label/imm32 -13821 0x11/imm32/alloc-id _string-break-if-<=/imm32 0x11/imm32/alloc-id _string_0f_87_jump_label/imm32 -13822 0x11/imm32/alloc-id _string-loop-if-<=/imm32 0x11/imm32/alloc-id _string_0f_87_jump_label/imm32 -13823 0x11/imm32/alloc-id _string-break-if->=/imm32 0x11/imm32/alloc-id _string_0f_8c_jump_label/imm32 -13824 0x11/imm32/alloc-id _string-loop-if->=/imm32 0x11/imm32/alloc-id _string_0f_8c_jump_label/imm32 -13825 0x11/imm32/alloc-id _string-break-if-addr</imm32 0x11/imm32/alloc-id _string_0f_83_jump_label/imm32 -13826 0x11/imm32/alloc-id _string-loop-if-addr</imm32 0x11/imm32/alloc-id _string_0f_83_jump_label/imm32 -13827 0x11/imm32/alloc-id _string-break-if-addr>/imm32 0x11/imm32/alloc-id _string_0f_86_jump_label/imm32 -13828 0x11/imm32/alloc-id _string-loop-if-addr>/imm32 0x11/imm32/alloc-id _string_0f_86_jump_label/imm32 -13829 0x11/imm32/alloc-id _string-break-if-addr<=/imm32 0x11/imm32/alloc-id _string_0f_87_jump_label/imm32 -13830 0x11/imm32/alloc-id _string-loop-if-addr<=/imm32 0x11/imm32/alloc-id _string_0f_87_jump_label/imm32 -13831 0x11/imm32/alloc-id _string-break-if-addr>=/imm32 0x11/imm32/alloc-id _string_0f_82_jump_label/imm32 -13832 0x11/imm32/alloc-id _string-loop-if-addr>=/imm32 0x11/imm32/alloc-id _string_0f_82_jump_label/imm32 -13833 -13834 == code -13835 -13836 emit-unconditional-jump-to-depth: # out: (addr buffered-file), vars: (addr stack live-var), depth: int, label-suffix: (addr array byte) -13837 # . prologue -13838 55/push-ebp -13839 89/<- %ebp 4/r32/esp -13840 # . save registers -13841 50/push-eax -13842 51/push-ecx -13843 52/push-edx -13844 53/push-ebx -13845 56/push-esi -13846 # ecx = vars -13847 8b/-> *(ebp+0xc) 1/r32/ecx -13848 # var eax: int = vars->top -13849 8b/-> *ecx 0/r32/eax -13850 # var curr/esi: (addr handle var) = &vars->data[vars->top - 12] -13851 8d/copy-address *(ecx+eax-4) 6/r32/esi # vars + 8 + vars->top - 12/Live-var-size -13852 # var min/ecx: (addr handle var) = vars->data -13853 8d/copy-address *(ecx+8) 1/r32/ecx -13854 # edx = depth -13855 8b/-> *(ebp+0x10) 2/r32/edx -13856 { -13857 $emit-unconditional-jump-to-depth:loop: -13858 # if (curr < min) break -13859 39/compare %esi 1/r32/ecx -13860 0f 82/jump-if-addr< break/disp32 -13861 # var v/ebx: (addr var) = lookup(*curr) -13862 (lookup *esi *(esi+4)) # => eax -13863 89/<- %ebx 0/r32/eax -13864 # if (v->block-depth < until-block-depth) break -13865 39/compare *(ebx+0x10) 2/r32/edx # Var-block-depth -13866 0f 8c/jump-if-< break/disp32 -13867 { -13868 $emit-unconditional-jump-to-depth:check: -13869 # if v->block-depth != until-block-depth, continue -13870 39/compare *(ebx+0x10) 2/r32/edx # Var-block-depth -13871 0f 85/jump-if-!= break/disp32 -13872 $emit-unconditional-jump-to-depth:depth-found: -13873 # if v is not a literal, continue -13874 (size-of %ebx) # => eax -13875 3d/compare-eax-and 0/imm32 -13876 0f 85/jump-if-!= break/disp32 -13877 $emit-unconditional-jump-to-depth:label-found: -13878 # emit unconditional jump, then return -13879 (emit-indent *(ebp+8) *Curr-block-depth) -13880 (write-buffered *(ebp+8) "e9/jump ") -13881 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax -13882 (write-buffered *(ebp+8) %eax) -13883 (write-buffered *(ebp+8) ":") -13884 (write-buffered *(ebp+8) *(ebp+0x14)) -13885 (write-buffered *(ebp+8) "/disp32\n") -13886 eb/jump $emit-unconditional-jump-to-depth:end/disp8 +13708 $check-mu-index-stmt:error-output-not-in-register: +13709 (write-buffered *(ebp+0x10) "fn ") +13710 8b/-> *(ebp+0xc) 0/r32/eax +13711 (lookup *eax *(eax+4)) # Function-name Function-name => eax +13712 (write-buffered *(ebp+0x10) %eax) +13713 (write-buffered *(ebp+0x10) ": stmt index: output '") +13714 (lookup *edi *(edi+4)) # Var-name Var-name => eax +13715 (write-buffered *(ebp+0x10) %eax) +13716 (write-buffered *(ebp+0x10) "' is not in a register\n") +13717 (flush *(ebp+0x10)) +13718 (stop *(ebp+0x14) 1) +13719 # never gets here +13720 +13721 $check-mu-index-stmt:error-output-type-not-address: +13722 (write-buffered *(ebp+0x10) "fn ") +13723 8b/-> *(ebp+0xc) 0/r32/eax +13724 (lookup *eax *(eax+4)) # Function-name Function-name => eax +13725 (write-buffered *(ebp+0x10) %eax) +13726 (write-buffered *(ebp+0x10) ": stmt index: output '") +13727 (lookup *edi *(edi+4)) # Var-name Var-name => eax +13728 (write-buffered *(ebp+0x10) %eax) +13729 (write-buffered *(ebp+0x10) "' must be an address\n") +13730 (flush *(ebp+0x10)) +13731 (stop *(ebp+0x14) 1) +13732 # never gets here +13733 +13734 $check-mu-index-stmt:error-bad-output-type: +13735 (write-buffered *(ebp+0x10) "fn ") +13736 8b/-> *(ebp+0xc) 0/r32/eax +13737 (lookup *eax *(eax+4)) # Function-name Function-name => eax +13738 (write-buffered *(ebp+0x10) %eax) +13739 (write-buffered *(ebp+0x10) ": stmt index: output '") +13740 (lookup *edi *(edi+4)) # Var-name Var-name => eax +13741 (write-buffered *(ebp+0x10) %eax) +13742 (write-buffered *(ebp+0x10) "' does not have the right type\n") +13743 (flush *(ebp+0x10)) +13744 (stop *(ebp+0x14) 1) +13745 # never gets here +13746 +13747 check-mu-length-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +13748 # . prologue +13749 55/push-ebp +13750 89/<- %ebp 4/r32/esp +13751 # . save registers +13752 $check-mu-length-stmt:end: +13753 # . restore registers +13754 # . epilogue +13755 89/<- %esp 5/r32/ebp +13756 5d/pop-to-ebp +13757 c3/return +13758 +13759 check-mu-compute-offset-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +13760 # . prologue +13761 55/push-ebp +13762 89/<- %ebp 4/r32/esp +13763 # . save registers +13764 $check-mu-compute-offset-stmt:end: +13765 # . restore registers +13766 # . epilogue +13767 89/<- %esp 5/r32/ebp +13768 5d/pop-to-ebp +13769 c3/return +13770 +13771 check-mu-allocate-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +13772 # . prologue +13773 55/push-ebp +13774 89/<- %ebp 4/r32/esp +13775 # . save registers +13776 $check-mu-allocate-stmt:end: +13777 # . restore registers +13778 # . epilogue +13779 89/<- %esp 5/r32/ebp +13780 5d/pop-to-ebp +13781 c3/return +13782 +13783 check-mu-populate-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +13784 # . prologue +13785 55/push-ebp +13786 89/<- %ebp 4/r32/esp +13787 # . save registers +13788 $check-mu-populate-stmt:end: +13789 # . restore registers +13790 # . epilogue +13791 89/<- %esp 5/r32/ebp +13792 5d/pop-to-ebp +13793 c3/return +13794 +13795 check-mu-populate-stream-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +13796 # . prologue +13797 55/push-ebp +13798 89/<- %ebp 4/r32/esp +13799 # . save registers +13800 $check-mu-populate-stream-stmt:end: +13801 # . restore registers +13802 # . epilogue +13803 89/<- %esp 5/r32/ebp +13804 5d/pop-to-ebp +13805 c3/return +13806 +13807 check-mu-read-from-stream-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +13808 # . prologue +13809 55/push-ebp +13810 89/<- %ebp 4/r32/esp +13811 # . save registers +13812 $check-mu-read-from-stream-stmt:end: +13813 # . restore registers +13814 # . epilogue +13815 89/<- %esp 5/r32/ebp +13816 5d/pop-to-ebp +13817 c3/return +13818 +13819 check-mu-write-to-stream-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +13820 # . prologue +13821 55/push-ebp +13822 89/<- %ebp 4/r32/esp +13823 # . save registers +13824 $check-mu-write-to-stream-stmt:end: +13825 # . restore registers +13826 # . epilogue +13827 89/<- %esp 5/r32/ebp +13828 5d/pop-to-ebp +13829 c3/return +13830 +13831 check-mu-call: # stmt: (addr stmt), callee: (addr function), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +13832 # . prologue +13833 55/push-ebp +13834 89/<- %ebp 4/r32/esp +13835 # var type-parameters: (addr table (handle array byte) (addr type-tree) 8) +13836 68/push 0/imm32 +13837 # var type-parameters-storage: (table (handle array byte) (addr type-tree) 8) +13838 81 5/subop/subtract %esp 0x60/imm32 +13839 68/push 0x60/imm32/size +13840 68/push 0/imm32/read +13841 68/push 0/imm32/write +13842 # save a pointer to type-parameters-storage at type-parameters +13843 89/<- *(ebp-4) 4/r32/esp +13844 (clear-stream *(ebp-4)) +13845 # . save registers +13846 50/push-eax +13847 51/push-ecx +13848 52/push-edx +13849 53/push-ebx +13850 56/push-esi +13851 57/push-edi +13852 # esi = stmt +13853 8b/-> *(ebp+8) 6/r32/esi +13854 # edi = callee +13855 8b/-> *(ebp+0xc) 7/r32/edi +13856 # var inouts/ecx: (addr stmt-var) = lookup(stmt->inouts) +13857 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax +13858 89/<- %ecx 0/r32/eax +13859 # var expected/edx: (addr list var) = lookup(f->inouts) +13860 (lookup *(edi+8) *(edi+0xc)) # Function-inouts Function-inouts => eax +13861 89/<- %edx 0/r32/eax +13862 { +13863 $check-mu-call:check-for-inouts: +13864 # if (inouts == 0) break +13865 81 7/subop/compare %ecx 0/imm32 +13866 0f 84/jump-if-= break/disp32 +13867 # if (expected == 0) error +13868 81 7/subop/compare %edx 0/imm32 +13869 0f 84/jump-if-= break/disp32 +13870 $check-mu-call:check-inout-type: +13871 # var v/eax: (addr v) = lookup(inouts->value) +13872 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax +13873 # var t/ebx: (addr type-tree) = lookup(v->type) +13874 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +13875 89/<- %ebx 0/r32/eax +13876 # if (inouts->is-deref?) t = t->right # TODO: check that t->left is an addr +13877 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref +13878 { +13879 74/jump-if-= break/disp8 +13880 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax +13881 89/<- %ebx 0/r32/eax +13882 # if t->right is null, t = t->left +13883 81 7/subop/compare *(ebx+0xc) 0/imm32 # Type-tree-right +13884 75/jump-if-!= break/disp8 +13885 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax +13886 89/<- %ebx 0/r32/eax 13887 } -13888 # curr -= 12 -13889 81 5/subop/subtract %esi 0xc/imm32 -13890 e9/jump loop/disp32 -13891 } -13892 # TODO: error if no label at 'depth' was found -13893 $emit-unconditional-jump-to-depth:end: -13894 # . restore registers -13895 5e/pop-to-esi -13896 5b/pop-to-ebx -13897 5a/pop-to-edx -13898 59/pop-to-ecx -13899 58/pop-to-eax -13900 # . epilogue -13901 89/<- %esp 5/r32/ebp -13902 5d/pop-to-ebp -13903 c3/return -13904 -13905 # emit clean-up code for 'vars' until some block depth -13906 # doesn't actually modify 'vars' so we need traverse manually inside the stack -13907 emit-cleanup-code-until-depth: # out: (addr buffered-file), vars: (addr stack live-var), until-block-depth: int -13908 # . prologue -13909 55/push-ebp -13910 89/<- %ebp 4/r32/esp -13911 # . save registers -13912 50/push-eax -13913 51/push-ecx -13914 52/push-edx -13915 53/push-ebx -13916 56/push-esi -13917 #? (write-buffered Stderr "--- cleanup\n") -13918 #? (flush Stderr) -13919 # ecx = vars -13920 8b/-> *(ebp+0xc) 1/r32/ecx -13921 # var esi: int = vars->top -13922 8b/-> *ecx 6/r32/esi -13923 # var curr/esi: (addr handle var) = &vars->data[vars->top - 12] -13924 8d/copy-address *(ecx+esi-4) 6/r32/esi # vars + 8 + vars->top - 12/Live-var-size -13925 # var min/ecx: (addr handle var) = vars->data -13926 81 0/subop/add %ecx 8/imm32 -13927 # edx = until-block-depth -13928 8b/-> *(ebp+0x10) 2/r32/edx -13929 { -13930 $emit-cleanup-code-until-depth:loop: -13931 # if (curr < min) break -13932 39/compare %esi 1/r32/ecx -13933 0f 82/jump-if-addr< break/disp32 -13934 # var v/ebx: (addr var) = lookup(*curr) -13935 (lookup *esi *(esi+4)) # => eax -13936 89/<- %ebx 0/r32/eax -13937 #? (lookup *ebx *(ebx+4)) # Var-name -13938 #? (write-buffered Stderr "var ") -13939 #? (write-buffered Stderr %eax) -13940 #? (write-buffered Stderr Newline) -13941 #? (flush Stderr) -13942 # if (v->block-depth < until-block-depth) break -13943 39/compare *(ebx+0x10) 2/r32/edx # Var-block-depth -13944 0f 8c/jump-if-< break/disp32 -13945 # if v is in a register -13946 81 7/subop/compare *(ebx+0x18) 0/imm32 # Var-register -13947 { -13948 0f 84/jump-if-= break/disp32 -13949 { -13950 $emit-cleanup-code-until-depth:check-for-previous-spill: -13951 8b/-> *(esi+8) 0/r32/eax # Live-var-register-spilled -13952 3d/compare-eax-and 0/imm32/false -13953 74/jump-if-= break/disp8 -13954 $emit-cleanup-code-until-depth:reclaim-var-in-register: -13955 (emit-indent *(ebp+8) *Curr-block-depth) -13956 (write-buffered *(ebp+8) "8f 0/subop/pop %") -13957 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register Var-register => eax -13958 (write-buffered *(ebp+8) %eax) -13959 (write-buffered *(ebp+8) Newline) -13960 } -13961 eb/jump $emit-cleanup-code-until-depth:continue/disp8 -13962 } -13963 # otherwise v is on the stack -13964 { -13965 75/jump-if-!= break/disp8 -13966 $emit-cleanup-code-until-depth:var-on-stack: -13967 (size-of %ebx) # => eax -13968 # don't emit code for labels -13969 3d/compare-eax-and 0/imm32 -13970 74/jump-if-= break/disp8 -13971 $emit-cleanup-code-until-depth:reclaim-var-on-stack: -13972 (emit-indent *(ebp+8) *Curr-block-depth) -13973 (write-buffered *(ebp+8) "81 0/subop/add %esp ") -13974 (write-int32-hex-buffered *(ebp+8) %eax) -13975 (write-buffered *(ebp+8) "/imm32\n") -13976 } -13977 $emit-cleanup-code-until-depth:continue: -13978 # curr -= 12 -13979 81 5/subop/subtract %esi 0xc/imm32 -13980 e9/jump loop/disp32 -13981 } -13982 $emit-cleanup-code-until-depth:end: -13983 # . restore registers -13984 5e/pop-to-esi -13985 5b/pop-to-ebx -13986 5a/pop-to-edx -13987 59/pop-to-ecx -13988 58/pop-to-eax -13989 # . epilogue -13990 89/<- %esp 5/r32/ebp -13991 5d/pop-to-ebp -13992 c3/return -13993 -13994 # emit clean-up code for 'vars' until a given label is encountered -13995 # doesn't actually modify 'vars' so we need traverse manually inside the stack -13996 emit-cleanup-code-until-target: # out: (addr buffered-file), vars: (addr stack live-var), until-block-label: (addr array byte) -13997 # . prologue -13998 55/push-ebp -13999 89/<- %ebp 4/r32/esp -14000 # . save registers -14001 50/push-eax -14002 51/push-ecx -14003 52/push-edx -14004 53/push-ebx -14005 # ecx = vars -14006 8b/-> *(ebp+0xc) 1/r32/ecx -14007 # var eax: int = vars->top -14008 8b/-> *ecx 0/r32/eax -14009 # var curr/edx: (addr handle var) = &vars->data[vars->top - 12] -14010 8d/copy-address *(ecx+eax-4) 2/r32/edx # vars + 8 + vars->top - 12/Live-var-size -14011 # var min/ecx: (addr handle var) = vars->data -14012 81 0/subop/add %ecx 8/imm32 -14013 { -14014 $emit-cleanup-code-until-target:loop: -14015 # if (curr < min) break -14016 39/compare %edx 1/r32/ecx -14017 0f 82/jump-if-addr< break/disp32 -14018 # var v/ebx: (handle var) = lookup(*curr) -14019 (lookup *edx *(edx+4)) # => eax -14020 89/<- %ebx 0/r32/eax -14021 # if (v->name == until-block-label) break -14022 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax -14023 (string-equal? %eax *(ebp+0x10)) # => eax -14024 3d/compare-eax-and 0/imm32/false -14025 0f 85/jump-if-!= break/disp32 -14026 # if v is in a register -14027 81 7/subop/compare *(ebx+0x18) 0/imm32 # Var-register -14028 { -14029 0f 84/jump-if-= break/disp32 -14030 { -14031 $emit-cleanup-code-until-target:check-for-previous-spill: -14032 8b/-> *(edx+8) 0/r32/eax # Live-var-register-spilled -14033 3d/compare-eax-and 0/imm32/false -14034 74/jump-if-= break/disp8 -14035 $emit-cleanup-code-until-target:reclaim-var-in-register: -14036 (emit-indent *(ebp+8) *Curr-block-depth) -14037 (write-buffered *(ebp+8) "8f 0/subop/pop %") -14038 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register Var-register => eax -14039 (write-buffered *(ebp+8) %eax) -14040 (write-buffered *(ebp+8) Newline) -14041 } -14042 eb/jump $emit-cleanup-code-until-target:continue/disp8 -14043 } -14044 # otherwise v is on the stack -14045 { -14046 75/jump-if-!= break/disp8 -14047 $emit-cleanup-code-until-target:reclaim-var-on-stack: -14048 (size-of %ebx) # => eax -14049 # don't emit code for labels -14050 3d/compare-eax-and 0/imm32 -14051 74/jump-if-= break/disp8 -14052 # -14053 (emit-indent *(ebp+8) *Curr-block-depth) -14054 (write-buffered *(ebp+8) "81 0/subop/add %esp ") -14055 (write-int32-hex-buffered *(ebp+8) %eax) -14056 (write-buffered *(ebp+8) "/imm32\n") -14057 } -14058 $emit-cleanup-code-until-target:continue: -14059 # curr -= 12 -14060 81 5/subop/subtract %edx 0xc/imm32 -14061 e9/jump loop/disp32 -14062 } -14063 $emit-cleanup-code-until-target:end: -14064 # . restore registers -14065 5b/pop-to-ebx -14066 5a/pop-to-edx -14067 59/pop-to-ecx -14068 58/pop-to-eax -14069 # . epilogue -14070 89/<- %esp 5/r32/ebp -14071 5d/pop-to-ebp -14072 c3/return -14073 -14074 # Return true if there isn't a variable in 'vars' with the same block-depth -14075 # and register as 'v'. -14076 # 'v' is guaranteed not to be within 'vars'. -14077 not-yet-spilled-this-block?: # v: (addr var), vars: (addr stack live-var) -> result/eax: boolean -14078 # . prologue -14079 55/push-ebp -14080 89/<- %ebp 4/r32/esp -14081 # . save registers -14082 51/push-ecx -14083 52/push-edx -14084 53/push-ebx -14085 56/push-esi -14086 57/push-edi -14087 # ecx = vars -14088 8b/-> *(ebp+0xc) 1/r32/ecx -14089 # var eax: int = vars->top -14090 8b/-> *ecx 0/r32/eax -14091 # var curr/edx: (addr handle var) = &vars->data[vars->top - 12] -14092 8d/copy-address *(ecx+eax-4) 2/r32/edx # vars + 8 + vars->top - 12/Live-var-size -14093 # var min/ecx: (addr handle var) = vars->data -14094 8d/copy-address *(ecx+8) 1/r32/ecx -14095 # var depth/ebx: int = v->block-depth -14096 8b/-> *(ebp+8) 3/r32/ebx -14097 8b/-> *(ebx+0x10) 3/r32/ebx # Var-block-depth -14098 # var needle/esi: (addr array byte) = v->register -14099 8b/-> *(ebp+8) 6/r32/esi -14100 (lookup *(esi+0x18) *(esi+0x1c)) # Var-register Var-register => eax -14101 89/<- %esi 0/r32/eax -14102 { -14103 $not-yet-spilled-this-block?:loop: -14104 # if (curr < min) break -14105 39/compare %edx 1/r32/ecx -14106 0f 82/jump-if-addr< break/disp32 -14107 # var cand/edi: (addr var) = lookup(*curr) -14108 (lookup *edx *(edx+4)) # => eax -14109 89/<- %edi 0/r32/eax -14110 # if (cand->block-depth < depth) break -14111 39/compare *(edi+0x10) 3/r32/ebx # Var-block-depth -14112 0f 8c/jump-if-< break/disp32 -14113 # var cand-reg/edi: (array array byte) = cand->reg -14114 (lookup *(edi+0x18) *(edi+0x1c)) # Var-register Var-register => eax -14115 89/<- %edi 0/r32/eax -14116 # if (cand-reg == null) continue -14117 { -14118 $not-yet-spilled-this-block?:check-reg: -14119 81 7/subop/compare %edi 0/imm32 -14120 0f 84/jump-if-= break/disp32 -14121 # if (cand-reg == needle) return true -14122 (string-equal? %esi %edi) # => eax -14123 3d/compare-eax-and 0/imm32/false -14124 74/jump-if-= break/disp8 -14125 $not-yet-spilled-this-block?:return-false: -14126 b8/copy-to-eax 0/imm32/false -14127 eb/jump $not-yet-spilled-this-block?:end/disp8 -14128 } -14129 $not-yet-spilled-this-block?:continue: -14130 # curr -= 12 -14131 81 5/subop/subtract %edx 0xc/imm32 -14132 e9/jump loop/disp32 -14133 } -14134 $not-yet-spilled-this-block?:return-true: -14135 # return true -14136 b8/copy-to-eax 1/imm32/true -14137 $not-yet-spilled-this-block?:end: -14138 # . restore registers -14139 5f/pop-to-edi -14140 5e/pop-to-esi -14141 5b/pop-to-ebx -14142 5a/pop-to-edx -14143 59/pop-to-ecx -14144 # . epilogue -14145 89/<- %esp 5/r32/ebp -14146 5d/pop-to-ebp -14147 c3/return -14148 -14149 # could the register of 'v' ever be written to by one of the vars in fn-outputs? -14150 will-not-write-some-register?: # v: (addr var), stmts: (addr list stmt), fn: (addr function) -> result/eax: boolean -14151 # . prologue -14152 55/push-ebp -14153 89/<- %ebp 4/r32/esp -14154 # eax = v -14155 8b/-> *(ebp+8) 0/r32/eax -14156 # var reg/eax: (addr array byte) = lookup(v->register) -14157 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax -14158 # var target/eax: (addr var) = find-register(fn-outputs, reg) -14159 (find-register *(ebp+0x10) %eax) # => eax -14160 # if (target == 0) return true -14161 { -14162 3d/compare-eax-and 0/imm32 +13888 # var v2/eax: (addr v) = lookup(expected->value) +13889 (lookup *edx *(edx+4)) # List-value List-value => eax +13890 # var t2/eax: (addr type-tree) = lookup(v2->type) +13891 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +13892 # if (t != t2) error +13893 (type-match? %eax %ebx *(ebp-4)) # => eax +13894 3d/compare-eax-and 0/imm32/false +13895 { +13896 0f 85/jump-if-!= break/disp32 +13897 (write-buffered *(ebp+0x14) "fn ") +13898 8b/-> *(ebp+0x10) 0/r32/eax +13899 (lookup *eax *(eax+4)) # Function-name Function-name => eax +13900 (write-buffered *(ebp+0x14) %eax) +13901 (write-buffered *(ebp+0x14) ": call ") +13902 (lookup *edi *(edi+4)) # Function-name Function-name => eax +13903 (write-buffered *(ebp+0x14) %eax) +13904 (write-buffered *(ebp+0x14) ": type for inout '") +13905 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax +13906 (lookup *eax *(eax+4)) # Var-name Var-name => eax +13907 (write-buffered *(ebp+0x14) %eax) +13908 (write-buffered *(ebp+0x14) "' is not right\n") +13909 (flush *(ebp+0x14)) +13910 (stop *(ebp+0x18) 1) +13911 } +13912 $check-mu-call:continue-to-next-inout: +13913 # inouts = lookup(inouts->next) +13914 (lookup *(ecx+8) *(ecx+0xc)) # Stmt-var-next Stmt-var-next => eax +13915 89/<- %ecx 0/r32/eax +13916 # expected = lookup(expected->next) +13917 (lookup *(edx+8) *(edx+0xc)) # List-next List-next => eax +13918 89/<- %edx 0/r32/eax +13919 # +13920 e9/jump loop/disp32 +13921 } +13922 $check-mu-call:check-inout-count: +13923 # if (inouts == expected) proceed +13924 39/compare %ecx 2/r32/edx +13925 { +13926 0f 84/jump-if-= break/disp32 +13927 # exactly one of the two is null +13928 # if (inouts == 0) error("too many inouts") +13929 { +13930 81 7/subop/compare %ecx 0/imm32 +13931 0f 84/jump-if-= break/disp32 +13932 (write-buffered *(ebp+0x14) "fn ") +13933 8b/-> *(ebp+0x10) 0/r32/eax +13934 (lookup *eax *(eax+4)) # Function-name Function-name => eax +13935 (write-buffered *(ebp+0x14) %eax) +13936 (write-buffered *(ebp+0x14) ": call ") +13937 (lookup *edi *(edi+4)) # Function-name Function-name => eax +13938 (write-buffered *(ebp+0x14) %eax) +13939 (write-buffered *(ebp+0x14) ": too many inouts\n") +13940 (flush *(ebp+0x14)) +13941 (stop *(ebp+0x18) 1) +13942 } +13943 # if (expected == 0) error("too few inouts") +13944 { +13945 81 7/subop/compare %edx 0/imm32 +13946 0f 84/jump-if-= break/disp32 +13947 (write-buffered *(ebp+0x14) "fn ") +13948 8b/-> *(ebp+0x10) 0/r32/eax +13949 (lookup *eax *(eax+4)) # Function-name Function-name => eax +13950 (write-buffered *(ebp+0x14) %eax) +13951 (write-buffered *(ebp+0x14) ": call ") +13952 (lookup *edi *(edi+4)) # Function-name Function-name => eax +13953 (write-buffered *(ebp+0x14) %eax) +13954 (write-buffered *(ebp+0x14) ": too few inouts\n") +13955 (flush *(ebp+0x14)) +13956 (stop *(ebp+0x18) 1) +13957 } +13958 } +13959 $check-mu-call:check-outputs: +13960 # var outputs/ecx: (addr stmt-var) = lookup(stmt->outputs) +13961 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax +13962 89/<- %ecx 0/r32/eax +13963 # var expected/edx: (addr list var) = lookup(f->outputs) +13964 (lookup *(edi+0x10) *(edi+0x14)) # Function-outputs Function-outputs => eax +13965 89/<- %edx 0/r32/eax +13966 { +13967 $check-mu-call:check-for-outputs: +13968 # if (outputs == 0) break +13969 81 7/subop/compare %ecx 0/imm32 +13970 0f 84/jump-if-= break/disp32 +13971 # if (expected == 0) error +13972 81 7/subop/compare %edx 0/imm32 +13973 0f 84/jump-if-= break/disp32 +13974 $check-mu-call:check-output-type: +13975 # var v/eax: (addr v) = lookup(outputs->value) +13976 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax +13977 # var t/ebx: (addr type-tree) = lookup(v->type) +13978 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +13979 89/<- %ebx 0/r32/eax +13980 # if (outputs->is-deref?) t = t->right # TODO: check that t->left is an addr +13981 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref +13982 { +13983 74/jump-if-= break/disp8 +13984 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax +13985 89/<- %ebx 0/r32/eax +13986 } +13987 # var v2/eax: (addr v) = lookup(expected->value) +13988 (lookup *edx *(edx+4)) # List-value List-value => eax +13989 # var t2/eax: (addr type-tree) = lookup(v2->type) +13990 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +13991 # if (t != t2) error +13992 (type-match? %eax %ebx *(ebp-4)) # => eax +13993 3d/compare-eax-and 0/imm32/false +13994 { +13995 0f 85/jump-if-!= break/disp32 +13996 (write-buffered *(ebp+0x14) "fn ") +13997 8b/-> *(ebp+0x10) 0/r32/eax +13998 (lookup *eax *(eax+4)) # Function-name Function-name => eax +13999 (write-buffered *(ebp+0x14) %eax) +14000 (write-buffered *(ebp+0x14) ": call ") +14001 (lookup *edi *(edi+4)) # Function-name Function-name => eax +14002 (write-buffered *(ebp+0x14) %eax) +14003 (write-buffered *(ebp+0x14) ": type for output '") +14004 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax +14005 (lookup *eax *(eax+4)) # Var-name Var-name => eax +14006 (write-buffered *(ebp+0x14) %eax) +14007 (write-buffered *(ebp+0x14) "' is not right\n") +14008 (flush *(ebp+0x14)) +14009 (stop *(ebp+0x18) 1) +14010 } +14011 $check-mu-call:check-output-register: +14012 # var v/eax: (addr v) = lookup(outputs->value) +14013 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax +14014 # var r/ebx: (addr array byte) = lookup(v->register) +14015 (lookup *(eax+18) *(eax+0x1c)) # Var-register Var-register => eax +14016 89/<- %ebx 0/r32/eax +14017 # var v2/eax: (addr v) = lookup(expected->value) +14018 (lookup *edx *(edx+4)) # Stmt-var-value Stmt-var-value => eax +14019 # var r2/eax: (addr array byte) = lookup(v2->register) +14020 (lookup *(eax+18) *(eax+0x1c)) # Var-register Var-register => eax +14021 # if (r != r2) error +14022 (string-equal? %eax %ebx) # => eax +14023 3d/compare-eax-and 0/imm32/false +14024 { +14025 0f 85/jump-if-!= break/disp32 +14026 (write-buffered *(ebp+0x14) "fn ") +14027 8b/-> *(ebp+0x10) 0/r32/eax +14028 (lookup *eax *(eax+4)) # Function-name Function-name => eax +14029 (write-buffered *(ebp+0x14) %eax) +14030 (write-buffered *(ebp+0x14) ": call ") +14031 (lookup *edi *(edi+4)) # Function-name Function-name => eax +14032 (write-buffered *(ebp+0x14) %eax) +14033 (write-buffered *(ebp+0x14) ": register for output '") +14034 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax +14035 (lookup *eax *(eax+4)) # Var-name Var-name => eax +14036 (write-buffered *(ebp+0x14) %eax) +14037 (write-buffered *(ebp+0x14) "' is not right\n") +14038 (flush *(ebp+0x14)) +14039 (stop *(ebp+0x18) 1) +14040 } +14041 $check-mu-call:continue-to-next-output: +14042 # outputs = lookup(outputs->next) +14043 (lookup *(ecx+8) *(ecx+0xc)) # Stmt-var-next Stmt-var-next => eax +14044 89/<- %ecx 0/r32/eax +14045 # expected = lookup(expected->next) +14046 (lookup *(edx+8) *(edx+0xc)) # List-next List-next => eax +14047 89/<- %edx 0/r32/eax +14048 # +14049 e9/jump loop/disp32 +14050 } +14051 $check-mu-call:check-output-count: +14052 # if (outputs == expected) proceed +14053 39/compare %ecx 2/r32/edx +14054 { +14055 0f 84/jump-if-= break/disp32 +14056 # exactly one of the two is null +14057 # if (outputs == 0) error("too many outputs") +14058 { +14059 81 7/subop/compare %ecx 0/imm32 +14060 0f 84/jump-if-= break/disp32 +14061 (write-buffered *(ebp+0x14) "fn ") +14062 8b/-> *(ebp+0x10) 0/r32/eax +14063 (lookup *eax *(eax+4)) # Function-name Function-name => eax +14064 (write-buffered *(ebp+0x14) %eax) +14065 (write-buffered *(ebp+0x14) ": call ") +14066 (lookup *edi *(edi+4)) # Function-name Function-name => eax +14067 (write-buffered *(ebp+0x14) %eax) +14068 (write-buffered *(ebp+0x14) ": too many outputs\n") +14069 (flush *(ebp+0x14)) +14070 (stop *(ebp+0x18) 1) +14071 } +14072 # if (expected == 0) error("too few outputs") +14073 { +14074 81 7/subop/compare %edx 0/imm32 +14075 0f 84/jump-if-= break/disp32 +14076 (write-buffered *(ebp+0x14) "fn ") +14077 8b/-> *(ebp+0x10) 0/r32/eax +14078 (lookup *eax *(eax+4)) # Function-name Function-name => eax +14079 (write-buffered *(ebp+0x14) %eax) +14080 (write-buffered *(ebp+0x14) ": call ") +14081 (lookup *edi *(edi+4)) # Function-name Function-name => eax +14082 (write-buffered *(ebp+0x14) %eax) +14083 (write-buffered *(ebp+0x14) ": too few outputs\n") +14084 (flush *(ebp+0x14)) +14085 (stop *(ebp+0x18) 1) +14086 } +14087 } +14088 $check-mu-call:end: +14089 # . restore registers +14090 5f/pop-to-edi +14091 5e/pop-to-esi +14092 5b/pop-to-ebx +14093 5a/pop-to-edx +14094 59/pop-to-ecx +14095 58/pop-to-eax +14096 # . reclaim locals exclusively on the stack +14097 81 0/subop/add %esp 0x70/imm32 +14098 # . epilogue +14099 89/<- %esp 5/r32/ebp +14100 5d/pop-to-ebp +14101 c3/return +14102 +14103 # like type-equal? but takes literals into account +14104 type-match?: # def: (addr type-tree), call: (addr type-tree), type-parameters: (addr table (handle array byte) (addr type-tree)) -> result/eax: boolean +14105 # . prologue +14106 55/push-ebp +14107 89/<- %ebp 4/r32/esp +14108 # if (call == literal) return true # TODO: more precise +14109 (is-simple-mu-type? *(ebp+0xc) 0) # literal => eax +14110 3d/compare-eax-and 0/imm32/false +14111 b8/copy-to-eax 1/imm32/true +14112 75/jump-if-!= $type-match?:end/disp8 +14113 $type-match?:baseline: +14114 # otherwise fall back +14115 (type-component-match? *(ebp+8) *(ebp+0xc) *(ebp+0x10)) # => eax +14116 $type-match?:end: +14117 # . epilogue +14118 89/<- %esp 5/r32/ebp +14119 5d/pop-to-ebp +14120 c3/return +14121 +14122 type-component-match?: # def: (addr type-tree), call: (addr type-tree), type-parameters: (addr table (handle array byte) (addr type-tree)) -> result/eax: boolean +14123 # . prologue +14124 55/push-ebp +14125 89/<- %ebp 4/r32/esp +14126 # . save registers +14127 51/push-ecx +14128 52/push-edx +14129 53/push-ebx +14130 # ecx = def +14131 8b/-> *(ebp+8) 1/r32/ecx +14132 # edx = call +14133 8b/-> *(ebp+0xc) 2/r32/edx +14134 $type-component-match?:compare-addr: +14135 # if (def == call) return true +14136 8b/-> %ecx 0/r32/eax # Var-type +14137 39/compare %edx 0/r32/eax # Var-type +14138 b8/copy-to-eax 1/imm32/true +14139 0f 84/jump-if-= $type-component-match?:end/disp32 +14140 # if (def == 0) return false +14141 b8/copy-to-eax 0/imm32/false +14142 81 7/subop/compare %ecx 0/imm32 # Type-tree-is-atom +14143 0f 84/jump-if-= $type-component-match?:end/disp32 +14144 # if (call == 0) return false +14145 81 7/subop/compare %edx 0/imm32 # Type-tree-is-atom +14146 0f 84/jump-if-= $type-component-match?:end/disp32 +14147 # if def is a type parameter, just check in type-parameters +14148 { +14149 $type-component-match?:check-type-parameter: +14150 81 7/subop/compare *ecx 0/imm32/false # Type-tree-is-atom +14151 74/jump-if-= break/disp8 +14152 81 7/subop/compare *(ecx+4) 0xa/imm32/type-parameter # Type-tree-value +14153 75/jump-if-!= break/disp8 +14154 $type-component-match?:type-parameter: +14155 (type-parameter-match? *(ecx+8) *(ecx+0xc) %edx *(ebp+0x10)) # => eax +14156 e9/jump $type-component-match?:end/disp32 +14157 } +14158 # if def is a list containing just a type parameter, just check in type-parameters +14159 { +14160 $type-component-match?:check-list-type-parameter: +14161 # if def is a list.. +14162 81 7/subop/compare *ecx 0/imm32/false # Type-tree-is-atom 14163 75/jump-if-!= break/disp8 -14164 b8/copy-to-eax 1/imm32/true -14165 eb/jump $will-not-write-some-register?:end/disp8 -14166 } -14167 # return !assigns-in-stmts?(stmts, target) -14168 (assigns-in-stmts? *(ebp+0xc) %eax) # => eax -14169 3d/compare-eax-and 0/imm32/false -14170 # assume: true = 1, so no need to mask with 0x000000ff -14171 0f 94/set-if-= %al -14172 $will-not-write-some-register?:end: -14173 # . epilogue -14174 89/<- %esp 5/r32/ebp -14175 5d/pop-to-ebp -14176 c3/return -14177 -14178 # return fn output with matching register -14179 # always returns false if 'reg' is null -14180 find-register: # fn: (addr function), reg: (addr array byte) -> result/eax: (addr var) -14181 # . prologue -14182 55/push-ebp -14183 89/<- %ebp 4/r32/esp -14184 # . save registers -14185 51/push-ecx -14186 # var curr/ecx: (addr list var) = lookup(fn->outputs) -14187 8b/-> *(ebp+8) 1/r32/ecx -14188 (lookup *(ecx+0x10) *(ecx+0x14)) # Function-outputs Function-outputs => eax -14189 89/<- %ecx 0/r32/eax -14190 { -14191 $find-register:loop: -14192 # if (curr == 0) break -14193 81 7/subop/compare %ecx 0/imm32 -14194 74/jump-if-= break/disp8 -14195 # eax = curr->value->register -14196 (lookup *ecx *(ecx+4)) # List-value List-value => eax -14197 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax -14198 # if (eax == reg) return curr->value -14199 $find-register:compare: -14200 (string-equal? *(ebp+0xc) %eax) # => eax -14201 { -14202 3d/compare-eax-and 0/imm32/false -14203 74/jump-if-= break/disp8 -14204 $find-register:found: -14205 (lookup *ecx *(ecx+4)) # List-value List-value => eax -14206 eb/jump $find-register:end/disp8 -14207 } -14208 # curr = lookup(curr->next) -14209 (lookup *(ecx+8) *(ecx+0xc)) # List-next List-next => eax -14210 89/<- %ecx 0/r32/eax -14211 # -14212 eb/jump loop/disp8 -14213 } -14214 $find-register:end: -14215 # . restore registers -14216 59/pop-to-ecx -14217 # . epilogue -14218 89/<- %esp 5/r32/ebp -14219 5d/pop-to-ebp -14220 c3/return -14221 -14222 assigns-in-stmts?: # stmts: (addr list stmt), v: (addr var) -> result/eax: boolean -14223 # . prologue -14224 55/push-ebp -14225 89/<- %ebp 4/r32/esp -14226 # . save registers -14227 51/push-ecx -14228 # var curr/ecx: (addr list stmt) = stmts -14229 8b/-> *(ebp+8) 1/r32/ecx -14230 { -14231 # if (curr == 0) break -14232 81 7/subop/compare %ecx 0/imm32 -14233 74/jump-if-= break/disp8 -14234 # if assigns-in-stmt?(curr->value, v) return true -14235 (lookup *ecx *(ecx+4)) # List-value List-value => eax -14236 (assigns-in-stmt? %eax *(ebp+0xc)) # => eax -14237 3d/compare-eax-and 0/imm32/false -14238 75/jump-if-!= break/disp8 -14239 # curr = lookup(curr->next) -14240 (lookup *(ecx+8) *(ecx+0xc)) # List-next List-next => eax -14241 89/<- %ecx 0/r32/eax -14242 # -14243 eb/jump loop/disp8 -14244 } -14245 $assigns-in-stmts?:end: -14246 # . restore registers -14247 59/pop-to-ecx -14248 # . epilogue -14249 89/<- %esp 5/r32/ebp -14250 5d/pop-to-ebp -14251 c3/return -14252 -14253 assigns-in-stmt?: # stmt: (addr stmt), v: (addr var) -> result/eax: boolean -14254 # . prologue -14255 55/push-ebp -14256 89/<- %ebp 4/r32/esp -14257 # . save registers -14258 51/push-ecx -14259 # ecx = stmt -14260 8b/-> *(ebp+8) 1/r32/ecx -14261 # if stmt is a stmt1, return assigns-in-stmt-vars?(stmt->outputs, v) +14164 # ..that's a singleton +14165 81 7/subop/compare *(ecx+0xc) 0/imm32 # Type-tree-left +14166 75/jump-if-!= break/disp8 +14167 # ..and whose head is a type parameter +14168 (lookup *(ecx+4) *(ecx+8)) # Type-tree-left Type-tree-left => eax +14169 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom +14170 74/jump-if-= break/disp8 +14171 81 7/subop/compare *(eax+4) 0xa/imm32/type-parameter # Type-tree-value +14172 75/jump-if-!= break/disp8 +14173 $type-component-match?:list-type-parameter: +14174 (type-parameter-match? *(eax+8) *(eax+0xc) %edx *(ebp+0x10)) # => eax +14175 e9/jump $type-component-match?:end/disp32 +14176 } +14177 $type-component-match?:compare-atom-state: +14178 # if (def->is-atom? != call->is-atom?) return false +14179 8b/-> *ecx 3/r32/ebx # Type-tree-is-atom +14180 39/compare *edx 3/r32/ebx # Type-tree-is-atom +14181 b8/copy-to-eax 0/imm32/false +14182 0f 85/jump-if-!= $type-component-match?:end/disp32 +14183 # if def->is-atom? return (def->value == call->value) +14184 { +14185 $type-component-match?:check-atom: +14186 81 7/subop/compare %ebx 0/imm32/false +14187 74/jump-if-= break/disp8 +14188 $type-component-match?:is-atom: +14189 8b/-> *(ecx+4) 0/r32/eax # Type-tree-value +14190 39/compare *(edx+4) 0/r32/eax # Type-tree-value +14191 0f 94/set-if-= %al +14192 81 4/subop/and %eax 0xff/imm32 +14193 e9/jump $type-component-match?:end/disp32 +14194 } +14195 $type-component-match?:check-left: +14196 # if (!type-component-match?(def->left, call->left)) return false +14197 (lookup *(ecx+4) *(ecx+8)) # Type-tree-left Type-tree-left => eax +14198 89/<- %ebx 0/r32/eax +14199 (lookup *(edx+4) *(edx+8)) # Type-tree-left Type-tree-left => eax +14200 (type-component-match? %ebx %eax *(ebp+0x10)) # => eax +14201 3d/compare-eax-and 0/imm32/false +14202 74/jump-if-= $type-component-match?:end/disp8 +14203 $type-component-match?:check-right: +14204 # return type-component-match?(def->right, call->right) +14205 (lookup *(ecx+0xc) *(ecx+0x10)) # Type-tree-right Type-tree-right => eax +14206 89/<- %ebx 0/r32/eax +14207 (lookup *(edx+0xc) *(edx+0x10)) # Type-tree-right Type-tree-right => eax +14208 (type-component-match? %ebx %eax *(ebp+0x10)) # => eax +14209 $type-component-match?:end: +14210 # . restore registers +14211 5b/pop-to-ebx +14212 5a/pop-to-edx +14213 59/pop-to-ecx +14214 # . epilogue +14215 89/<- %esp 5/r32/ebp +14216 5d/pop-to-ebp +14217 c3/return +14218 +14219 type-parameter-match?: # type-parameter-name: (handle array byte), type: (addr type-tree), type-parameters: (addr table (handle array byte) (addr type-tree)) -> result/eax: boolean +14220 # . prologue +14221 55/push-ebp +14222 89/<- %ebp 4/r32/esp +14223 # . save registers +14224 51/push-ecx +14225 # +14226 (get-or-insert-handle *(ebp+0x14) *(ebp+8) *(ebp+0xc) 0xc) # => eax +14227 # if parameter wasn't saved, save it +14228 { +14229 81 7/subop/compare *eax 0/imm32 +14230 75/jump-if-!= break/disp8 +14231 8b/-> *(ebp+0x10) 1/r32/ecx +14232 89/<- *eax 1/r32/ecx +14233 } +14234 # +14235 (type-equal? *(ebp+0x10) *eax) # => eax +14236 $type-parameter-match?:end: +14237 # . restore registers +14238 59/pop-to-ecx +14239 # . epilogue +14240 89/<- %esp 5/r32/ebp +14241 5d/pop-to-ebp +14242 c3/return +14243 +14244 size-of: # v: (addr var) -> result/eax: int +14245 # . prologue +14246 55/push-ebp +14247 89/<- %ebp 4/r32/esp +14248 # . save registers +14249 51/push-ecx +14250 # var t/ecx: (addr type-tree) = lookup(v->type) +14251 8b/-> *(ebp+8) 1/r32/ecx +14252 #? (write-buffered Stderr "size-of ") +14253 #? (write-int32-hex-buffered Stderr %ecx) +14254 #? (write-buffered Stderr Newline) +14255 #? (write-buffered Stderr "type allocid: ") +14256 #? (write-int32-hex-buffered Stderr *(ecx+8)) +14257 #? (write-buffered Stderr Newline) +14258 #? (flush Stderr) +14259 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax +14260 89/<- %ecx 0/r32/eax +14261 # if is-mu-array?(t) return size-of-array(t) 14262 { -14263 81 7/subop/compare *ecx 1/imm32/stmt1 # Stmt-tag -14264 75/jump-if-!= break/disp8 -14265 (lookup *(ecx+0x14) *(ecx+0x18)) # Stmt1-outputs Stmt1-outputs => eax -14266 (assigns-in-stmt-vars? %eax *(ebp+0xc)) # => eax -14267 eb/jump $assigns-in-stmt?:end/disp8 +14263 (is-mu-array? %ecx) # => eax +14264 3d/compare-eax-and 0/imm32/false +14265 74/jump-if-= break/disp8 +14266 (size-of-array %ecx) # => eax +14267 eb/jump $size-of:end/disp8 14268 } -14269 # if stmt is a block, return assigns-in-stmts?(stmt->stmts, v) +14269 # if is-mu-stream?(t) return size-of-stream(t) 14270 { -14271 81 7/subop/compare *ecx 0/imm32/block # Stmt-tag -14272 75/jump-if-!= break/disp8 -14273 (lookup *(ecx+4) *(ecx+8)) # Block-stmts Block-stmts => eax -14274 (assigns-in-stmts? %eax *(ebp+0xc)) # => eax -14275 eb/jump $assigns-in-stmt?:end/disp8 +14271 (is-mu-stream? %ecx) # => eax +14272 3d/compare-eax-and 0/imm32/false +14273 74/jump-if-= break/disp8 +14274 (size-of-stream %ecx) # => eax +14275 eb/jump $size-of:end/disp8 14276 } -14277 # otherwise return false -14278 b8/copy 0/imm32/false -14279 $assigns-in-stmt?:end: -14280 # . restore registers -14281 59/pop-to-ecx -14282 # . epilogue -14283 89/<- %esp 5/r32/ebp -14284 5d/pop-to-ebp -14285 c3/return -14286 -14287 assigns-in-stmt-vars?: # stmt-var: (addr stmt-var), v: (addr var) -> result/eax: boolean -14288 # . prologue -14289 55/push-ebp -14290 89/<- %ebp 4/r32/esp -14291 # . save registers -14292 51/push-ecx -14293 # var curr/ecx: (addr stmt-var) = stmt-var -14294 8b/-> *(ebp+8) 1/r32/ecx -14295 { -14296 # if (curr == 0) break -14297 81 7/subop/compare %ecx 0/imm32 -14298 74/jump-if-= break/disp8 -14299 # eax = lookup(curr->value) -14300 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax -14301 # if (eax == v && curr->is-deref? == false) return true -14302 { -14303 39/compare *(ebp+0xc) 0/r32/eax -14304 75/jump-if-!= break/disp8 -14305 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref -14306 75/jump-if-!= break/disp8 -14307 b8/copy-to-eax 1/imm32/true -14308 eb/jump $assigns-in-stmt-vars?:end/disp8 -14309 } -14310 # curr = lookup(curr->next) -14311 (lookup *(ecx+8) *(ecx+0xc)) # Stmt-var-next Stmt-var-next => eax -14312 89/<- %ecx 0/r32/eax -14313 # -14314 eb/jump loop/disp8 +14277 # if (!t->is-atom?) t = lookup(t->left) +14278 { +14279 81 7/subop/compare *ecx 0/imm32/false # Type-tree-is-atom +14280 75/jump-if-!= break/disp8 +14281 (lookup *(ecx+4) *(ecx+8)) # Type-tree-left Type-tree-left => eax +14282 89/<- %ecx 0/r32/eax +14283 } +14284 # TODO: assert t->is-atom? +14285 (size-of-type-id *(ecx+4)) # Type-tree-value => eax +14286 $size-of:end: +14287 # . restore registers +14288 59/pop-to-ecx +14289 # . epilogue +14290 89/<- %esp 5/r32/ebp +14291 5d/pop-to-ebp +14292 c3/return +14293 +14294 size-of-deref: # v: (addr var) -> result/eax: int +14295 # . prologue +14296 55/push-ebp +14297 89/<- %ebp 4/r32/esp +14298 # . save registers +14299 51/push-ecx +14300 # var t/ecx: (addr type-tree) = lookup(v->type) +14301 8b/-> *(ebp+8) 1/r32/ecx +14302 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax +14303 89/<- %ecx 0/r32/eax +14304 # TODO: assert(t is an addr) +14305 # t = lookup(t->right) +14306 (lookup *(ecx+0xc) *(ecx+0x10)) # Type-tree-right Type-tree-right => eax +14307 89/<- %ecx 0/r32/eax +14308 # if is-mu-array?(t) return size-of-array(t) +14309 { +14310 (is-mu-array? %ecx) # => eax +14311 3d/compare-eax-and 0/imm32/false +14312 74/jump-if-= break/disp8 +14313 (size-of-array %ecx) # => eax +14314 eb/jump $size-of-deref:end/disp8 14315 } -14316 $assigns-in-stmt-vars?:end: -14317 # . restore registers -14318 59/pop-to-ecx -14319 # . epilogue -14320 89/<- %esp 5/r32/ebp -14321 5d/pop-to-ebp -14322 c3/return -14323 -14324 # is there a var before 'v' with the same block-depth and register on the 'vars' stack? -14325 # v is guaranteed to be within vars -14326 # 'start' is provided as an optimization, a pointer within vars -14327 # *start == v -14328 same-register-spilled-before?: # v: (addr var), vars: (addr stack (handle var)), start: (addr var) -> result/eax: boolean -14329 # . prologue -14330 55/push-ebp -14331 89/<- %ebp 4/r32/esp -14332 # . save registers -14333 51/push-ecx -14334 52/push-edx -14335 53/push-ebx -14336 56/push-esi -14337 57/push-edi -14338 # ecx = v -14339 8b/-> *(ebp+8) 1/r32/ecx -14340 # var reg/edx: (addr array byte) = lookup(v->register) -14341 (lookup *(ecx+0x18) *(ecx+0x1c)) # Var-register Var-register => eax -14342 89/<- %edx 0/r32/eax -14343 # var depth/ebx: int = v->block-depth -14344 8b/-> *(ecx+0x10) 3/r32/ebx # Var-block-depth -14345 # var min/ecx: (addr handle var) = vars->data -14346 8b/-> *(ebp+0xc) 1/r32/ecx -14347 81 0/subop/add %ecx 8/imm32 -14348 # TODO: check that start >= min and start < &vars->data[top] -14349 # TODO: check that *start == v -14350 # var curr/esi: (addr handle var) = start -14351 8b/-> *(ebp+0x10) 6/r32/esi -14352 # curr -= 8 -14353 81 5/subop/subtract %esi 8/imm32 -14354 { -14355 $same-register-spilled-before?:loop: -14356 # if (curr < min) break -14357 39/compare %esi 1/r32/ecx -14358 0f 82/jump-if-addr< break/disp32 -14359 # var x/eax: (addr var) = lookup(*curr) -14360 (lookup *esi *(esi+4)) # => eax -14361 # if (x->block-depth < depth) break -14362 39/compare *(eax+0x10) 3/r32/ebx # Var-block-depth -14363 0f 8c/jump-if-< break/disp32 -14364 # if (x->register == 0) continue -14365 81 7/subop/compare *(eax+0x18) 0/imm32 # Var-register -14366 74/jump-if-= $same-register-spilled-before?:continue/disp8 -14367 # if (x->register == reg) return true -14368 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax -14369 (string-equal? %eax %edx) # => eax -14370 3d/compare-eax-and 0/imm32/false -14371 b8/copy-to-eax 1/imm32/true -14372 75/jump-if-!= $same-register-spilled-before?:end/disp8 -14373 $same-register-spilled-before?:continue: -14374 # curr -= 8 -14375 81 5/subop/subtract %esi 8/imm32 -14376 e9/jump loop/disp32 -14377 } -14378 $same-register-spilled-before?:false: -14379 b8/copy-to-eax 0/imm32/false -14380 $same-register-spilled-before?:end: -14381 # . restore registers -14382 5f/pop-to-edi -14383 5e/pop-to-esi -14384 5b/pop-to-ebx -14385 5a/pop-to-edx -14386 59/pop-to-ecx -14387 # . epilogue -14388 89/<- %esp 5/r32/ebp -14389 5d/pop-to-ebp -14390 c3/return -14391 -14392 # Clean up global state for 'vars' until some block depth (inclusive). -14393 # -14394 # This would be a simple series of pops, if it wasn't for fn outputs, which -14395 # can occur anywhere in the stack. -14396 # So we have to _compact_ the entire array underlying the stack. -14397 # -14398 # We want to allow a fn output register to be written to by locals before the -14399 # output is set. -14400 # So fn outputs can't just be pushed at the start of the function. -14401 # -14402 # We want to allow other locals to shadow a fn output register after the -14403 # output is set. -14404 # So the output can't just always override anything in the stack. Sequence matters. -14405 clean-up-blocks: # vars: (addr stack live-var), until-block-depth: int, fn: (addr function) -14406 # pseudocode: -14407 # to = vars->top (which points outside the stack) -14408 # while true -14409 # if to <= 0 -14410 # break -14411 # var v = vars->data[to-1] -14412 # if v.depth < until and !in-function-outputs?(fn, v) -14413 # break -14414 # --to -14415 # from = to -14416 # while true -14417 # if from >= vars->top -14418 # break -14419 # assert(from >= to) -14420 # v = vars->data[from] -14421 # if in-function-outputs?(fn, v) -14422 # if from > to -14423 # vars->data[to] = vars->data[from] -14424 # ++to -14425 # ++from -14426 # vars->top = to -14427 # -14428 # . prologue -14429 55/push-ebp -14430 89/<- %ebp 4/r32/esp -14431 # . save registers -14432 50/push-eax -14433 52/push-edx -14434 53/push-ebx -14435 56/push-esi -14436 57/push-edi -14437 # ebx = vars -14438 8b/-> *(ebp+8) 3/r32/ebx -14439 # edx = until-block-depth -14440 8b/-> *(ebp+0xc) 2/r32/edx -14441 $clean-up-blocks:phase1: -14442 # var to/edi: int = vars->top -14443 8b/-> *ebx 7/r32/edi -14444 { -14445 $clean-up-blocks:loop1: -14446 # if (to <= 0) break -14447 81 7/subop/compare %edi 0/imm32 -14448 7e/jump-if-<= break/disp8 -14449 # var v/eax: (addr var) = lookup(vars->data[to-1]->var) -14450 8d/copy-address *(ebx+edi-4) 0/r32/eax # vars + 8 + to - 12 -14451 (lookup *eax *(eax+4)) # => eax -14452 # if (v->block-depth >= until-block-depth) continue -14453 39/compare *(eax+0x10) 2/r32/edx # Var-block-depth -14454 { -14455 7d/jump-if->= break/disp8 -14456 # if (!in-function-outputs?(fn, v)) break -14457 (in-function-outputs? *(ebp+0x10) %eax) # => eax -14458 3d/compare-eax-and 0/imm32/false -14459 74/jump-if-= $clean-up-blocks:phase2/disp8 -14460 } -14461 $clean-up-blocks:loop1-continue: -14462 # --to -14463 81 5/subop/subtract %edi 0xc/imm32 -14464 # -14465 eb/jump loop/disp8 -14466 } -14467 $clean-up-blocks:phase2: -14468 # var from/esi: int = to -14469 89/<- %esi 7/r32/edi -14470 { -14471 $clean-up-blocks:loop2: -14472 # if (from >= vars->top) break -14473 3b/compare 6/r32/esi *ebx -14474 7d/jump-if->= break/disp8 -14475 # var v/eax: (addr var) = lookup(vars->data[from]->var) -14476 8d/copy-address *(ebx+esi+8) 0/r32/eax -14477 (lookup *eax *(eax+4)) # => eax -14478 # if !in-function-outputs?(fn, v) continue -14479 (in-function-outputs? *(ebp+0x10) %eax) # => eax -14480 3d/compare-eax-and 0/imm32/false -14481 74/jump-if-= $clean-up-blocks:loop2-continue/disp8 -14482 # invariant: from >= to -14483 # if (from > to) vars->data[to] = vars->data[from] -14484 { -14485 39/compare %esi 7/r32/edi -14486 7e/jump-if-<= break/disp8 -14487 56/push-esi -14488 57/push-edi -14489 # . var from/esi: (addr byte) = &vars->data[from] -14490 8d/copy-address *(ebx+esi+8) 6/r32/esi -14491 # . var to/edi: (addr byte) = &vars->data[to] -14492 8d/copy-address *(ebx+edi+8) 7/r32/edi -14493 # . -14494 8b/-> *esi 0/r32/eax -14495 89/<- *edi 0/r32/eax -14496 8b/-> *(esi+4) 0/r32/eax -14497 89/<- *(edi+4) 0/r32/eax -14498 8b/-> *(esi+8) 0/r32/eax -14499 89/<- *(edi+8) 0/r32/eax -14500 5f/pop-to-edi -14501 5e/pop-to-esi -14502 } -14503 # ++to -14504 81 0/subop/add %edi 0xc/imm32 -14505 $clean-up-blocks:loop2-continue: -14506 # ++from -14507 81 0/subop/add %esi 0xc/imm32 -14508 # -14509 eb/jump loop/disp8 -14510 } -14511 89/<- *ebx 7/r32/edi -14512 $clean-up-blocks:end: -14513 # . restore registers -14514 5f/pop-to-edi -14515 5e/pop-to-esi -14516 5b/pop-to-ebx -14517 5a/pop-to-edx -14518 58/pop-to-eax -14519 # . epilogue -14520 89/<- %esp 5/r32/ebp -14521 5d/pop-to-ebp -14522 c3/return -14523 -14524 in-function-outputs?: # fn: (addr function), target: (addr var) -> result/eax: boolean -14525 # . prologue -14526 55/push-ebp -14527 89/<- %ebp 4/r32/esp -14528 # . save registers -14529 51/push-ecx -14530 # var curr/ecx: (addr list var) = lookup(fn->outputs) -14531 8b/-> *(ebp+8) 1/r32/ecx -14532 (lookup *(ecx+0x10) *(ecx+0x14)) # Function-outputs Function-outputs => eax -14533 89/<- %ecx 0/r32/eax -14534 # while curr != null -14535 { -14536 81 7/subop/compare %ecx 0/imm32 -14537 74/jump-if-= break/disp8 -14538 # var v/eax: (addr var) = lookup(curr->value) -14539 (lookup *ecx *(ecx+4)) # List-value List-value => eax -14540 # if (v == target) return true -14541 39/compare *(ebp+0xc) 0/r32/eax -14542 b8/copy-to-eax 1/imm32/true -14543 74/jump-if-= $in-function-outputs?:end/disp8 -14544 # curr = curr->next -14545 (lookup *(ecx+8) *(ecx+0xc)) # List-next List-next => eax -14546 89/<- %ecx 0/r32/eax -14547 # -14548 eb/jump loop/disp8 -14549 } -14550 b8/copy-to-eax 0/imm32 -14551 $in-function-outputs?:end: -14552 # . restore registers -14553 59/pop-to-ecx -14554 # . epilogue -14555 89/<- %esp 5/r32/ebp -14556 5d/pop-to-ebp -14557 c3/return -14558 -14559 emit-subx-var-def: # out: (addr buffered-file), stmt: (addr stmt) -14560 # . prologue -14561 55/push-ebp -14562 89/<- %ebp 4/r32/esp -14563 # . save registers -14564 50/push-eax -14565 51/push-ecx -14566 52/push-edx -14567 # eax = stmt -14568 8b/-> *(ebp+0xc) 0/r32/eax -14569 # var v/ecx: (addr var) -14570 (lookup *(eax+4) *(eax+8)) # Vardef-var Vardef-var => eax -14571 89/<- %ecx 0/r32/eax -14572 # v->block-depth = *Curr-block-depth -14573 8b/-> *Curr-block-depth 0/r32/eax -14574 89/<- *(ecx+0x10) 0/r32/eax # Var-block-depth -14575 # var n/edx: int = size-of(stmt->var) -14576 (size-of %ecx) # => eax -14577 89/<- %edx 0/r32/eax -14578 # *Curr-local-stack-offset -= n -14579 29/subtract-from *Curr-local-stack-offset 2/r32/edx -14580 # v->offset = *Curr-local-stack-offset -14581 8b/-> *Curr-local-stack-offset 0/r32/eax -14582 89/<- *(ecx+0x14) 0/r32/eax # Var-offset -14583 # if v is an array, do something special to initialize it -14584 { -14585 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax -14586 (is-mu-array? %eax) # => eax -14587 3d/compare-eax-and 0/imm32/false -14588 0f 84/jump-if-= break/disp32 -14589 # var array-size-without-size/edx: int = n-4 -14590 81 5/subop/subtract %edx 4/imm32 -14591 # -14592 (emit-array-data-initialization *(ebp+8) %edx) -14593 e9/jump $emit-subx-var-def:end/disp32 -14594 } -14595 # another special-case for initializing streams -14596 # a stream is an array with 2 extra pointers +14316 # if is-mu-stream?(t) return size-of-stream(t) +14317 { +14318 (is-mu-stream? %ecx) # => eax +14319 3d/compare-eax-and 0/imm32/false +14320 74/jump-if-= break/disp8 +14321 (size-of-stream %ecx) # => eax +14322 eb/jump $size-of-deref:end/disp8 +14323 } +14324 # if (!t->is-atom?) t = lookup(t->left) +14325 { +14326 81 7/subop/compare *ecx 0/imm32/false # Type-tree-is-atom +14327 75/jump-if-!= break/disp8 +14328 (lookup *(ecx+4) *(ecx+8)) # Type-tree-left Type-tree-left => eax +14329 89/<- %ecx 0/r32/eax +14330 } +14331 # TODO: assert t->is-atom? +14332 (size-of-type-id *(ecx+4)) # Type-tree-value => eax +14333 $size-of-deref:end: +14334 # . restore registers +14335 59/pop-to-ecx +14336 # . epilogue +14337 89/<- %esp 5/r32/ebp +14338 5d/pop-to-ebp +14339 c3/return +14340 +14341 is-mu-array?: # t: (addr type-tree) -> result/eax: boolean +14342 # . prologue +14343 55/push-ebp +14344 89/<- %ebp 4/r32/esp +14345 # . save registers +14346 51/push-ecx +14347 # ecx = t +14348 8b/-> *(ebp+8) 1/r32/ecx +14349 # if t->is-atom?, return false +14350 81 7/subop/compare *ecx 0/imm32/false # Type-tree-is-atom +14351 75/jump-if-!= $is-mu-array?:return-false/disp8 +14352 # if !t->left->is-atom?, return false +14353 (lookup *(ecx+4) *(ecx+8)) # Type-tree-left Type-tree-left => eax +14354 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom +14355 74/jump-if-= $is-mu-array?:return-false/disp8 +14356 # return t->left->value == array +14357 81 7/subop/compare *(eax+4) 3/imm32/array-type-id # Type-tree-value +14358 0f 94/set-if-= %al +14359 81 4/subop/and %eax 0xff/imm32 +14360 eb/jump $is-mu-array?:end/disp8 +14361 $is-mu-array?:return-false: +14362 b8/copy-to-eax 0/imm32/false +14363 $is-mu-array?:end: +14364 # . restore registers +14365 59/pop-to-ecx +14366 # . epilogue +14367 89/<- %esp 5/r32/ebp +14368 5d/pop-to-ebp +14369 c3/return +14370 +14371 # size of a statically allocated array where the size is part of the type expression +14372 size-of-array: # a: (addr type-tree) -> result/eax: int +14373 # . prologue +14374 55/push-ebp +14375 89/<- %ebp 4/r32/esp +14376 # . save registers +14377 51/push-ecx +14378 52/push-edx +14379 # +14380 8b/-> *(ebp+8) 1/r32/ecx +14381 # TODO: assert that a->left is 'array' +14382 (lookup *(ecx+0xc) *(ecx+0x10)) # Type-tree-right Type-tree-right => eax +14383 89/<- %ecx 0/r32/eax +14384 # var elem-type/edx: type-id = a->right->left->value +14385 (lookup *(ecx+4) *(ecx+8)) # Type-tree-left Type-tree-left => eax +14386 8b/-> *(eax+4) 2/r32/edx # Type-tree-value +14387 # TODO: assert that a->right->right->left->value == size +14388 # var array-size/ecx: int = a->right->right->left->value-size +14389 (lookup *(ecx+0xc) *(ecx+0x10)) # Type-tree-right Type-tree-right => eax +14390 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +14391 8b/-> *(eax+8) 1/r32/ecx # Type-tree-value-size +14392 # return 4 + array-size * size-of(elem-type) +14393 (size-of-type-id-as-array-element %edx) # => eax +14394 f7 4/subop/multiply-into-eax %ecx +14395 05/add-to-eax 4/imm32 # for array size +14396 $size-of-array:end: +14397 # . restore registers +14398 5a/pop-to-edx +14399 59/pop-to-ecx +14400 # . epilogue +14401 89/<- %esp 5/r32/ebp +14402 5d/pop-to-ebp +14403 c3/return +14404 +14405 is-mu-stream?: # t: (addr type-tree) -> result/eax: boolean +14406 # . prologue +14407 55/push-ebp +14408 89/<- %ebp 4/r32/esp +14409 # . save registers +14410 51/push-ecx +14411 # ecx = t +14412 8b/-> *(ebp+8) 1/r32/ecx +14413 # if t->is-atom?, return false +14414 81 7/subop/compare *ecx 0/imm32/false # Type-tree-is-atom +14415 75/jump-if-!= $is-mu-stream?:return-false/disp8 +14416 # if !t->left->is-atom?, return false +14417 (lookup *(ecx+4) *(ecx+8)) # Type-tree-left Type-tree-left => eax +14418 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom +14419 74/jump-if-= $is-mu-stream?:return-false/disp8 +14420 # return t->left->value == stream +14421 81 7/subop/compare *(eax+4) 0xb/imm32/stream-type-id # Type-tree-value +14422 0f 94/set-if-= %al +14423 81 4/subop/and %eax 0xff/imm32 +14424 eb/jump $is-mu-stream?:end/disp8 +14425 $is-mu-stream?:return-false: +14426 b8/copy-to-eax 0/imm32/false +14427 $is-mu-stream?:end: +14428 # . restore registers +14429 59/pop-to-ecx +14430 # . epilogue +14431 89/<- %esp 5/r32/ebp +14432 5d/pop-to-ebp +14433 c3/return +14434 +14435 # size of a statically allocated stream where the size is part of the type expression +14436 size-of-stream: # a: (addr type-tree) -> result/eax: int +14437 # . prologue +14438 55/push-ebp +14439 89/<- %ebp 4/r32/esp +14440 # +14441 (size-of-array *(ebp+8)) # assumes we ignore the actual type name 'array' in the type +14442 05/add-to-eax 8/imm32 # for read/write pointers +14443 $size-of-stream:end: +14444 # . epilogue +14445 89/<- %esp 5/r32/ebp +14446 5d/pop-to-ebp +14447 c3/return +14448 +14449 size-of-type-id: # t: type-id -> result/eax: int +14450 # . prologue +14451 55/push-ebp +14452 89/<- %ebp 4/r32/esp +14453 # . save registers +14454 51/push-ecx +14455 # var out/ecx: (handle typeinfo) +14456 68/push 0/imm32 +14457 68/push 0/imm32 +14458 89/<- %ecx 4/r32/esp +14459 # eax = t +14460 8b/-> *(ebp+8) 0/r32/eax +14461 # if t is a literal, return 0 +14462 3d/compare-eax-and 0/imm32 +14463 0f 84/jump-if-= $size-of-type-id:end/disp32 # eax changes type from type-id to int +14464 # if t is a byte, return 4 (because we don't really support non-multiples of 4) +14465 3d/compare-eax-and 8/imm32/byte +14466 { +14467 75/jump-if-!= break/disp8 +14468 b8/copy-to-eax 4/imm32 +14469 eb/jump $size-of-type-id:end/disp8 +14470 } +14471 # if t is a handle, return 8 +14472 3d/compare-eax-and 4/imm32/handle +14473 { +14474 75/jump-if-!= break/disp8 +14475 b8/copy-to-eax 8/imm32 +14476 eb/jump $size-of-type-id:end/disp8 # eax changes type from type-id to int +14477 } +14478 # if t is a user-defined type, return its size +14479 # TODO: support non-atom type +14480 (find-typeinfo %eax %ecx) +14481 { +14482 81 7/subop/compare *ecx 0/imm32 +14483 74/jump-if-= break/disp8 +14484 $size-of-type-id:user-defined: +14485 (lookup *ecx *(ecx+4)) # => eax +14486 8b/-> *(eax+0xc) 0/r32/eax # Typeinfo-total-size-in-bytes +14487 eb/jump $size-of-type-id:end/disp8 +14488 } +14489 # otherwise return the word size +14490 b8/copy-to-eax 4/imm32 +14491 $size-of-type-id:end: +14492 # . reclaim locals +14493 81 0/subop/add %esp 8/imm32 +14494 # . restore registers +14495 59/pop-to-ecx +14496 # . epilogue +14497 89/<- %esp 5/r32/ebp +14498 5d/pop-to-ebp +14499 c3/return +14500 +14501 # Minor violation of our type system since it returns an addr. But we could +14502 # replace it with a handle some time. +14503 # Returns null if t is an atom. +14504 type-tail: # t: (addr type-tree) -> out/eax: (addr type-tree) +14505 # . prologue +14506 55/push-ebp +14507 89/<- %ebp 4/r32/esp +14508 # . save registers +14509 51/push-ecx +14510 # eax = 0 +14511 b8/copy-to-eax 0/imm32 +14512 # ecx = t +14513 8b/-> *(ebp+8) 1/r32/ecx +14514 $type-tail:check-atom: +14515 # if t->is-atom? return 0 +14516 81 7/subop/compare *ecx 0/imm32/false # Type-tree-is-atom +14517 0f 85/jump-if-!= $type-tail:end/disp32 +14518 # var tail = t->right +14519 (lookup *(ecx+0xc) *(ecx+0x10)) # Type-tree-right Type-tree-right => eax +14520 89/<- %ecx 0/r32/eax +14521 $type-tail:check-singleton: +14522 # if (tail->right == 0) return tail->left +14523 { +14524 81 7/subop/compare *(ecx+0xc) 0/imm32 # Type-tree-right +14525 75/jump-if-!= break/disp8 +14526 (lookup *(ecx+4) *(ecx+8)) # Type-tree-left Type-tree-left => eax +14527 e9/jump $type-tail:end/disp32 +14528 } +14529 # if tail->right->left is an array-capacity, return tail->left +14530 { +14531 $type-tail:check-array-capacity: +14532 (lookup *(ecx+0xc) *(ecx+0x10)) # Type-tree-right Type-tree-right => eax +14533 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom +14534 75/jump-if-!= break/disp8 +14535 $type-tail:check-array-capacity-1: +14536 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +14537 3d/compare-eax-and 0/imm32 +14538 74/jump-if-= break/disp8 +14539 $type-tail:check-array-capacity-2: +14540 (is-simple-mu-type? %eax 9) # array-capacity => eax +14541 3d/compare-eax-and 0/imm32/false +14542 74/jump-if-= break/disp8 +14543 $type-tail:array-capacity: +14544 (lookup *(ecx+4) *(ecx+8)) # Type-tree-left Type-tree-left => eax +14545 eb/jump $type-tail:end/disp8 +14546 } +14547 $type-tail:check-compound-left: +14548 # if !tail->left->is-atom? return tail->left +14549 (lookup *(ecx+4) *(ecx+8)) # Type-tree-left Type-tree-left => eax +14550 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom +14551 74/jump-if-= $type-tail:end/disp8 +14552 $type-tail:return-tail: +14553 # return tail +14554 89/<- %eax 1/r32/ecx +14555 $type-tail:end: +14556 # . restore registers +14557 59/pop-to-ecx +14558 # . epilogue +14559 89/<- %esp 5/r32/ebp +14560 5d/pop-to-ebp +14561 c3/return +14562 +14563 type-equal?: # a: (addr type-tree), b: (addr type-tree) -> result/eax: boolean +14564 # . prologue +14565 55/push-ebp +14566 89/<- %ebp 4/r32/esp +14567 # . save registers +14568 51/push-ecx +14569 52/push-edx +14570 53/push-ebx +14571 # ecx = a +14572 8b/-> *(ebp+8) 1/r32/ecx +14573 # edx = b +14574 8b/-> *(ebp+0xc) 2/r32/edx +14575 $type-equal?:compare-addr: +14576 # if (a == b) return true +14577 8b/-> %ecx 0/r32/eax # Var-type +14578 39/compare %edx 0/r32/eax # Var-type +14579 b8/copy-to-eax 1/imm32/true +14580 0f 84/jump-if-= $type-equal?:end/disp32 +14581 $type-equal?:compare-null-a: +14582 # if (a == 0) return false +14583 b8/copy-to-eax 0/imm32/false +14584 81 7/subop/compare %ecx 0/imm32 +14585 0f 84/jump-if-= $type-equal?:end/disp32 +14586 $type-equal?:compare-null-b: +14587 # if (b == 0) return false +14588 81 7/subop/compare %edx 0/imm32 +14589 0f 84/jump-if-= $type-equal?:end/disp32 +14590 $type-equal?:compare-atom-state: +14591 # if (a->is-atom? != b->is-atom?) return false +14592 8b/-> *ecx 3/r32/ebx # Type-tree-is-atom +14593 39/compare *edx 3/r32/ebx # Type-tree-is-atom +14594 b8/copy-to-eax 0/imm32/false +14595 0f 85/jump-if-!= $type-equal?:end/disp32 +14596 # if a->is-atom? return (a->value == b->value) 14597 { -14598 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax -14599 (is-mu-stream? %eax) # => eax -14600 3d/compare-eax-and 0/imm32/false -14601 0f 84/jump-if-= break/disp32 -14602 # var array-size-without-size/edx: int = n-12 -14603 81 5/subop/subtract %edx 0xc/imm32 -14604 (emit-array-data-initialization *(ebp+8) %edx) -14605 # emit read and write pointers -14606 (emit-indent *(ebp+8) *Curr-block-depth) -14607 (write-buffered *(ebp+8) "68/push 0/imm32\n") -14608 (emit-indent *(ebp+8) *Curr-block-depth) -14609 (write-buffered *(ebp+8) "68/push 0/imm32\n") -14610 # -14611 eb/jump $emit-subx-var-def:end/disp8 -14612 } -14613 # while n > 0 -14614 { -14615 81 7/subop/compare %edx 0/imm32 -14616 7e/jump-if-<= break/disp8 -14617 (emit-indent *(ebp+8) *Curr-block-depth) -14618 (write-buffered *(ebp+8) "68/push 0/imm32\n") -14619 # n -= 4 -14620 81 5/subop/subtract %edx 4/imm32 -14621 # -14622 eb/jump loop/disp8 -14623 } -14624 $emit-subx-var-def:end: -14625 # . restore registers -14626 5a/pop-to-edx -14627 59/pop-to-ecx -14628 58/pop-to-eax -14629 # . epilogue -14630 89/<- %esp 5/r32/ebp -14631 5d/pop-to-ebp -14632 c3/return -14633 -14634 emit-array-data-initialization: # out: (addr buffered-file), n: int -14635 # . prologue -14636 55/push-ebp -14637 89/<- %ebp 4/r32/esp -14638 # -14639 (emit-indent *(ebp+8) *Curr-block-depth) -14640 (write-buffered *(ebp+8) "(push-n-zero-bytes ") -14641 (write-int32-hex-buffered *(ebp+8) *(ebp+0xc)) -14642 (write-buffered *(ebp+8) ")\n") -14643 (emit-indent *(ebp+8) *Curr-block-depth) -14644 (write-buffered *(ebp+8) "68/push ") -14645 (write-int32-hex-buffered *(ebp+8) *(ebp+0xc)) -14646 (write-buffered *(ebp+8) "/imm32\n") -14647 $emit-array-data-initialization:end: -14648 # . epilogue -14649 89/<- %esp 5/r32/ebp -14650 5d/pop-to-ebp -14651 c3/return -14652 -14653 emit-subx-stmt: # out: (addr buffered-file), stmt: (addr stmt), primitives: (addr primitive), err: (addr buffered-file), ed: (addr exit-descriptor) -14654 # . prologue -14655 55/push-ebp -14656 89/<- %ebp 4/r32/esp -14657 # . save registers -14658 50/push-eax -14659 51/push-ecx -14660 # - some special-case primitives that don't actually use the 'primitives' data structure -14661 # var op/ecx: (addr array byte) = lookup(stmt->operation) -14662 8b/-> *(ebp+0xc) 1/r32/ecx -14663 (lookup *(ecx+4) *(ecx+8)) # Stmt1-operation Stmt1-operation => eax -14664 89/<- %ecx 0/r32/eax -14665 # array size -14666 { -14667 # if (!string-equal?(stmt->operation, "length")) break -14668 (string-equal? %ecx "length") # => eax -14669 3d/compare-eax-and 0/imm32 -14670 0f 84/jump-if-= break/disp32 -14671 (translate-mu-length-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18)) -14672 e9/jump $emit-subx-stmt:end/disp32 -14673 } -14674 # index into array -14675 { -14676 # if (!string-equal?(stmt->operation, "index")) break -14677 (string-equal? %ecx "index") # => eax -14678 3d/compare-eax-and 0/imm32 -14679 0f 84/jump-if-= break/disp32 -14680 (translate-mu-index-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18)) -14681 e9/jump $emit-subx-stmt:end/disp32 -14682 } -14683 # compute-offset for index into array -14684 { -14685 # if (!string-equal?(stmt->operation, "compute-offset")) break -14686 (string-equal? %ecx "compute-offset") # => eax -14687 3d/compare-eax-and 0/imm32 -14688 0f 84/jump-if-= break/disp32 -14689 (translate-mu-compute-index-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18)) -14690 e9/jump $emit-subx-stmt:end/disp32 -14691 } -14692 # get field from record -14693 { -14694 # if (!string-equal?(stmt->operation, "get")) break -14695 (string-equal? %ecx "get") # => eax -14696 3d/compare-eax-and 0/imm32 -14697 0f 84/jump-if-= break/disp32 -14698 (translate-mu-get-stmt *(ebp+8) *(ebp+0xc)) -14699 e9/jump $emit-subx-stmt:end/disp32 -14700 } -14701 # allocate scalar -14702 { -14703 # if (!string-equal?(stmt->operation, "allocate")) break -14704 (string-equal? %ecx "allocate") # => eax -14705 3d/compare-eax-and 0/imm32 -14706 0f 84/jump-if-= break/disp32 -14707 (translate-mu-allocate-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18)) -14708 e9/jump $emit-subx-stmt:end/disp32 -14709 } -14710 # allocate array -14711 { -14712 # if (!string-equal?(stmt->operation, "populate")) break -14713 (string-equal? %ecx "populate") # => eax -14714 3d/compare-eax-and 0/imm32 -14715 0f 84/jump-if-= break/disp32 -14716 (translate-mu-populate-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18)) -14717 e9/jump $emit-subx-stmt:end/disp32 -14718 } -14719 # allocate stream -14720 { -14721 # if (!string-equal?(stmt->operation, "populate-stream")) break -14722 (string-equal? %ecx "populate-stream") # => eax -14723 3d/compare-eax-and 0/imm32 -14724 0f 84/jump-if-= break/disp32 -14725 (translate-mu-populate-stream-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18)) -14726 e9/jump $emit-subx-stmt:end/disp32 -14727 } -14728 # read from stream -14729 { -14730 # if (!string-equal?(stmt->operation, "read-from-stream")) break -14731 (string-equal? %ecx "read-from-stream") # => eax -14732 3d/compare-eax-and 0/imm32 -14733 0f 84/jump-if-= break/disp32 -14734 (translate-mu-read-from-stream-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18)) -14735 e9/jump $emit-subx-stmt:end/disp32 -14736 } -14737 # write to stream -14738 { -14739 # if (!string-equal?(stmt->operation, "write-to-stream")) break -14740 (string-equal? %ecx "write-to-stream") # => eax -14741 3d/compare-eax-and 0/imm32 -14742 0f 84/jump-if-= break/disp32 -14743 (translate-mu-write-to-stream-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18)) -14744 e9/jump $emit-subx-stmt:end/disp32 -14745 } -14746 # - if stmt matches a primitive, emit it -14747 { -14748 $emit-subx-stmt:check-for-primitive: -14749 # var curr/eax: (addr primitive) -14750 (find-matching-primitive *(ebp+0x10) *(ebp+0xc)) # primitives, stmt => eax -14751 3d/compare-eax-and 0/imm32 -14752 74/jump-if-= break/disp8 -14753 $emit-subx-stmt:primitive: -14754 (emit-subx-primitive *(ebp+8) *(ebp+0xc) %eax) # out, stmt, curr -14755 e9/jump $emit-subx-stmt:end/disp32 +14598 $type-equal?:check-atom: +14599 81 7/subop/compare %ebx 0/imm32/false +14600 74/jump-if-= break/disp8 +14601 $type-equal?:is-atom: +14602 8b/-> *(ecx+4) 0/r32/eax # Type-tree-value +14603 39/compare *(edx+4) 0/r32/eax # Type-tree-value +14604 0f 94/set-if-= %al +14605 81 4/subop/and %eax 0xff/imm32 +14606 e9/jump $type-equal?:end/disp32 +14607 } +14608 $type-equal?:check-left: +14609 # if (!type-equal?(a->left, b->left)) return false +14610 (lookup *(ecx+4) *(ecx+8)) # Type-tree-left Type-tree-left => eax +14611 89/<- %ebx 0/r32/eax +14612 (lookup *(edx+4) *(edx+8)) # Type-tree-left Type-tree-left => eax +14613 (type-equal? %eax %ebx) # => eax +14614 3d/compare-eax-and 0/imm32/false +14615 74/jump-if-= $type-equal?:end/disp8 +14616 $type-equal?:check-right: +14617 # return type-equal?(a->right, b->right) +14618 (lookup *(ecx+0xc) *(ecx+0x10)) # Type-tree-right Type-tree-right => eax +14619 89/<- %ebx 0/r32/eax +14620 (lookup *(edx+0xc) *(edx+0x10)) # Type-tree-right Type-tree-right => eax +14621 (type-equal? %eax %ebx) # => eax +14622 $type-equal?:end: +14623 # . restore registers +14624 5b/pop-to-ebx +14625 5a/pop-to-edx +14626 59/pop-to-ecx +14627 # . epilogue +14628 89/<- %esp 5/r32/ebp +14629 5d/pop-to-ebp +14630 c3/return +14631 +14632 ####################################################### +14633 # Code-generation +14634 ####################################################### +14635 +14636 == data +14637 +14638 # Global state added to each var record when performing code-generation. +14639 Curr-local-stack-offset: # (addr int) +14640 0/imm32 +14641 +14642 == code +14643 +14644 emit-subx: # out: (addr buffered-file), err: (addr buffered-file), ed: (addr exit-descriptor) +14645 # . prologue +14646 55/push-ebp +14647 89/<- %ebp 4/r32/esp +14648 # . save registers +14649 50/push-eax +14650 # var curr/eax: (addr function) = *Program->functions +14651 (lookup *_Program-functions *_Program-functions->payload) # => eax +14652 { +14653 # if (curr == null) break +14654 3d/compare-eax-and 0/imm32 +14655 0f 84/jump-if-= break/disp32 +14656 (emit-subx-function *(ebp+8) %eax *(ebp+0xc) *(ebp+0x10)) +14657 # curr = lookup(curr->next) +14658 (lookup *(eax+0x20) *(eax+0x24)) # Function-next Function-next => eax +14659 e9/jump loop/disp32 +14660 } +14661 $emit-subx:end: +14662 # . restore registers +14663 58/pop-to-eax +14664 # . epilogue +14665 89/<- %esp 5/r32/ebp +14666 5d/pop-to-ebp +14667 c3/return +14668 +14669 emit-subx-function: # out: (addr buffered-file), f: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +14670 # . prologue +14671 55/push-ebp +14672 89/<- %ebp 4/r32/esp +14673 # some preprocessing +14674 (populate-mu-type-offsets-in-inouts *(ebp+0xc)) +14675 # . save registers +14676 50/push-eax +14677 51/push-ecx +14678 52/push-edx +14679 # initialize some global state +14680 c7 0/subop/copy *Curr-block-depth 1/imm32 # Important: keep this in sync with the parse phase +14681 c7 0/subop/copy *Curr-local-stack-offset 0/imm32 +14682 # ecx = f +14683 8b/-> *(ebp+0xc) 1/r32/ecx +14684 # var vars/edx: (stack (addr var) 256) +14685 81 5/subop/subtract %esp 0xc00/imm32 +14686 68/push 0xc00/imm32/size +14687 68/push 0/imm32/top +14688 89/<- %edx 4/r32/esp +14689 # var name/eax: (addr array byte) = lookup(f->name) +14690 (lookup *ecx *(ecx+4)) # Function-name Function-name => eax +14691 # +14692 (write-buffered *(ebp+8) %eax) +14693 (write-buffered *(ebp+8) ":\n") +14694 (emit-subx-prologue *(ebp+8)) +14695 # var body/eax: (addr block) = lookup(f->body) +14696 (lookup *(ecx+0x18) *(ecx+0x1c)) # Function-body Function-body => eax +14697 # +14698 (emit-subx-block *(ebp+8) %eax %edx *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +14699 (emit-subx-epilogue *(ebp+8)) +14700 # TODO: validate that *Curr-block-depth and *Curr-local-stack-offset have +14701 # been cleaned up +14702 $emit-subx-function:end: +14703 # . reclaim locals +14704 81 0/subop/add %esp 0xc08/imm32 +14705 # . restore registers +14706 5a/pop-to-edx +14707 59/pop-to-ecx +14708 58/pop-to-eax +14709 # . epilogue +14710 89/<- %esp 5/r32/ebp +14711 5d/pop-to-ebp +14712 c3/return +14713 +14714 populate-mu-type-offsets-in-inouts: # f: (addr function) +14715 # . prologue +14716 55/push-ebp +14717 89/<- %ebp 4/r32/esp +14718 # . save registers +14719 50/push-eax +14720 51/push-ecx +14721 52/push-edx +14722 53/push-ebx +14723 57/push-edi +14724 # var next-offset/edx: int = 8 +14725 ba/copy-to-edx 8/imm32 +14726 # var curr/ecx: (addr list var) = lookup(f->inouts) +14727 8b/-> *(ebp+8) 1/r32/ecx +14728 (lookup *(ecx+8) *(ecx+0xc)) # Function-inouts Function-inouts => eax +14729 89/<- %ecx 0/r32/eax +14730 { +14731 $populate-mu-type-offsets-in-inouts:loop: +14732 81 7/subop/compare %ecx 0/imm32 +14733 74/jump-if-= break/disp8 +14734 # var v/ebx: (addr var) = lookup(curr->value) +14735 (lookup *ecx *(ecx+4)) # List-value List-value => eax +14736 89/<- %ebx 0/r32/eax +14737 #? (lookup *ebx *(ebx+4)) +14738 #? (write-buffered Stderr "setting offset of fn inout ") +14739 #? (write-buffered Stderr %eax) +14740 #? (write-buffered Stderr "@") +14741 #? (write-int32-hex-buffered Stderr %ebx) +14742 #? (write-buffered Stderr " to ") +14743 #? (write-int32-hex-buffered Stderr %edx) +14744 #? (write-buffered Stderr Newline) +14745 #? (flush Stderr) +14746 # v->offset = next-offset +14747 89/<- *(ebx+0x14) 2/r32/edx # Var-offset +14748 # next-offset += size-of(v) +14749 (size-of %ebx) # => eax +14750 01/add-to %edx 0/r32/eax +14751 # curr = lookup(curr->next) +14752 (lookup *(ecx+8) *(ecx+0xc)) # List-next List-next => eax +14753 89/<- %ecx 0/r32/eax +14754 # +14755 eb/jump loop/disp8 14756 } -14757 # - otherwise emit a call -14758 # TODO: type-checking -14759 $emit-subx-stmt:call: -14760 (emit-call *(ebp+8) *(ebp+0xc)) -14761 $emit-subx-stmt:end: -14762 # . restore registers -14763 59/pop-to-ecx -14764 58/pop-to-eax -14765 # . epilogue -14766 89/<- %esp 5/r32/ebp -14767 5d/pop-to-ebp -14768 c3/return -14769 -14770 translate-mu-length-stmt: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) -14771 # . prologue -14772 55/push-ebp -14773 89/<- %ebp 4/r32/esp -14774 # . save registers -14775 50/push-eax -14776 51/push-ecx -14777 52/push-edx -14778 53/push-ebx -14779 56/push-esi -14780 # esi = stmt -14781 8b/-> *(ebp+0xc) 6/r32/esi -14782 # var base/ebx: (addr var) = stmt->inouts[0]->value -14783 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax -14784 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -14785 89/<- %ebx 0/r32/eax -14786 # var elemsize/ecx: int = array-element-size(base) -14787 (array-element-size %ebx *(ebp+0x10) *(ebp+0x14)) # => eax -14788 89/<- %ecx 0/r32/eax -14789 # var outreg/edx: (addr array byte) = stmt->outputs[0]->value->register -14790 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax -14791 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -14792 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax -14793 89/<- %edx 0/r32/eax -14794 # if elemsize == 1 -14795 { -14796 81 7/subop/compare %ecx 1/imm32 -14797 75/jump-if-!= break/disp8 -14798 $translate-mu-length-stmt:size-1: -14799 (emit-save-size-to *(ebp+8) %ebx %edx) -14800 e9/jump $translate-mu-length-stmt:end/disp32 -14801 } -14802 # if elemsize is a power of 2 less than 256 -14803 { -14804 (power-of-2? %ecx *(ebp+0x10) *(ebp+0x14)) # => eax -14805 3d/compare-eax-and 0/imm32/false -14806 74/jump-if-= break/disp8 -14807 81 7/subop/compare %ecx 0xff/imm32 -14808 7f/jump-if-> break/disp8 -14809 $translate-mu-length-stmt:size-power-of-2: -14810 (emit-save-size-to *(ebp+8) %ebx %edx) -14811 (emit-divide-by-shift-right *(ebp+8) %edx %ecx) -14812 e9/jump $translate-mu-length-stmt:end/disp32 -14813 } -14814 # otherwise, the complex case -14815 # . emit register spills -14816 { -14817 $translate-mu-length-stmt:complex: -14818 (string-equal? %edx "eax") # => eax -14819 3d/compare-eax-and 0/imm32/false -14820 75/break-if-!= break/disp8 -14821 (emit-indent *(ebp+8) *Curr-block-depth) -14822 (write-buffered *(ebp+8) "50/push-eax\n") -14823 } -14824 { -14825 (string-equal? %edx "ecx") # => eax -14826 3d/compare-eax-and 0/imm32/false -14827 75/break-if-!= break/disp8 -14828 (emit-indent *(ebp+8) *Curr-block-depth) -14829 (write-buffered *(ebp+8) "51/push-ecx\n") -14830 } -14831 { -14832 (string-equal? %edx "edx") # => eax -14833 3d/compare-eax-and 0/imm32/false -14834 75/break-if-!= break/disp8 -14835 (emit-indent *(ebp+8) *Curr-block-depth) -14836 (write-buffered *(ebp+8) "52/push-edx\n") -14837 } -14838 # . -14839 (emit-save-size-to *(ebp+8) %ebx "eax") -14840 (emit-indent *(ebp+8) *Curr-block-depth) -14841 (write-buffered *(ebp+8) "31/xor %edx 2/r32/edx\n") -14842 (emit-indent *(ebp+8) *Curr-block-depth) -14843 (write-buffered *(ebp+8) "b9/copy-to-ecx ") -14844 (write-int32-hex-buffered *(ebp+8) %ecx) -14845 (write-buffered *(ebp+8) "/imm32\n") -14846 (emit-indent *(ebp+8) *Curr-block-depth) -14847 (write-buffered *(ebp+8) "f7 7/subop/idiv-eax-edx-by %ecx\n") -14848 { -14849 (string-equal? %edx "eax") # => eax -14850 3d/compare-eax-and 0/imm32/false -14851 75/break-if-!= break/disp8 -14852 (emit-indent *(ebp+8) *Curr-block-depth) -14853 (write-buffered *(ebp+8) "89/<- %") -14854 (write-buffered *(ebp+8) %edx) -14855 (write-buffered *(ebp+8) " 0/r32/eax\n") -14856 } -14857 # . emit register restores -14858 { -14859 (string-equal? %edx "edx") # => eax -14860 3d/compare-eax-and 0/imm32/false -14861 75/break-if-!= break/disp8 -14862 (emit-indent *(ebp+8) *Curr-block-depth) -14863 (write-buffered *(ebp+8) "5a/pop-to-edx\n") -14864 } -14865 { -14866 (string-equal? %edx "ecx") # => eax -14867 3d/compare-eax-and 0/imm32/false -14868 75/break-if-!= break/disp8 -14869 (emit-indent *(ebp+8) *Curr-block-depth) -14870 (write-buffered *(ebp+8) "59/pop-to-ecx\n") -14871 } -14872 { -14873 (string-equal? %edx "eax") # => eax -14874 3d/compare-eax-and 0/imm32/false -14875 75/break-if-!= break/disp8 -14876 (emit-indent *(ebp+8) *Curr-block-depth) -14877 (write-buffered *(ebp+8) "58/pop-to-eax\n") -14878 } -14879 $translate-mu-length-stmt:end: -14880 # . restore registers -14881 5e/pop-to-esi -14882 5b/pop-to-ebx -14883 5a/pop-to-edx -14884 59/pop-to-ecx -14885 58/pop-to-eax -14886 # . epilogue -14887 89/<- %esp 5/r32/ebp -14888 5d/pop-to-ebp -14889 c3/return -14890 -14891 array-element-size: # arr: (addr var), err: (addr buffered-file), ed: (addr exit-descriptor) -> result/eax: int -14892 # . prologue -14893 55/push-ebp -14894 89/<- %ebp 4/r32/esp -14895 # -14896 (array-element-type-id *(ebp+8) *(ebp+0xc) *(ebp+0x10)) # => eax -14897 (size-of-type-id-as-array-element %eax) # => eax -14898 $array-element-size:end: -14899 # . epilogue -14900 89/<- %esp 5/r32/ebp -14901 5d/pop-to-ebp -14902 c3/return -14903 -14904 array-element-type-id: # v: (addr var), err: (addr buffered-file), ed: (addr exit-descriptor) -> result/eax: type-id -14905 # precondition: n is positive -14906 # . prologue -14907 55/push-ebp -14908 89/<- %ebp 4/r32/esp -14909 # -14910 8b/-> *(ebp+8) 0/r32/eax -14911 # var t/eax: (addr type-tree) -14912 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax -14913 # if t == 0 abort -14914 3d/compare-eax-with 0/imm32 -14915 0f 84/jump-if-== $array-element-type-id:error0/disp32 -14916 # if t->is-atom? abort -14917 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom -14918 0f 85/jump-if-!= $array-element-type-id:error1/disp32 -14919 # if (t->left == addr) t = t->right -14920 { -14921 50/push-eax -14922 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax -14923 (is-simple-mu-type? %eax 2) # addr => eax -14924 3d/compare-eax-with 0/imm32/false -14925 58/pop-to-eax -14926 74/jump-if-= break/disp8 -14927 $array-element-type-id:skip-addr: -14928 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax -14929 } -14930 # if t == 0 abort -14931 3d/compare-eax-with 0/imm32 -14932 0f 84/jump-if-= $array-element-type-id:error2/disp32 -14933 # if t->is-atom? abort -14934 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom -14935 0f 85/jump-if-!= $array-element-type-id:error2/disp32 -14936 # if t->left != array abort -14937 { -14938 50/push-eax -14939 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax -14940 (is-simple-mu-type? %eax 3) # array => eax -14941 3d/compare-eax-with 0/imm32/false -14942 58/pop-to-eax -14943 $array-element-type-id:no-array: -14944 0f 84/jump-if-= $array-element-type-id:error2/disp32 -14945 } -14946 $array-element-type-id:skip-array: -14947 # t = t->right -14948 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax -14949 # if t == 0 abort -14950 3d/compare-eax-with 0/imm32 -14951 0f 84/jump-if-= $array-element-type-id:error2/disp32 -14952 # if t->is-atom? abort -14953 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom -14954 0f 85/jump-if-!= $array-element-type-id:error2/disp32 -14955 # return t->left->value -14956 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax -14957 8b/-> *(eax+4) 0/r32/eax # Type-tree-value -14958 $array-element-type-id:end: -14959 # . epilogue -14960 89/<- %esp 5/r32/ebp -14961 5d/pop-to-ebp -14962 c3/return -14963 -14964 $array-element-type-id:error0: -14965 (write-buffered *(ebp+0xc) "array-element-type-id: var '") -14966 50/push-eax -14967 8b/-> *(ebp+8) 0/r32/eax -14968 (lookup *eax *(eax+4)) # Var-name Var-name => eax -14969 (write-buffered *(ebp+0xc) %eax) -14970 58/pop-to-eax -14971 (write-buffered *(ebp+0xc) "' has no type\n") -14972 (flush *(ebp+0xc)) -14973 (stop *(ebp+0x10) 1) -14974 # never gets here -14975 -14976 $array-element-type-id:error1: -14977 (write-buffered *(ebp+0xc) "array-element-type-id: var '") -14978 50/push-eax -14979 8b/-> *(ebp+8) 0/r32/eax -14980 (lookup *eax *(eax+4)) # Var-name Var-name => eax -14981 (write-buffered *(ebp+0xc) %eax) -14982 58/pop-to-eax -14983 (write-buffered *(ebp+0xc) "' has atomic type ") -14984 (write-int32-hex-buffered *(ebp+0xc) *(eax+4)) # Type-tree-value -14985 (write-buffered *(ebp+0xc) Newline) -14986 (flush *(ebp+0xc)) -14987 (stop *(ebp+0x10) 1) -14988 # never gets here -14989 -14990 $array-element-type-id:error2: -14991 (write-buffered *(ebp+0xc) "array-element-type-id: var '") -14992 50/push-eax -14993 8b/-> *(ebp+8) 0/r32/eax -14994 (lookup *eax *(eax+4)) # Var-name Var-name => eax -14995 (write-buffered *(ebp+0xc) %eax) -14996 58/pop-to-eax -14997 (write-buffered *(ebp+0xc) "' has non-array type\n") -14998 (flush *(ebp+0xc)) -14999 (stop *(ebp+0x10) 1) -15000 # never gets here -15001 -15002 size-of-type-id-as-array-element: # t: type-id -> result/eax: int -15003 # . prologue -15004 55/push-ebp -15005 89/<- %ebp 4/r32/esp -15006 # eax = t -15007 8b/-> *(ebp+8) 0/r32/eax -15008 # if t is 'byte', size is 1 -15009 3d/compare-eax-and 8/imm32/byte -15010 { -15011 75/jump-if-!= break/disp8 -15012 b8/copy-to-eax 1/imm32 -15013 eb/jump $size-of-type-id-as-array-element:end/disp8 -15014 } -15015 # otherwise proceed as usual -15016 (size-of-type-id %eax) # => eax -15017 $size-of-type-id-as-array-element:end: -15018 # . epilogue -15019 89/<- %esp 5/r32/ebp -15020 5d/pop-to-ebp -15021 c3/return -15022 -15023 emit-save-size-to: # out: (addr buffered-file), base: (addr var), outreg: (addr array byte) -15024 # . prologue -15025 55/push-ebp -15026 89/<- %ebp 4/r32/esp -15027 # . save registers -15028 50/push-eax -15029 53/push-ebx -15030 # ebx = base -15031 8b/-> *(ebp+0xc) 3/r32/ebx -15032 (emit-indent *(ebp+8) *Curr-block-depth) -15033 (write-buffered *(ebp+8) "8b/-> *") -15034 # if base is an (addr array ...) in a register -15035 { -15036 81 7/subop/compare *(ebx+0x18)) 0/imm32 # Var-register -15037 74/jump-if-= break/disp8 -15038 $emit-save-size-to:emit-base-from-register: -15039 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register Var-register => eax -15040 (write-buffered *(ebp+8) %eax) -15041 eb/jump $emit-save-size-to:emit-output/disp8 -15042 } -15043 # otherwise if base is an (array ...) on the stack -15044 { -15045 81 7/subop/compare *(ebx+0x14)) 0/imm32 # Var-offset -15046 74/jump-if-= break/disp8 -15047 $emit-save-size-to:emit-base-from-stack: -15048 (write-buffered *(ebp+8) "(ebp+") -15049 (write-int32-hex-buffered *(ebp+8) *(ebx+0x14)) # Var-offset -15050 (write-buffered *(ebp+8) ")") -15051 } -15052 $emit-save-size-to:emit-output: -15053 (write-buffered *(ebp+8) " ") -15054 (get Mu-registers *(ebp+0x10) 0xc "Mu-registers") # => eax -15055 (write-int32-hex-buffered *(ebp+8) *eax) -15056 (write-buffered *(ebp+8) "/r32\n") -15057 $emit-save-size-to:end: -15058 # . restore registers -15059 5b/pop-to-ebx -15060 58/pop-to-eax -15061 # . epilogue -15062 89/<- %esp 5/r32/ebp -15063 5d/pop-to-ebp -15064 c3/return -15065 -15066 emit-divide-by-shift-right: # out: (addr buffered-file), reg: (addr array byte), size: int -15067 # . prologue -15068 55/push-ebp -15069 89/<- %ebp 4/r32/esp -15070 # . save registers -15071 50/push-eax -15072 # -15073 (emit-indent *(ebp+8) *Curr-block-depth) -15074 (write-buffered *(ebp+8) "c1/shift 5/subop/>> %") -15075 (write-buffered *(ebp+8) *(ebp+0xc)) -15076 (write-buffered *(ebp+8) Space) -15077 (num-shift-rights *(ebp+0x10)) # => eax -15078 (write-int32-hex-buffered *(ebp+8) %eax) -15079 (write-buffered *(ebp+8) "/imm8\n") -15080 $emit-divide-by-shift-right:end: -15081 # . restore registers -15082 58/pop-to-eax -15083 # . epilogue -15084 89/<- %esp 5/r32/ebp -15085 5d/pop-to-ebp -15086 c3/return -15087 -15088 translate-mu-index-stmt: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) -15089 # . prologue -15090 55/push-ebp -15091 89/<- %ebp 4/r32/esp -15092 # . save registers -15093 51/push-ecx -15094 # ecx = stmt -15095 8b/-> *(ebp+0xc) 1/r32/ecx -15096 # var base/ecx: (addr var) = stmt->inouts[0] -15097 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax -15098 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -15099 89/<- %ecx 0/r32/eax -15100 # if (var->register) do one thing -15101 { -15102 81 7/subop/compare *(ecx+0x18) 0/imm32 # Var-register -15103 74/jump-if-= break/disp8 -15104 # TODO: ensure there's no dereference -15105 (translate-mu-index-stmt-with-array-in-register *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -15106 eb/jump $translate-mu-index-stmt:end/disp8 -15107 } -15108 # if (var->offset) do a different thing -15109 { -15110 81 7/subop/compare *(ecx+0x14) 0/imm32 # Var-offset -15111 74/jump-if-= break/disp8 -15112 # TODO: ensure there's no dereference -15113 (translate-mu-index-stmt-with-array-on-stack *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -15114 eb/jump $translate-mu-index-stmt:end/disp8 -15115 } -15116 $translate-mu-index-stmt:end: -15117 # . restore registers -15118 59/pop-to-ecx -15119 # . epilogue -15120 89/<- %esp 5/r32/ebp -15121 5d/pop-to-ebp -15122 c3/return -15123 -15124 $translate-mu-index-stmt-with-array:error1: -15125 (write-buffered *(ebp+0x10) "couldn't translate an index instruction. second (index) input must either lie in a register or be a literal\n") -15126 (flush *(ebp+0x10)) -15127 (stop *(ebp+0x14) 1) -15128 # never gets here -15129 -15130 $translate-mu-index-stmt-with-array:error2: -15131 (write-buffered *(ebp+0x10) "couldn't translate an index instruction. second (index) input when in a register must be an int or offset\n") -15132 (flush *(ebp+0x10)) -15133 (stop *(ebp+0x14) 1) -15134 # never gets here -15135 -15136 translate-mu-index-stmt-with-array-in-register: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) -15137 # . prologue -15138 55/push-ebp -15139 89/<- %ebp 4/r32/esp -15140 # . save registers -15141 50/push-eax -15142 51/push-ecx -15143 52/push-edx -15144 53/push-ebx -15145 # -15146 (emit-indent *(ebp+8) *Curr-block-depth) -15147 (write-buffered *(ebp+8) "8d/copy-address *(") -15148 # TODO: ensure inouts[0] is in a register and not dereferenced -15149 $translate-mu-index-stmt-with-array-in-register:emit-base: -15150 # ecx = stmt -15151 8b/-> *(ebp+0xc) 1/r32/ecx -15152 # var base/ebx: (addr var) = inouts[0] -15153 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax -15154 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -15155 89/<- %ebx 0/r32/eax -15156 # print base->register " + " -15157 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register Var-register => eax -15158 (write-buffered *(ebp+8) %eax) -15159 (write-buffered *(ebp+8) " + ") -15160 # var index/edx: (addr var) = inouts[1] -15161 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax -15162 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax -15163 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -15164 89/<- %edx 0/r32/eax -15165 # if index->register -15166 81 7/subop/compare *(edx+0x18) 0/imm32 # Var-register -15167 { -15168 0f 84/jump-if-= break/disp32 -15169 $translate-mu-index-stmt-with-array-in-register:emit-register-index: -15170 # if index is an int -15171 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax -15172 (is-simple-mu-type? %eax 1) # int => eax -15173 3d/compare-eax-and 0/imm32/false -15174 { -15175 0f 84/jump-if-= break/disp32 -15176 $translate-mu-index-stmt-with-array-in-register:emit-int-register-index: -15177 # print index->register "<<" log2(array-element-size(base)) " + 4) " -15178 # . index->register "<<" -15179 (lookup *(edx+0x18) *(edx+0x1c)) # Var-register Var-register => eax -15180 (write-buffered *(ebp+8) %eax) -15181 (write-buffered *(ebp+8) "<<") -15182 # . log2(array-element-size(base->type)) -15183 # TODO: ensure size is a power of 2 -15184 (array-element-size %ebx *(ebp+0x10) *(ebp+0x14)) # => eax -15185 (num-shift-rights %eax) # => eax -15186 (write-int32-hex-buffered *(ebp+8) %eax) -15187 e9/jump $translate-mu-index-stmt-with-array-in-register:emit-register-index-done/disp32 -15188 } -15189 # if index->type is any other atom, abort -15190 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax -15191 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom -15192 0f 85/jump-if-!= $translate-mu-index-stmt-with-array:error2/disp32 -15193 # if index has type (offset ...) -15194 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax -15195 (is-simple-mu-type? %eax 7) # => eax -15196 3d/compare-eax-and 0/imm32/false -15197 { -15198 0f 84/jump-if-= break/disp32 -15199 # print index->register -15200 $translate-mu-index-stmt-with-array-in-register:emit-offset-register-index: -15201 (lookup *(edx+0x18) *(edx+0x1c)) # Var-register Var-register => eax -15202 (write-buffered *(ebp+8) %eax) -15203 } -15204 $translate-mu-index-stmt-with-array-in-register:emit-register-index-done: -15205 (write-buffered *(ebp+8) " + 4) ") -15206 e9/jump $translate-mu-index-stmt-with-array-in-register:emit-output/disp32 -15207 } -15208 # otherwise if index is a literal -15209 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax -15210 (is-simple-mu-type? %eax 0) # => eax -15211 3d/compare-eax-and 0/imm32/false -15212 { -15213 0f 84/jump-if-= break/disp32 -15214 $translate-mu-index-stmt-with-array-in-register:emit-literal-index: -15215 # var index-value/edx: int = parse-hex-int(index->name) -15216 (lookup *edx *(edx+4)) # Var-name Var-name => eax -15217 (parse-hex-int %eax) # => eax -15218 89/<- %edx 0/r32/eax -15219 # offset = idx-value * array-element-size(base->type) -15220 (array-element-size %ebx *(ebp+0x10) *(ebp+0x14)) # => eax -15221 f7 4/subop/multiply-into-eax %edx # clobbers edx -15222 # offset += 4 for array size -15223 05/add-to-eax 4/imm32 -15224 # TODO: check edx for overflow -15225 # print offset -15226 (write-int32-hex-buffered *(ebp+8) %eax) -15227 (write-buffered *(ebp+8) ") ") -15228 e9/jump $translate-mu-index-stmt-with-array-in-register:emit-output/disp32 -15229 } -15230 # otherwise abort -15231 e9/jump $translate-mu-index-stmt-with-array:error1/disp32 -15232 $translate-mu-index-stmt-with-array-in-register:emit-output: -15233 # outputs[0] "/r32" -15234 8b/-> *(ebp+0xc) 1/r32/ecx -15235 (lookup *(ecx+0x14) *(ecx+0x18)) # Stmt1-outputs Stmt1-outputs => eax -15236 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -15237 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax -15238 (get Mu-registers %eax 0xc "Mu-registers") # => eax: (addr int) -15239 (write-int32-hex-buffered *(ebp+8) *eax) -15240 (write-buffered *(ebp+8) "/r32\n") -15241 $translate-mu-index-stmt-with-array-in-register:end: -15242 # . restore registers -15243 5b/pop-to-ebx -15244 5a/pop-to-edx -15245 59/pop-to-ecx -15246 58/pop-to-eax -15247 # . epilogue -15248 89/<- %esp 5/r32/ebp -15249 5d/pop-to-ebp -15250 c3/return -15251 -15252 translate-mu-index-stmt-with-array-on-stack: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) -15253 # . prologue -15254 55/push-ebp -15255 89/<- %ebp 4/r32/esp -15256 # . save registers -15257 50/push-eax -15258 51/push-ecx -15259 52/push-edx -15260 53/push-ebx -15261 # -15262 (emit-indent *(ebp+8) *Curr-block-depth) -15263 (write-buffered *(ebp+8) "8d/copy-address *(ebp + ") -15264 # var curr/edx: (addr stmt-var) = lookup(stmt->inouts) -15265 8b/-> *(ebp+0xc) 0/r32/eax -15266 (lookup *(eax+0xc) *(eax+0x10)) # Stmt1-inouts Stmt1-inouts => eax -15267 89/<- %edx 0/r32/eax -15268 # var base/ecx: (addr var) = lookup(curr->value) -15269 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -15270 89/<- %ecx 0/r32/eax -15271 # var curr2/eax: (addr stmt-var) = lookup(curr->next) -15272 (lookup *(edx+8) *(edx+0xc)) # Stmt-var-next Stmt-var-next => eax -15273 # var index/edx: (handle var) = curr2->value -15274 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -15275 89/<- %edx 0/r32/eax -15276 # if index->register -15277 81 7/subop/compare *(edx+0x18) 0/imm32 # Var-register -15278 { -15279 0f 84/jump-if-= break/disp32 -15280 $translate-mu-index-stmt-with-array-on-stack:emit-register-index: -15281 # if index is an int -15282 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax -15283 (is-simple-mu-type? %eax 1) # int => eax -15284 3d/compare-eax-and 0/imm32/false -15285 { -15286 0f 84/jump-if-= break/disp32 -15287 $translate-mu-index-stmt-with-array-on-stack:emit-int-register-index: -15288 # print index->register "<<" log2(array-element-size(base)) " + " base->offset+4 -15289 # . inouts[1]->register "<<" -15290 (lookup *(edx+0x18) *(edx+0x1c)) # Var-register Var-register => eax -15291 (write-buffered *(ebp+8) %eax) -15292 (write-buffered *(ebp+8) "<<") -15293 # . log2(array-element-size(base)) -15294 # TODO: ensure size is a power of 2 -15295 (array-element-size %ecx *(ebp+0x10) *(ebp+0x14)) # => eax -15296 (num-shift-rights %eax) # => eax -15297 (write-int32-hex-buffered *(ebp+8) %eax) -15298 # -15299 (write-buffered *(ebp+8) " + ") -15300 # -15301 8b/-> *(ecx+0x14) 0/r32/eax # Var-offset -15302 05/add-to-eax 4/imm32 # for array length -15303 (write-int32-hex-buffered *(ebp+8) %eax) -15304 e9/jump $translate-mu-index-stmt-with-array-on-stack:emit-register-index-done/disp32 -15305 } -15306 # if index->type is any other atom, abort -15307 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax -15308 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom -15309 0f 85/jump-if-!= $translate-mu-index-stmt-with-array:error2/disp32 -15310 # if index has type (offset ...) -15311 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax -15312 (is-simple-mu-type? %eax 7) # => eax -15313 3d/compare-eax-and 0/imm32/false -15314 { -15315 0f 84/jump-if-= break/disp32 -15316 # print index->register -15317 $translate-mu-index-stmt-with-array-on-stack:emit-offset-register-index: -15318 (lookup *(edx+0x18) *(edx+0x1c)) # Var-register Var-register => eax -15319 (write-buffered *(ebp+8) %eax) -15320 } -15321 $translate-mu-index-stmt-with-array-on-stack:emit-register-index-done: -15322 (write-buffered *(ebp+8) ") ") -15323 e9/jump $translate-mu-index-stmt-with-array-on-stack:emit-output/disp32 -15324 } -15325 # otherwise if index is a literal -15326 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax -15327 (is-simple-mu-type? %eax 0) # => eax -15328 3d/compare-eax-and 0/imm32/false -15329 { -15330 0f 84/jump-if-= break/disp32 -15331 $translate-mu-index-stmt-with-array-on-stack:emit-literal-index: -15332 # var idx-value/edx: int = parse-hex-int(index->name) -15333 (lookup *edx *(edx+4)) # Var-name Var-name => eax -15334 (parse-hex-int %eax) # Var-name => eax -15335 89/<- %edx 0/r32/eax -15336 # offset = idx-value * array-element-size(base) -15337 (array-element-size %ecx *(ebp+0x10) *(ebp+0x14)) # => eax -15338 f7 4/subop/multiply-into-eax %edx # clobbers edx -15339 # offset += base->offset -15340 03/add *(ecx+0x14) 0/r32/eax # Var-offset -15341 # offset += 4 for array size -15342 05/add-to-eax 4/imm32 -15343 # TODO: check edx for overflow -15344 # print offset -15345 (write-int32-hex-buffered *(ebp+8) %eax) -15346 (write-buffered *(ebp+8) ") ") -15347 e9/jump $translate-mu-index-stmt-with-array-on-stack:emit-output/disp32 -15348 } -15349 # otherwise abort -15350 e9/jump $translate-mu-index-stmt-with-array:error1/disp32 -15351 $translate-mu-index-stmt-with-array-on-stack:emit-output: -15352 # outputs[0] "/r32" -15353 8b/-> *(ebp+0xc) 0/r32/eax -15354 (lookup *(eax+0x14) *(eax+0x18)) # Stmt1-outputs Stmt1-outputs => eax -15355 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -15356 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax -15357 (get Mu-registers %eax 0xc "Mu-registers") # => eax: (addr int) -15358 (write-int32-hex-buffered *(ebp+8) *eax) -15359 (write-buffered *(ebp+8) "/r32\n") -15360 $translate-mu-index-stmt-with-array-on-stack:end: -15361 # . restore registers -15362 5b/pop-to-ebx -15363 5a/pop-to-edx -15364 59/pop-to-ecx -15365 58/pop-to-eax -15366 # . epilogue -15367 89/<- %esp 5/r32/ebp -15368 5d/pop-to-ebp -15369 c3/return -15370 -15371 translate-mu-compute-index-stmt: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) -15372 # . prologue -15373 55/push-ebp -15374 89/<- %ebp 4/r32/esp -15375 # . save registers -15376 50/push-eax -15377 51/push-ecx -15378 52/push-edx -15379 53/push-ebx -15380 # -15381 (emit-indent *(ebp+8) *Curr-block-depth) -15382 (write-buffered *(ebp+8) "69/multiply") -15383 # ecx = stmt -15384 8b/-> *(ebp+0xc) 1/r32/ecx -15385 # var first-inout/ebx: (addr stmt-var) = stmt->inouts[0] -15386 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax -15387 89/<- %ebx 0/r32/eax -15388 $translate-mu-compute-index-stmt:emit-index: -15389 (lookup *(ebx+8) *(ebx+0xc)) # Stmt-var-next Stmt-var-next => eax -15390 (emit-subx-var-as-rm32 *(ebp+8) %eax) -15391 (write-buffered *(ebp+8) Space) -15392 $translate-mu-compute-index-stmt:emit-elem-size: -15393 # var base/ebx: (addr var) -15394 (lookup *ebx *(ebx+4)) # Stmt-var-value Stmt-var-value => eax -15395 89/<- %ebx 0/r32/eax -15396 # print array-element-size(base) -15397 (array-element-size %ebx *(ebp+0x10) *(ebp+0x14)) # => eax -15398 (write-int32-hex-buffered *(ebp+8) %eax) -15399 (write-buffered *(ebp+8) "/imm32 ") -15400 $translate-mu-compute-index-stmt:emit-output: -15401 # outputs[0] "/r32" -15402 (lookup *(ecx+0x14) *(ecx+0x18)) # Stmt1-outputs Stmt1-outputs => eax -15403 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -15404 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax -15405 (get Mu-registers %eax 0xc "Mu-registers") # => eax: (addr int) -15406 (write-int32-hex-buffered *(ebp+8) *eax) -15407 (write-buffered *(ebp+8) "/r32\n") -15408 $translate-mu-compute-index-stmt:end: -15409 # . restore registers -15410 5b/pop-to-ebx -15411 5a/pop-to-edx -15412 59/pop-to-ecx -15413 58/pop-to-eax -15414 # . epilogue -15415 89/<- %esp 5/r32/ebp -15416 5d/pop-to-ebp -15417 c3/return -15418 -15419 translate-mu-get-stmt: # out: (addr buffered-file), stmt: (addr stmt) -15420 # . prologue -15421 55/push-ebp -15422 89/<- %ebp 4/r32/esp -15423 # . save registers -15424 50/push-eax -15425 51/push-ecx -15426 52/push-edx -15427 # -15428 (emit-indent *(ebp+8) *Curr-block-depth) -15429 (write-buffered *(ebp+8) "8d/copy-address ") -15430 # ecx = stmt -15431 8b/-> *(ebp+0xc) 1/r32/ecx -15432 # var offset/edx: int = get offset of stmt -15433 (mu-get-offset %ecx) # => eax -15434 89/<- %edx 0/r32/eax -15435 # var base/eax: (addr var) = stmt->inouts->value -15436 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax -15437 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -15438 # if base is in a register -15439 81 7/subop/compare *(eax+0x18) 0/imm32 # Var-register -15440 { -15441 0f 84/jump-if-= break/disp32 -15442 $translate-mu-get-stmt:emit-register-input: -15443 # emit "*(" base->register " + " offset ") " -15444 (write-buffered *(ebp+8) "*(") -15445 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax -15446 (write-buffered *(ebp+8) %eax) -15447 (write-buffered *(ebp+8) " + ") -15448 (write-int32-hex-buffered *(ebp+8) %edx) -15449 (write-buffered *(ebp+8) ") ") -15450 e9/jump $translate-mu-get-stmt:emit-output/disp32 -15451 } -15452 # otherwise base is on the stack -15453 { -15454 $translate-mu-get-stmt:emit-stack-input: -15455 # emit "*(ebp + " inouts[0]->stack-offset + offset ") " -15456 (write-buffered *(ebp+8) "*(ebp+") -15457 03/add *(eax+0x14) 2/r32/edx # Var-offset -15458 (write-int32-hex-buffered *(ebp+8) %edx) -15459 (write-buffered *(ebp+8) ") ") -15460 eb/jump $translate-mu-get-stmt:emit-output/disp8 -15461 } -15462 $translate-mu-get-stmt:emit-output: -15463 # var output/eax: (addr var) = stmt->outputs->value -15464 (lookup *(ecx+0x14) *(ecx+0x18)) # Stmt1-outputs Stmt1-outputs => eax -15465 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -15466 # emit offset->register "/r32" -15467 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax -15468 (get Mu-registers %eax 0xc "Mu-registers") # => eax: (addr int) -15469 (write-int32-hex-buffered *(ebp+8) *eax) -15470 (write-buffered *(ebp+8) "/r32\n") -15471 $translate-mu-get-stmt:end: -15472 # . restore registers -15473 5a/pop-to-edx -15474 59/pop-to-ecx -15475 58/pop-to-eax -15476 # . epilogue -15477 89/<- %esp 5/r32/ebp -15478 5d/pop-to-ebp -15479 c3/return -15480 -15481 translate-mu-allocate-stmt: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) -15482 # . prologue -15483 55/push-ebp -15484 89/<- %ebp 4/r32/esp -15485 # . save registers -15486 50/push-eax -15487 56/push-esi -15488 57/push-edi -15489 # esi = stmt -15490 8b/-> *(ebp+0xc) 6/r32/esi -15491 # var target/edi: (addr stmt-var) = stmt->inouts[0] -15492 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax -15493 89/<- %edi 0/r32/eax -15494 # -15495 (emit-indent *(ebp+8) *Curr-block-depth) -15496 (write-buffered *(ebp+8) "(allocate Heap ") -15497 (addr-handle-payload-size %edi *(ebp+0x10) *(ebp+0x14)) # => eax -15498 (write-int32-hex-buffered *(ebp+8) %eax) -15499 (emit-subx-call-operand *(ebp+8) %edi) -15500 (write-buffered *(ebp+8) ")\n") -15501 $translate-mu-allocate-stmt:end: -15502 # . restore registers -15503 5f/pop-to-edi -15504 5e/pop-to-esi -15505 58/pop-to-eax -15506 # . epilogue -15507 89/<- %esp 5/r32/ebp -15508 5d/pop-to-ebp -15509 c3/return -15510 -15511 addr-handle-payload-size: # s: (addr stmt-var), err: (addr buffered-file), ed: (addr exit-descriptor) -> result/eax: int -15512 # . prologue -15513 55/push-ebp -15514 89/<- %ebp 4/r32/esp -15515 # var t/eax: (addr type-tree) = s->value->type -15516 8b/-> *(ebp+8) 0/r32/eax -15517 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -15518 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax -15519 # TODO: check eax != 0 -15520 # TODO: check !t->is-atom? -15521 # TODO: check t->left == addr -15522 # t = t->right -15523 $addr-handle-payload-size:skip-addr: -15524 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax -15525 # TODO: check eax != 0 -15526 # TODO: check !t->is-atom? -15527 # TODO: check t->left == handle -15528 # t = t->right -15529 $addr-handle-payload-size:skip-handle: -15530 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax -15531 # TODO: check eax != 0 -15532 # if !t->is-atom? t = t->left -15533 81 7/subop/compare *eax 0/imm32/false -15534 { -15535 75/jump-if-!= break/disp8 -15536 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax -15537 } -15538 # TODO: check t->is-atom? -15539 # return size(t->value) -15540 (size-of-type-id *(eax+4)) # Type-tree-value => eax -15541 $addr-handle-payload-size:end: -15542 # . epilogue -15543 89/<- %esp 5/r32/ebp -15544 5d/pop-to-ebp -15545 c3/return -15546 -15547 addr-payload-size: # s: (addr stmt-var), err: (addr buffered-file), ed: (addr exit-descriptor) -> result/eax: int -15548 # . prologue -15549 55/push-ebp -15550 89/<- %ebp 4/r32/esp -15551 # var t/eax: (addr type-tree) = s->value->type -15552 8b/-> *(ebp+8) 0/r32/eax -15553 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -15554 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax -15555 # TODO: check eax != 0 -15556 # TODO: check !t->is-atom? -15557 # TODO: check t->left == addr -15558 # t = t->right -15559 $addr-payload-size:skip-addr: -15560 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax -15561 # TODO: check eax != 0 -15562 # if !t->is-atom? t = t->left -15563 81 7/subop/compare *eax 0/imm32/false -15564 { -15565 75/jump-if-!= break/disp8 -15566 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax -15567 } -15568 # TODO: check t->is-atom? -15569 # return size(t->value) -15570 (size-of-type-id *(eax+4)) # Type-tree-value => eax -15571 $addr-payload-size:end: -15572 # . epilogue -15573 89/<- %esp 5/r32/ebp -15574 5d/pop-to-ebp -15575 c3/return -15576 -15577 translate-mu-populate-stmt: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) -15578 # . prologue -15579 55/push-ebp -15580 89/<- %ebp 4/r32/esp -15581 # . save registers -15582 50/push-eax -15583 51/push-ecx -15584 56/push-esi -15585 57/push-edi -15586 # esi = stmt -15587 8b/-> *(ebp+0xc) 6/r32/esi -15588 # var target/edi: (addr stmt-var) = stmt->inouts[0] -15589 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax -15590 89/<- %edi 0/r32/eax -15591 # var len/ecx: (addr stmt-var) = stmt->inouts[1] -15592 (lookup *(edi+8) *(edi+0xc)) # Stmt-var-next Stmt-var-next => eax -15593 89/<- %ecx 0/r32/eax -15594 # -15595 (emit-indent *(ebp+8) *Curr-block-depth) -15596 (write-buffered *(ebp+8) "(allocate-array2 Heap ") -15597 (addr-handle-array-payload-size %edi *(ebp+0x10) *(ebp+0x14)) # => eax -15598 (write-int32-hex-buffered *(ebp+8) %eax) -15599 (emit-subx-call-operand *(ebp+8) %ecx) -15600 (emit-subx-call-operand *(ebp+8) %edi) -15601 (write-buffered *(ebp+8) ")\n") -15602 $translate-mu-populate-stmt:end: -15603 # . restore registers -15604 5f/pop-to-edi -15605 5e/pop-to-esi -15606 59/pop-to-ecx -15607 58/pop-to-eax -15608 # . epilogue -15609 89/<- %esp 5/r32/ebp -15610 5d/pop-to-ebp -15611 c3/return -15612 -15613 translate-mu-populate-stream-stmt: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) -15614 # . prologue -15615 55/push-ebp -15616 89/<- %ebp 4/r32/esp -15617 # . save registers -15618 50/push-eax -15619 51/push-ecx -15620 56/push-esi -15621 57/push-edi -15622 # esi = stmt -15623 8b/-> *(ebp+0xc) 6/r32/esi -15624 # var target/edi: (addr stmt-var) = stmt->inouts[0] -15625 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax -15626 89/<- %edi 0/r32/eax -15627 # var len/ecx: (addr stmt-var) = stmt->inouts[1] -15628 (lookup *(edi+8) *(edi+0xc)) # Stmt-var-next Stmt-var-next => eax -15629 89/<- %ecx 0/r32/eax -15630 # -15631 (emit-indent *(ebp+8) *Curr-block-depth) -15632 (write-buffered *(ebp+8) "(new-stream Heap ") -15633 (addr-handle-stream-payload-size %edi *(ebp+0x10) *(ebp+0x14)) # => eax -15634 (write-int32-hex-buffered *(ebp+8) %eax) -15635 (emit-subx-call-operand *(ebp+8) %ecx) -15636 (emit-subx-call-operand *(ebp+8) %edi) -15637 (write-buffered *(ebp+8) ")\n") -15638 $translate-mu-populate-stream-stmt:end: -15639 # . restore registers -15640 5f/pop-to-edi -15641 5e/pop-to-esi -15642 59/pop-to-ecx -15643 58/pop-to-eax -15644 # . epilogue -15645 89/<- %esp 5/r32/ebp -15646 5d/pop-to-ebp -15647 c3/return -15648 -15649 translate-mu-read-from-stream-stmt: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) -15650 # . prologue -15651 55/push-ebp -15652 89/<- %ebp 4/r32/esp -15653 # . save registers -15654 50/push-eax -15655 51/push-ecx -15656 56/push-esi -15657 57/push-edi -15658 # esi = stmt -15659 8b/-> *(ebp+0xc) 6/r32/esi -15660 # var stream/ecx: (addr stmt-var) = stmt->inouts[0] -15661 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax -15662 89/<- %ecx 0/r32/eax -15663 # var target/edi: (addr stmt-var) = stmt->inouts[1] -15664 (lookup *(ecx+8) *(ecx+0xc)) # Stmt-var-next Stmt-var-next => eax -15665 89/<- %edi 0/r32/eax -15666 # -15667 (emit-indent *(ebp+8) *Curr-block-depth) -15668 (write-buffered *(ebp+8) "(read-from-stream") -15669 (emit-subx-call-operand *(ebp+8) %ecx) -15670 (emit-subx-call-operand *(ebp+8) %edi) -15671 (write-buffered *(ebp+8) Space) -15672 (addr-payload-size %edi *(ebp+0x10) *(ebp+0x14)) # => eax -15673 (write-int32-hex-buffered *(ebp+8) %eax) -15674 (write-buffered *(ebp+8) ")\n") -15675 $translate-mu-read-from-stream-stmt:end: -15676 # . restore registers -15677 5f/pop-to-edi -15678 5e/pop-to-esi -15679 59/pop-to-ecx -15680 58/pop-to-eax -15681 # . epilogue -15682 89/<- %esp 5/r32/ebp -15683 5d/pop-to-ebp -15684 c3/return -15685 -15686 translate-mu-write-to-stream-stmt: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) -15687 # . prologue -15688 55/push-ebp -15689 89/<- %ebp 4/r32/esp -15690 # . save registers -15691 50/push-eax -15692 51/push-ecx -15693 56/push-esi -15694 57/push-edi -15695 # esi = stmt -15696 8b/-> *(ebp+0xc) 6/r32/esi -15697 # var stream/ecx: (addr stmt-var) = stmt->inouts[0] -15698 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax -15699 89/<- %ecx 0/r32/eax -15700 # var target/edi: (addr stmt-var) = stmt->inouts[1] -15701 (lookup *(ecx+8) *(ecx+0xc)) # Stmt-var-next Stmt-var-next => eax -15702 89/<- %edi 0/r32/eax -15703 # -15704 (emit-indent *(ebp+8) *Curr-block-depth) -15705 (write-buffered *(ebp+8) "(write-to-stream") -15706 (emit-subx-call-operand *(ebp+8) %ecx) -15707 (flush *(ebp+8)) -15708 (emit-subx-call-operand *(ebp+8) %edi) -15709 (flush *(ebp+8)) -15710 (write-buffered *(ebp+8) Space) -15711 (flush *(ebp+8)) -15712 (addr-payload-size %edi *(ebp+0x10) *(ebp+0x14)) # => eax -15713 (write-int32-hex-buffered *(ebp+8) %eax) -15714 (write-buffered *(ebp+8) ")\n") -15715 $translate-mu-write-to-stream-stmt:end: -15716 # . restore registers -15717 5f/pop-to-edi -15718 5e/pop-to-esi -15719 59/pop-to-ecx -15720 58/pop-to-eax -15721 # . epilogue -15722 89/<- %esp 5/r32/ebp -15723 5d/pop-to-ebp -15724 c3/return -15725 -15726 addr-handle-array-payload-size: # s: (addr stmt-var), err: (addr buffered-file), ed: (addr exit-descriptor) -> result/eax: int -15727 # . prologue -15728 55/push-ebp -15729 89/<- %ebp 4/r32/esp -15730 # var t/eax: (addr type-tree) = s->value->type -15731 8b/-> *(ebp+8) 0/r32/eax -15732 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -15733 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax -15734 # TODO: check eax != 0 -15735 # TODO: check !t->is-atom? -15736 # TODO: check t->left == addr -15737 # t = t->right -15738 $addr-handle-array-payload-size:skip-addr: -15739 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax -15740 # TODO: check eax != 0 -15741 # TODO: check !t->is-atom? -15742 # TODO: check t->left == handle -15743 # t = t->right -15744 $addr-handle-array-payload-size:skip-handle: -15745 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax -15746 # TODO: check eax != 0 -15747 # TODO: check !t->is-atom? -15748 # TODO: check t->left == array -15749 # t = t->right -15750 $addr-handle-array-payload-size:skip-array: -15751 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax -15752 # TODO: check eax != 0 -15753 # if !t->is-atom? t = t->left -15754 81 7/subop/compare *eax 0/imm32/false -15755 { -15756 75/jump-if-!= break/disp8 -15757 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax -15758 } -15759 $addr-handle-array-payload-size:compute-size: -15760 # TODO: check t->is-atom? -15761 # return size(t->value) -15762 (size-of-type-id-as-array-element *(eax+4)) # Type-tree-value => eax -15763 $addr-handle-array-payload-size:end: -15764 # . epilogue -15765 89/<- %esp 5/r32/ebp -15766 5d/pop-to-ebp -15767 c3/return -15768 -15769 addr-handle-stream-payload-size: # s: (addr stmt-var), err: (addr buffered-file), ed: (addr exit-descriptor) -> result/eax: int -15770 # . prologue -15771 55/push-ebp -15772 89/<- %ebp 4/r32/esp -15773 # var t/eax: (addr type-tree) = s->value->type -15774 8b/-> *(ebp+8) 0/r32/eax -15775 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -15776 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax -15777 # TODO: check eax != 0 -15778 # TODO: check !t->is-atom? -15779 # TODO: check t->left == addr -15780 # t = t->right -15781 $addr-handle-stream-payload-size:skip-addr: -15782 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax -15783 # TODO: check eax != 0 -15784 # TODO: check !t->is-atom? -15785 # TODO: check t->left == handle -15786 # t = t->right -15787 $addr-handle-stream-payload-size:skip-handle: -15788 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax -15789 # TODO: check eax != 0 -15790 # TODO: check !t->is-atom? -15791 # TODO: check t->left == stream -15792 # t = t->right -15793 $addr-handle-stream-payload-size:skip-stream: -15794 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax -15795 # TODO: check eax != 0 -15796 # if !t->is-atom? t = t->left -15797 81 7/subop/compare *eax 0/imm32/false -15798 { -15799 75/jump-if-!= break/disp8 -15800 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax -15801 } -15802 $addr-handle-stream-payload-size:compute-size: -15803 # TODO: check t->is-atom? -15804 # return size(t->value) -15805 (size-of-type-id-as-array-element *(eax+4)) # Type-tree-value => eax -15806 $addr-handle-stream-payload-size:end: -15807 # . epilogue -15808 89/<- %esp 5/r32/ebp -15809 5d/pop-to-ebp -15810 c3/return -15811 -15812 power-of-2?: # n: int, err: (addr buffered-file), ed: (addr exit-descriptor) -> result/eax: boolean -15813 # precondition: n is positive -15814 # . prologue -15815 55/push-ebp -15816 89/<- %ebp 4/r32/esp -15817 # eax = n -15818 8b/-> *(ebp+8) 0/r32/eax -15819 # if (n < 0) abort -15820 3d/compare-eax-with 0/imm32 -15821 0f 8c/jump-if-< $power-of-2?:abort/disp32 -15822 # var tmp/eax: int = n-1 -15823 48/decrement-eax -15824 # var tmp2/eax: int = n & tmp -15825 23/and-> *(ebp+8) 0/r32/eax -15826 # return (tmp2 == 0) -15827 3d/compare-eax-and 0/imm32 -15828 0f 94/set-byte-if-= %al -15829 81 4/subop/and %eax 0xff/imm32 -15830 $power-of-2?:end: -15831 # . epilogue -15832 89/<- %esp 5/r32/ebp -15833 5d/pop-to-ebp -15834 c3/return -15835 -15836 $power-of-2?:abort: -15837 (write-buffered *(ebp+0xc) "power-of-2?: negative number\n") -15838 (flush *(ebp+0xc)) -15839 (stop *(ebp+0x10) 1) -15840 # never gets here -15841 -15842 num-shift-rights: # n: int -> result/eax: int -15843 # precondition: n is a positive power of 2 -15844 # . prologue -15845 55/push-ebp -15846 89/<- %ebp 4/r32/esp -15847 # . save registers -15848 51/push-ecx -15849 # var curr/ecx: int = n -15850 8b/-> *(ebp+8) 1/r32/ecx -15851 # result = 0 -15852 b8/copy-to-eax 0/imm32 -15853 { -15854 # if (curr <= 1) break -15855 81 7/subop/compare %ecx 1/imm32 -15856 7e/jump-if-<= break/disp8 -15857 40/increment-eax -15858 c1/shift 5/subop/arithmetic-right %ecx 1/imm8 -15859 eb/jump loop/disp8 -15860 } -15861 $num-shift-rights:end: -15862 # . restore registers -15863 59/pop-to-ecx -15864 # . epilogue -15865 89/<- %esp 5/r32/ebp -15866 5d/pop-to-ebp -15867 c3/return -15868 -15869 mu-get-offset: # stmt: (addr stmt) -> result/eax: int -15870 # . prologue -15871 55/push-ebp -15872 89/<- %ebp 4/r32/esp -15873 # var second-inout/eax: (addr stmt-var) = stmt->inouts->next -15874 8b/-> *(ebp+8) 0/r32/eax -15875 (lookup *(eax+0xc) *(eax+0x10)) # Stmt1-inouts Stmt1-inouts => eax -15876 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax -15877 # var output-var/eax: (addr var) = second-inout->value -15878 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -15879 #? (write-buffered Stderr "mu-get-offset: ") -15880 #? (write-int32-hex-buffered Stderr %eax) -15881 #? (write-buffered Stderr " name: ") -15882 #? 50/push-eax -15883 #? (lookup *eax *(eax+4)) # Var-name -15884 #? (write-buffered Stderr %eax) -15885 #? 58/pop-to-eax -15886 #? (write-buffered Stderr Newline) -15887 #? (flush Stderr) -15888 # return output-var->stack-offset -15889 8b/-> *(eax+0x14) 0/r32/eax # Var-offset -15890 #? (write-buffered Stderr "=> ") -15891 #? (write-int32-hex-buffered Stderr %eax) -15892 #? (write-buffered Stderr Newline) -15893 #? (flush Stderr) -15894 $emit-get-offset:end: -15895 # . epilogue -15896 89/<- %esp 5/r32/ebp -15897 5d/pop-to-ebp -15898 c3/return -15899 -15900 emit-subx-block: # out: (addr buffered-file), block: (addr block), vars: (addr stack live-var), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -15901 # . prologue -15902 55/push-ebp -15903 89/<- %ebp 4/r32/esp -15904 # . save registers -15905 50/push-eax -15906 51/push-ecx -15907 56/push-esi -15908 # esi = block -15909 8b/-> *(ebp+0xc) 6/r32/esi -15910 # block->var->block-depth = *Curr-block-depth -15911 (lookup *(esi+0xc) *(esi+0x10)) # Block-var Block-var => eax -15912 8b/-> *Curr-block-depth 1/r32/ecx -15913 89/<- *(eax+0x10) 1/r32/ecx # Var-block-depth -15914 # var stmts/eax: (addr list stmt) = lookup(block->statements) -15915 (lookup *(esi+4) *(esi+8)) # Block-stmts Block-stmts => eax -15916 # -15917 { -15918 $emit-subx-block:check-empty: -15919 3d/compare-eax-and 0/imm32 -15920 0f 84/jump-if-= break/disp32 -15921 (emit-indent *(ebp+8) *Curr-block-depth) -15922 (write-buffered *(ebp+8) "{\n") -15923 # var v/ecx: (addr var) = lookup(block->var) -15924 (lookup *(esi+0xc) *(esi+0x10)) # Block-var Block-var => eax -15925 89/<- %ecx 0/r32/eax -15926 # -15927 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax -15928 (write-buffered *(ebp+8) %eax) -15929 (write-buffered *(ebp+8) ":loop:\n") -15930 ff 0/subop/increment *Curr-block-depth -15931 (push *(ebp+0x10) *(esi+0xc)) # Block-var -15932 (push *(ebp+0x10) *(esi+0x10)) # Block-var -15933 (push *(ebp+0x10) 0) # false -15934 # emit block->statements -15935 (lookup *(esi+4) *(esi+8)) # Block-stmts Block-stmts => eax -15936 (emit-subx-stmt-list *(ebp+8) %eax *(ebp+0x10) *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c)) -15937 (pop *(ebp+0x10)) # => eax -15938 (pop *(ebp+0x10)) # => eax -15939 (pop *(ebp+0x10)) # => eax -15940 ff 1/subop/decrement *Curr-block-depth -15941 (emit-indent *(ebp+8) *Curr-block-depth) -15942 (write-buffered *(ebp+8) "}\n") -15943 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax -15944 (write-buffered *(ebp+8) %eax) -15945 (write-buffered *(ebp+8) ":break:\n") -15946 } -15947 $emit-subx-block:end: -15948 # . restore registers -15949 5e/pop-to-esi -15950 59/pop-to-ecx -15951 58/pop-to-eax -15952 # . epilogue -15953 89/<- %esp 5/r32/ebp -15954 5d/pop-to-ebp -15955 c3/return -15956 -15957 # Primitives supported -15958 # See mu_instructions for a summary of this linked-list data structure. -15959 # -15960 # For each operation, put variants with hard-coded registers before flexible ones. -15961 # -15962 # Unfortunately, our restrictions on addresses require that various fields in -15963 # primitives be handles, which complicates these definitions. -15964 # - we need to insert dummy fields all over the place for fake alloc-ids -15965 # - we can't use our syntax sugar of quoted literals for string fields -15966 # -15967 # Fake alloc-ids are needed because our type definitions up top require -15968 # handles but it's clearer to statically allocate these long-lived objects. -15969 # Fake alloc-ids are perfectly safe, but they can't be reclaimed. -15970 # -15971 # Every 'object' below starts with a fake alloc-id. It may also contain other -15972 # fake alloc-ids for various handle fields. -15973 # -15974 # I think of objects starting with a fake alloc-id as having type 'payload'. -15975 # It's not really intended to be created dynamically; for that use `allocate` -15976 # as usual. -15977 # -15978 # Idea for a notation to simplify such definitions: -15979 # _Primitive-increment-eax: # (payload primitive) -15980 # 0x11/alloc-id:fake:payload -15981 # 0x11 @(0x11 "increment") # name -15982 # 0 0 # inouts -15983 # 0x11 @(0x11/payload -15984 # 0x11 @(0x11/payload # List-value -15985 # 0 0 # Var-name -15986 # 0x11 @(0x11 # Var-type -15987 # 1/is-atom -15988 # 1/value 0/unused # Type-tree-left -15989 # 0 0 # Type-tree-right -15990 # ) -15991 # 1 # block-depth -15992 # 0 # stack-offset -15993 # 0x11 @(0x11 "eax") # Var-register -15994 # ) -15995 # 0 0) # List-next -15996 # ... -15997 # _Primitive-increment-ecx/imm32/next -15998 # ... -15999 # Awfully complex and non-obvious. But also clearly signals there's something -16000 # to learn here, so may be worth trying. -16001 # -16002 # '@' is just an initial thought. Punctuation used so far in Mu: () * % # / " -16003 # -16004 # For now we'll continue to just use comments and manually ensure they stay up -16005 # to date. -16006 == data -16007 Primitives: # (addr primitive) -16008 # - increment/decrement -16009 _Primitive-increment-eax: # (addr primitive) -16010 # var/eax <- increment => 40/increment-eax -16011 0x11/imm32/alloc-id:fake -16012 _string-increment/imm32/name -16013 0/imm32/no-inouts -16014 0/imm32/no-inouts -16015 0x11/imm32/alloc-id:fake -16016 Single-int-var-in-eax/imm32/outputs -16017 0x11/imm32/alloc-id:fake -16018 _string_40_increment_eax/imm32/subx-name -16019 0/imm32/no-rm32 -16020 0/imm32/no-r32 -16021 0/imm32/no-imm32 -16022 0/imm32/no-imm8 -16023 0/imm32/no-disp32 -16024 0/imm32/output-is-write-only -16025 0x11/imm32/alloc-id:fake -16026 _Primitive-increment-ecx/imm32/next -16027 _Primitive-increment-ecx: # (payload primitive) -16028 0x11/imm32/alloc-id:fake:payload -16029 # var/ecx <- increment => 41/increment-ecx -16030 0x11/imm32/alloc-id:fake -16031 _string-increment/imm32/name -16032 0/imm32/no-inouts -16033 0/imm32/no-inouts -16034 0x11/imm32/alloc-id:fake -16035 Single-int-var-in-ecx/imm32/outputs -16036 0x11/imm32/alloc-id:fake -16037 _string_41_increment_ecx/imm32/subx-name -16038 0/imm32/no-rm32 -16039 0/imm32/no-r32 -16040 0/imm32/no-imm32 -16041 0/imm32/no-imm8 -16042 0/imm32/no-disp32 -16043 0/imm32/output-is-write-only -16044 0x11/imm32/alloc-id:fake -16045 _Primitive-increment-edx/imm32/next -16046 _Primitive-increment-edx: # (payload primitive) -16047 0x11/imm32/alloc-id:fake:payload -16048 # var/edx <- increment => 42/increment-edx -16049 0x11/imm32/alloc-id:fake -16050 _string-increment/imm32/name -16051 0/imm32/no-inouts -16052 0/imm32/no-inouts -16053 0x11/imm32/alloc-id:fake -16054 Single-int-var-in-edx/imm32/outputs -16055 0x11/imm32/alloc-id:fake -16056 _string_42_increment_edx/imm32/subx-name -16057 0/imm32/no-rm32 -16058 0/imm32/no-r32 -16059 0/imm32/no-imm32 -16060 0/imm32/no-imm8 -16061 0/imm32/no-disp32 -16062 0/imm32/output-is-write-only -16063 0x11/imm32/alloc-id:fake -16064 _Primitive-increment-ebx/imm32/next -16065 _Primitive-increment-ebx: # (payload primitive) -16066 0x11/imm32/alloc-id:fake:payload -16067 # var/ebx <- increment => 43/increment-ebx -16068 0x11/imm32/alloc-id:fake -16069 _string-increment/imm32/name -16070 0/imm32/no-inouts -16071 0/imm32/no-inouts -16072 0x11/imm32/alloc-id:fake -16073 Single-int-var-in-ebx/imm32/outputs -16074 0x11/imm32/alloc-id:fake -16075 _string_43_increment_ebx/imm32/subx-name -16076 0/imm32/no-rm32 -16077 0/imm32/no-r32 -16078 0/imm32/no-imm32 -16079 0/imm32/no-imm8 -16080 0/imm32/no-disp32 -16081 0/imm32/output-is-write-only -16082 0x11/imm32/alloc-id:fake -16083 _Primitive-increment-esi/imm32/next -16084 _Primitive-increment-esi: # (payload primitive) -16085 0x11/imm32/alloc-id:fake:payload -16086 # var/esi <- increment => 46/increment-esi -16087 0x11/imm32/alloc-id:fake -16088 _string-increment/imm32/name -16089 0/imm32/no-inouts -16090 0/imm32/no-inouts -16091 0x11/imm32/alloc-id:fake -16092 Single-int-var-in-esi/imm32/outputs -16093 0x11/imm32/alloc-id:fake -16094 _string_46_increment_esi/imm32/subx-name -16095 0/imm32/no-rm32 -16096 0/imm32/no-r32 -16097 0/imm32/no-imm32 -16098 0/imm32/no-imm8 -16099 0/imm32/no-disp32 -16100 0/imm32/output-is-write-only -16101 0x11/imm32/alloc-id:fake -16102 _Primitive-increment-edi/imm32/next -16103 _Primitive-increment-edi: # (payload primitive) -16104 0x11/imm32/alloc-id:fake:payload -16105 # var/edi <- increment => 47/increment-edi -16106 0x11/imm32/alloc-id:fake -16107 _string-increment/imm32/name -16108 0/imm32/no-inouts -16109 0/imm32/no-inouts -16110 0x11/imm32/alloc-id:fake -16111 Single-int-var-in-edi/imm32/outputs -16112 0x11/imm32/alloc-id:fake -16113 _string_47_increment_edi/imm32/subx-name -16114 0/imm32/no-rm32 -16115 0/imm32/no-r32 -16116 0/imm32/no-imm32 -16117 0/imm32/no-imm8 -16118 0/imm32/no-disp32 -16119 0/imm32/output-is-write-only -16120 0x11/imm32/alloc-id:fake -16121 _Primitive-decrement-eax/imm32/next -16122 _Primitive-decrement-eax: # (payload primitive) -16123 0x11/imm32/alloc-id:fake:payload -16124 # var/eax <- decrement => 48/decrement-eax -16125 0x11/imm32/alloc-id:fake -16126 _string-decrement/imm32/name -16127 0/imm32/no-inouts -16128 0/imm32/no-inouts -16129 0x11/imm32/alloc-id:fake -16130 Single-int-var-in-eax/imm32/outputs -16131 0x11/imm32/alloc-id:fake -16132 _string_48_decrement_eax/imm32/subx-name -16133 0/imm32/no-rm32 -16134 0/imm32/no-r32 -16135 0/imm32/no-imm32 -16136 0/imm32/no-imm8 -16137 0/imm32/no-disp32 -16138 0/imm32/output-is-write-only -16139 0x11/imm32/alloc-id:fake -16140 _Primitive-decrement-ecx/imm32/next -16141 _Primitive-decrement-ecx: # (payload primitive) -16142 0x11/imm32/alloc-id:fake:payload -16143 # var/ecx <- decrement => 49/decrement-ecx -16144 0x11/imm32/alloc-id:fake -16145 _string-decrement/imm32/name -16146 0/imm32/no-inouts -16147 0/imm32/no-inouts -16148 0x11/imm32/alloc-id:fake -16149 Single-int-var-in-ecx/imm32/outputs -16150 0x11/imm32/alloc-id:fake -16151 _string_49_decrement_ecx/imm32/subx-name -16152 0/imm32/no-rm32 -16153 0/imm32/no-r32 -16154 0/imm32/no-imm32 -16155 0/imm32/no-imm8 -16156 0/imm32/no-disp32 -16157 0/imm32/output-is-write-only -16158 0x11/imm32/alloc-id:fake -16159 _Primitive-decrement-edx/imm32/next -16160 _Primitive-decrement-edx: # (payload primitive) -16161 0x11/imm32/alloc-id:fake:payload -16162 # var/edx <- decrement => 4a/decrement-edx -16163 0x11/imm32/alloc-id:fake -16164 _string-decrement/imm32/name -16165 0/imm32/no-inouts -16166 0/imm32/no-inouts -16167 0x11/imm32/alloc-id:fake -16168 Single-int-var-in-edx/imm32/outputs -16169 0x11/imm32/alloc-id:fake -16170 _string_4a_decrement_edx/imm32/subx-name -16171 0/imm32/no-rm32 -16172 0/imm32/no-r32 -16173 0/imm32/no-imm32 -16174 0/imm32/no-imm8 -16175 0/imm32/no-disp32 -16176 0/imm32/output-is-write-only -16177 0x11/imm32/alloc-id:fake -16178 _Primitive-decrement-ebx/imm32/next -16179 _Primitive-decrement-ebx: # (payload primitive) -16180 0x11/imm32/alloc-id:fake:payload -16181 # var/ebx <- decrement => 4b/decrement-ebx -16182 0x11/imm32/alloc-id:fake -16183 _string-decrement/imm32/name -16184 0/imm32/no-inouts -16185 0/imm32/no-inouts -16186 0x11/imm32/alloc-id:fake -16187 Single-int-var-in-ebx/imm32/outputs -16188 0x11/imm32/alloc-id:fake -16189 _string_4b_decrement_ebx/imm32/subx-name -16190 0/imm32/no-rm32 -16191 0/imm32/no-r32 -16192 0/imm32/no-imm32 -16193 0/imm32/no-imm8 -16194 0/imm32/no-disp32 -16195 0/imm32/output-is-write-only -16196 0x11/imm32/alloc-id:fake -16197 _Primitive-decrement-esi/imm32/next -16198 _Primitive-decrement-esi: # (payload primitive) -16199 0x11/imm32/alloc-id:fake:payload -16200 # var/esi <- decrement => 4e/decrement-esi -16201 0x11/imm32/alloc-id:fake -16202 _string-decrement/imm32/name -16203 0/imm32/no-inouts -16204 0/imm32/no-inouts -16205 0x11/imm32/alloc-id:fake -16206 Single-int-var-in-esi/imm32/outputs -16207 0x11/imm32/alloc-id:fake -16208 _string_4e_decrement_esi/imm32/subx-name -16209 0/imm32/no-rm32 -16210 0/imm32/no-r32 -16211 0/imm32/no-imm32 -16212 0/imm32/no-imm8 -16213 0/imm32/no-disp32 -16214 0/imm32/output-is-write-only -16215 0x11/imm32/alloc-id:fake -16216 _Primitive-decrement-edi/imm32/next -16217 _Primitive-decrement-edi: # (payload primitive) -16218 0x11/imm32/alloc-id:fake:payload -16219 # var/edi <- decrement => 4f/decrement-edi -16220 0x11/imm32/alloc-id:fake -16221 _string-decrement/imm32/name -16222 0/imm32/no-inouts -16223 0/imm32/no-inouts -16224 0x11/imm32/alloc-id:fake -16225 Single-int-var-in-edi/imm32/outputs -16226 0x11/imm32/alloc-id:fake -16227 _string_4f_decrement_edi/imm32/subx-name -16228 0/imm32/no-rm32 -16229 0/imm32/no-r32 -16230 0/imm32/no-imm32 -16231 0/imm32/no-imm8 -16232 0/imm32/no-disp32 -16233 0/imm32/output-is-write-only -16234 0x11/imm32/alloc-id:fake -16235 _Primitive-increment-mem/imm32/next -16236 _Primitive-increment-mem: # (payload primitive) -16237 0x11/imm32/alloc-id:fake:payload -16238 # increment var => ff 0/subop/increment *(ebp+__) -16239 0x11/imm32/alloc-id:fake -16240 _string-increment/imm32/name -16241 0x11/imm32/alloc-id:fake -16242 Single-int-var-in-mem/imm32/inouts -16243 0/imm32/no-outputs -16244 0/imm32/no-outputs -16245 0x11/imm32/alloc-id:fake -16246 _string_ff_subop_increment/imm32/subx-name -16247 1/imm32/rm32-is-first-inout -16248 0/imm32/no-r32 -16249 0/imm32/no-imm32 -16250 0/imm32/no-imm8 -16251 0/imm32/no-disp32 -16252 0/imm32/output-is-write-only -16253 0x11/imm32/alloc-id:fake -16254 _Primitive-increment-reg/imm32/next -16255 _Primitive-increment-reg: # (payload primitive) -16256 0x11/imm32/alloc-id:fake:payload -16257 # var/reg <- increment => ff 0/subop/increment %__ -16258 0x11/imm32/alloc-id:fake -16259 _string-increment/imm32/name -16260 0/imm32/no-inouts -16261 0/imm32/no-inouts -16262 0x11/imm32/alloc-id:fake -16263 Single-int-var-in-some-register/imm32/outputs -16264 0x11/imm32/alloc-id:fake -16265 _string_ff_subop_increment/imm32/subx-name -16266 3/imm32/rm32-is-first-output -16267 0/imm32/no-r32 -16268 0/imm32/no-imm32 -16269 0/imm32/no-imm8 -16270 0/imm32/no-disp32 -16271 0/imm32/output-is-write-only -16272 0x11/imm32/alloc-id:fake -16273 _Primitive-decrement-mem/imm32/next -16274 _Primitive-decrement-mem: # (payload primitive) -16275 0x11/imm32/alloc-id:fake:payload -16276 # decrement var => ff 1/subop/decrement *(ebp+__) -16277 0x11/imm32/alloc-id:fake -16278 _string-decrement/imm32/name -16279 0x11/imm32/alloc-id:fake -16280 Single-int-var-in-mem/imm32/inouts -16281 0/imm32/no-outputs -16282 0/imm32/no-outputs -16283 0x11/imm32/alloc-id:fake -16284 _string_ff_subop_decrement/imm32/subx-name -16285 1/imm32/rm32-is-first-inout -16286 0/imm32/no-r32 -16287 0/imm32/no-imm32 -16288 0/imm32/no-imm8 -16289 0/imm32/no-disp32 -16290 0/imm32/output-is-write-only -16291 0x11/imm32/alloc-id:fake -16292 _Primitive-decrement-reg/imm32/next -16293 _Primitive-decrement-reg: # (payload primitive) -16294 0x11/imm32/alloc-id:fake:payload -16295 # var/reg <- decrement => ff 1/subop/decrement %__ -16296 0x11/imm32/alloc-id:fake -16297 _string-decrement/imm32/name -16298 0/imm32/no-inouts -16299 0/imm32/no-inouts -16300 0x11/imm32/alloc-id:fake -16301 Single-int-var-in-some-register/imm32/outputs -16302 0x11/imm32/alloc-id:fake -16303 _string_ff_subop_decrement/imm32/subx-name -16304 3/imm32/rm32-is-first-output -16305 0/imm32/no-r32 -16306 0/imm32/no-imm32 -16307 0/imm32/no-imm8 -16308 0/imm32/no-disp32 -16309 0/imm32/output-is-write-only -16310 0x11/imm32/alloc-id:fake -16311 _Primitive-add-to-eax/imm32/next -16312 # - add -16313 _Primitive-add-to-eax: # (payload primitive) -16314 0x11/imm32/alloc-id:fake:payload -16315 # var/eax <- add lit => 05/add-to-eax lit/imm32 -16316 0x11/imm32/alloc-id:fake -16317 _string-add/imm32/name -16318 0x11/imm32/alloc-id:fake -16319 Single-lit-var/imm32/inouts -16320 0x11/imm32/alloc-id:fake -16321 Single-int-var-in-eax/imm32/outputs -16322 0x11/imm32/alloc-id:fake -16323 _string_05_add_to_eax/imm32/subx-name -16324 0/imm32/no-rm32 -16325 0/imm32/no-r32 -16326 1/imm32/imm32-is-first-inout -16327 0/imm32/no-imm8 -16328 0/imm32/no-disp32 -16329 0/imm32/output-is-write-only -16330 0x11/imm32/alloc-id:fake -16331 _Primitive-add-reg-to-reg/imm32/next -16332 _Primitive-add-reg-to-reg: # (payload primitive) -16333 0x11/imm32/alloc-id:fake:payload -16334 # var1/reg <- add var2/reg => 01/add-to var1/rm32 var2/r32 -16335 0x11/imm32/alloc-id:fake -16336 _string-add/imm32/name -16337 0x11/imm32/alloc-id:fake -16338 Single-int-var-in-some-register/imm32/inouts -16339 0x11/imm32/alloc-id:fake -16340 Single-int-var-in-some-register/imm32/outputs -16341 0x11/imm32/alloc-id:fake -16342 _string_01_add_to/imm32/subx-name -16343 3/imm32/rm32-is-first-output -16344 1/imm32/r32-is-first-inout -16345 0/imm32/no-imm32 -16346 0/imm32/no-imm8 -16347 0/imm32/no-disp32 -16348 0/imm32/output-is-write-only -16349 0x11/imm32/alloc-id:fake -16350 _Primitive-add-reg-to-mem/imm32/next -16351 _Primitive-add-reg-to-mem: # (payload primitive) -16352 0x11/imm32/alloc-id:fake:payload -16353 # add-to var1 var2/reg => 01/add-to var1 var2/r32 -16354 0x11/imm32/alloc-id:fake -16355 _string-add-to/imm32/name -16356 0x11/imm32/alloc-id:fake -16357 Two-args-int-stack-int-reg/imm32/inouts -16358 0/imm32/no-outputs -16359 0/imm32/no-outputs -16360 0x11/imm32/alloc-id:fake -16361 _string_01_add_to/imm32/subx-name -16362 1/imm32/rm32-is-first-inout -16363 2/imm32/r32-is-second-inout -16364 0/imm32/no-imm32 -16365 0/imm32/no-imm8 -16366 0/imm32/no-disp32 -16367 0/imm32/output-is-write-only -16368 0x11/imm32/alloc-id:fake -16369 _Primitive-add-mem-to-reg/imm32/next -16370 _Primitive-add-mem-to-reg: # (payload primitive) -16371 0x11/imm32/alloc-id:fake:payload -16372 # var1/reg <- add var2 => 03/add var2/rm32 var1/r32 -16373 0x11/imm32/alloc-id:fake -16374 _string-add/imm32/name -16375 0x11/imm32/alloc-id:fake -16376 Single-int-var-in-mem/imm32/inouts -16377 0x11/imm32/alloc-id:fake -16378 Single-int-var-in-some-register/imm32/outputs -16379 0x11/imm32/alloc-id:fake -16380 _string_03_add/imm32/subx-name -16381 1/imm32/rm32-is-first-inout -16382 3/imm32/r32-is-first-output -16383 0/imm32/no-imm32 -16384 0/imm32/no-imm8 -16385 0/imm32/no-disp32 -16386 0/imm32/output-is-write-only -16387 0x11/imm32/alloc-id:fake -16388 _Primitive-add-lit-to-reg/imm32/next -16389 _Primitive-add-lit-to-reg: # (payload primitive) -16390 0x11/imm32/alloc-id:fake:payload -16391 # var1/reg <- add lit => 81 0/subop/add var1/rm32 lit/imm32 -16392 0x11/imm32/alloc-id:fake -16393 _string-add/imm32/name -16394 0x11/imm32/alloc-id:fake -16395 Single-lit-var/imm32/inouts -16396 0x11/imm32/alloc-id:fake -16397 Single-int-var-in-some-register/imm32/outputs -16398 0x11/imm32/alloc-id:fake -16399 _string_81_subop_add/imm32/subx-name -16400 3/imm32/rm32-is-first-output -16401 0/imm32/no-r32 -16402 1/imm32/imm32-is-first-inout -16403 0/imm32/no-imm8 -16404 0/imm32/no-disp32 -16405 0/imm32/output-is-write-only -16406 0x11/imm32/alloc-id:fake -16407 _Primitive-add-lit-to-mem/imm32/next -16408 _Primitive-add-lit-to-mem: # (payload primitive) -16409 0x11/imm32/alloc-id:fake:payload -16410 # add-to var1, lit => 81 0/subop/add var1/rm32 lit/imm32 -16411 0x11/imm32/alloc-id:fake -16412 _string-add-to/imm32/name -16413 0x11/imm32/alloc-id:fake -16414 Int-var-and-literal/imm32/inouts -16415 0/imm32/no-outputs -16416 0/imm32/no-outputs -16417 0x11/imm32/alloc-id:fake -16418 _string_81_subop_add/imm32/subx-name -16419 1/imm32/rm32-is-first-inout -16420 0/imm32/no-r32 -16421 2/imm32/imm32-is-second-inout -16422 0/imm32/no-imm8 -16423 0/imm32/no-disp32 -16424 0/imm32/output-is-write-only -16425 0x11/imm32/alloc-id:fake -16426 _Primitive-subtract-from-eax/imm32/next -16427 # - subtract -16428 _Primitive-subtract-from-eax: # (payload primitive) -16429 0x11/imm32/alloc-id:fake:payload -16430 # var/eax <- subtract lit => 2d/subtract-from-eax lit/imm32 -16431 0x11/imm32/alloc-id:fake -16432 _string-subtract/imm32/name -16433 0x11/imm32/alloc-id:fake -16434 Single-lit-var/imm32/inouts -16435 0x11/imm32/alloc-id:fake -16436 Single-int-var-in-eax/imm32/outputs -16437 0x11/imm32/alloc-id:fake -16438 _string_2d_subtract_from_eax/imm32/subx-name -16439 0/imm32/no-rm32 -16440 0/imm32/no-r32 -16441 1/imm32/imm32-is-first-inout -16442 0/imm32/no-imm8 -16443 0/imm32/no-disp32 -16444 0/imm32/output-is-write-only -16445 0x11/imm32/alloc-id:fake -16446 _Primitive-subtract-reg-from-reg/imm32/next -16447 _Primitive-subtract-reg-from-reg: # (payload primitive) -16448 0x11/imm32/alloc-id:fake:payload -16449 # var1/reg <- subtract var2/reg => 29/subtract-from var1/rm32 var2/r32 -16450 0x11/imm32/alloc-id:fake -16451 _string-subtract/imm32/name -16452 0x11/imm32/alloc-id:fake -16453 Single-int-var-in-some-register/imm32/inouts -16454 0x11/imm32/alloc-id:fake -16455 Single-int-var-in-some-register/imm32/outputs -16456 0x11/imm32/alloc-id:fake -16457 _string_29_subtract_from/imm32/subx-name -16458 3/imm32/rm32-is-first-output -16459 1/imm32/r32-is-first-inout -16460 0/imm32/no-imm32 -16461 0/imm32/no-imm8 -16462 0/imm32/no-disp32 -16463 0/imm32/output-is-write-only -16464 0x11/imm32/alloc-id:fake -16465 _Primitive-subtract-reg-from-mem/imm32/next -16466 _Primitive-subtract-reg-from-mem: # (payload primitive) -16467 0x11/imm32/alloc-id:fake:payload -16468 # subtract-from var1 var2/reg => 29/subtract-from var1 var2/r32 -16469 0x11/imm32/alloc-id:fake -16470 _string-subtract-from/imm32/name -16471 0x11/imm32/alloc-id:fake -16472 Two-args-int-stack-int-reg/imm32/inouts -16473 0/imm32/no-outputs -16474 0/imm32/no-outputs -16475 0x11/imm32/alloc-id:fake -16476 _string_29_subtract_from/imm32/subx-name -16477 1/imm32/rm32-is-first-inout -16478 2/imm32/r32-is-second-inout -16479 0/imm32/no-imm32 -16480 0/imm32/no-imm8 -16481 0/imm32/no-disp32 -16482 0/imm32/output-is-write-only -16483 0x11/imm32/alloc-id:fake -16484 _Primitive-subtract-mem-from-reg/imm32/next -16485 _Primitive-subtract-mem-from-reg: # (payload primitive) -16486 0x11/imm32/alloc-id:fake:payload -16487 # var1/reg <- subtract var2 => 2b/subtract var2/rm32 var1/r32 -16488 0x11/imm32/alloc-id:fake -16489 _string-subtract/imm32/name -16490 0x11/imm32/alloc-id:fake -16491 Single-int-var-in-mem/imm32/inouts -16492 0x11/imm32/alloc-id:fake -16493 Single-int-var-in-some-register/imm32/outputs -16494 0x11/imm32/alloc-id:fake -16495 _string_2b_subtract/imm32/subx-name -16496 1/imm32/rm32-is-first-inout -16497 3/imm32/r32-is-first-output -16498 0/imm32/no-imm32 -16499 0/imm32/no-imm8 -16500 0/imm32/no-disp32 -16501 0/imm32/output-is-write-only -16502 0x11/imm32/alloc-id:fake -16503 _Primitive-subtract-lit-from-reg/imm32/next -16504 _Primitive-subtract-lit-from-reg: # (payload primitive) -16505 0x11/imm32/alloc-id:fake:payload -16506 # var1/reg <- subtract lit => 81 5/subop/subtract var1/rm32 lit/imm32 -16507 0x11/imm32/alloc-id:fake -16508 _string-subtract/imm32/name -16509 0x11/imm32/alloc-id:fake -16510 Single-lit-var/imm32/inouts -16511 0x11/imm32/alloc-id:fake -16512 Single-int-var-in-some-register/imm32/outputs -16513 0x11/imm32/alloc-id:fake -16514 _string_81_subop_subtract/imm32/subx-name -16515 3/imm32/rm32-is-first-output -16516 0/imm32/no-r32 -16517 1/imm32/imm32-is-first-inout -16518 0/imm32/no-imm8 -16519 0/imm32/no-disp32 -16520 0/imm32/output-is-write-only -16521 0x11/imm32/alloc-id:fake -16522 _Primitive-subtract-lit-from-mem/imm32/next -16523 _Primitive-subtract-lit-from-mem: # (payload primitive) -16524 0x11/imm32/alloc-id:fake:payload -16525 # subtract-from var1, lit => 81 5/subop/subtract var1/rm32 lit/imm32 -16526 0x11/imm32/alloc-id:fake -16527 _string-subtract-from/imm32/name -16528 0x11/imm32/alloc-id:fake -16529 Int-var-and-literal/imm32/inouts -16530 0/imm32/no-outputs -16531 0/imm32/no-outputs -16532 0x11/imm32/alloc-id:fake -16533 _string_81_subop_subtract/imm32/subx-name -16534 1/imm32/rm32-is-first-inout -16535 0/imm32/no-r32 -16536 2/imm32/imm32-is-second-inout -16537 0/imm32/no-imm8 -16538 0/imm32/no-disp32 -16539 0/imm32/output-is-write-only -16540 0x11/imm32/alloc-id:fake -16541 _Primitive-and-with-eax/imm32/next -16542 # - and -16543 _Primitive-and-with-eax: # (payload primitive) -16544 0x11/imm32/alloc-id:fake:payload -16545 # var/eax <- and lit => 25/and-with-eax lit/imm32 -16546 0x11/imm32/alloc-id:fake -16547 _string-and/imm32/name -16548 0x11/imm32/alloc-id:fake -16549 Single-lit-var/imm32/inouts -16550 0x11/imm32/alloc-id:fake -16551 Single-int-var-in-eax/imm32/outputs -16552 0x11/imm32/alloc-id:fake -16553 _string_25_and_with_eax/imm32/subx-name -16554 0/imm32/no-rm32 -16555 0/imm32/no-r32 -16556 1/imm32/imm32-is-first-inout -16557 0/imm32/no-imm8 -16558 0/imm32/no-disp32 -16559 0/imm32/output-is-write-only -16560 0x11/imm32/alloc-id:fake -16561 _Primitive-and-reg-with-reg/imm32/next -16562 _Primitive-and-reg-with-reg: # (payload primitive) -16563 0x11/imm32/alloc-id:fake:payload -16564 # var1/reg <- and var2/reg => 21/and-with var1/rm32 var2/r32 -16565 0x11/imm32/alloc-id:fake -16566 _string-and/imm32/name -16567 0x11/imm32/alloc-id:fake -16568 Single-int-var-in-some-register/imm32/inouts -16569 0x11/imm32/alloc-id:fake -16570 Single-int-var-in-some-register/imm32/outputs -16571 0x11/imm32/alloc-id:fake -16572 _string_21_and_with/imm32/subx-name -16573 3/imm32/rm32-is-first-output -16574 1/imm32/r32-is-first-inout -16575 0/imm32/no-imm32 -16576 0/imm32/no-imm8 -16577 0/imm32/no-disp32 -16578 0/imm32/output-is-write-only -16579 0x11/imm32/alloc-id:fake -16580 _Primitive-and-reg-with-mem/imm32/next -16581 _Primitive-and-reg-with-mem: # (payload primitive) -16582 0x11/imm32/alloc-id:fake:payload -16583 # and-with var1 var2/reg => 21/and-with var1 var2/r32 -16584 0x11/imm32/alloc-id:fake -16585 _string-and-with/imm32/name -16586 0x11/imm32/alloc-id:fake -16587 Two-args-int-stack-int-reg/imm32/inouts -16588 0/imm32/no-outputs -16589 0/imm32/no-outputs -16590 0x11/imm32/alloc-id:fake -16591 _string_21_and_with/imm32/subx-name -16592 1/imm32/rm32-is-first-inout -16593 2/imm32/r32-is-second-inout -16594 0/imm32/no-imm32 -16595 0/imm32/no-imm8 -16596 0/imm32/no-disp32 -16597 0/imm32/output-is-write-only -16598 0x11/imm32/alloc-id:fake -16599 _Primitive-and-mem-with-reg/imm32/next -16600 _Primitive-and-mem-with-reg: # (payload primitive) -16601 0x11/imm32/alloc-id:fake:payload -16602 # var1/reg <- and var2 => 23/and var2/rm32 var1/r32 -16603 0x11/imm32/alloc-id:fake -16604 _string-and/imm32/name -16605 0x11/imm32/alloc-id:fake -16606 Single-int-var-in-mem/imm32/inouts -16607 0x11/imm32/alloc-id:fake -16608 Single-int-var-in-some-register/imm32/outputs -16609 0x11/imm32/alloc-id:fake -16610 _string_23_and/imm32/subx-name -16611 1/imm32/rm32-is-first-inout -16612 3/imm32/r32-is-first-output -16613 0/imm32/no-imm32 -16614 0/imm32/no-imm8 -16615 0/imm32/no-disp32 -16616 0/imm32/output-is-write-only -16617 0x11/imm32/alloc-id:fake -16618 _Primitive-and-lit-with-reg/imm32/next -16619 _Primitive-and-lit-with-reg: # (payload primitive) -16620 0x11/imm32/alloc-id:fake:payload -16621 # var1/reg <- and lit => 81 4/subop/and var1/rm32 lit/imm32 -16622 0x11/imm32/alloc-id:fake -16623 _string-and/imm32/name -16624 0x11/imm32/alloc-id:fake -16625 Single-lit-var/imm32/inouts -16626 0x11/imm32/alloc-id:fake -16627 Single-int-var-in-some-register/imm32/outputs -16628 0x11/imm32/alloc-id:fake -16629 _string_81_subop_and/imm32/subx-name -16630 3/imm32/rm32-is-first-output -16631 0/imm32/no-r32 -16632 1/imm32/imm32-is-first-inout -16633 0/imm32/no-imm8 -16634 0/imm32/no-disp32 -16635 0/imm32/output-is-write-only -16636 0x11/imm32/alloc-id:fake -16637 _Primitive-and-lit-with-mem/imm32/next -16638 _Primitive-and-lit-with-mem: # (payload primitive) -16639 0x11/imm32/alloc-id:fake:payload -16640 # and-with var1, lit => 81 4/subop/and var1/rm32 lit/imm32 -16641 0x11/imm32/alloc-id:fake -16642 _string-and-with/imm32/name -16643 0x11/imm32/alloc-id:fake -16644 Int-var-and-literal/imm32/inouts -16645 0/imm32/no-outputs -16646 0/imm32/no-outputs -16647 0x11/imm32/alloc-id:fake -16648 _string_81_subop_and/imm32/subx-name -16649 1/imm32/rm32-is-first-inout -16650 0/imm32/no-r32 -16651 2/imm32/imm32-is-second-inout -16652 0/imm32/no-imm8 -16653 0/imm32/no-disp32 -16654 0/imm32/output-is-write-only -16655 0x11/imm32/alloc-id:fake -16656 _Primitive-or-with-eax/imm32/next -16657 # - or -16658 _Primitive-or-with-eax: # (payload primitive) -16659 0x11/imm32/alloc-id:fake:payload -16660 # var/eax <- or lit => 0d/or-with-eax lit/imm32 -16661 0x11/imm32/alloc-id:fake -16662 _string-or/imm32/name -16663 0x11/imm32/alloc-id:fake -16664 Single-lit-var/imm32/inouts -16665 0x11/imm32/alloc-id:fake -16666 Single-int-var-in-eax/imm32/outputs -16667 0x11/imm32/alloc-id:fake -16668 _string_0d_or_with_eax/imm32/subx-name -16669 0/imm32/no-rm32 -16670 0/imm32/no-r32 -16671 1/imm32/imm32-is-first-inout -16672 0/imm32/no-imm8 -16673 0/imm32/no-disp32 -16674 0/imm32/output-is-write-only -16675 0x11/imm32/alloc-id:fake -16676 _Primitive-or-reg-with-reg/imm32/next -16677 _Primitive-or-reg-with-reg: # (payload primitive) -16678 0x11/imm32/alloc-id:fake:payload -16679 # var1/reg <- or var2/reg => 09/or-with var1/rm32 var2/r32 -16680 0x11/imm32/alloc-id:fake -16681 _string-or/imm32/name -16682 0x11/imm32/alloc-id:fake -16683 Single-int-var-in-some-register/imm32/inouts -16684 0x11/imm32/alloc-id:fake -16685 Single-int-var-in-some-register/imm32/outputs -16686 0x11/imm32/alloc-id:fake -16687 _string_09_or_with/imm32/subx-name -16688 3/imm32/rm32-is-first-output -16689 1/imm32/r32-is-first-inout -16690 0/imm32/no-imm32 -16691 0/imm32/no-imm8 -16692 0/imm32/no-disp32 -16693 0/imm32/output-is-write-only -16694 0x11/imm32/alloc-id:fake -16695 _Primitive-or-reg-with-mem/imm32/next -16696 _Primitive-or-reg-with-mem: # (payload primitive) -16697 0x11/imm32/alloc-id:fake:payload -16698 # or-with var1 var2/reg => 09/or-with var1 var2/r32 -16699 0x11/imm32/alloc-id:fake -16700 _string-or-with/imm32/name -16701 0x11/imm32/alloc-id:fake -16702 Two-args-int-stack-int-reg/imm32/inouts -16703 0/imm32/no-outputs -16704 0/imm32/no-outputs -16705 0x11/imm32/alloc-id:fake -16706 _string_09_or_with/imm32/subx-name -16707 1/imm32/rm32-is-first-inout -16708 2/imm32/r32-is-second-inout -16709 0/imm32/no-imm32 -16710 0/imm32/no-imm8 -16711 0/imm32/no-disp32 -16712 0/imm32/output-is-write-only -16713 0x11/imm32/alloc-id:fake -16714 _Primitive-or-mem-with-reg/imm32/next -16715 _Primitive-or-mem-with-reg: # (payload primitive) -16716 0x11/imm32/alloc-id:fake:payload -16717 # var1/reg <- or var2 => 0b/or var2/rm32 var1/r32 -16718 0x11/imm32/alloc-id:fake -16719 _string-or/imm32/name -16720 0x11/imm32/alloc-id:fake -16721 Single-int-var-in-mem/imm32/inouts -16722 0x11/imm32/alloc-id:fake -16723 Single-int-var-in-some-register/imm32/outputs -16724 0x11/imm32/alloc-id:fake -16725 _string_0b_or/imm32/subx-name -16726 1/imm32/rm32-is-first-inout -16727 3/imm32/r32-is-first-output -16728 0/imm32/no-imm32 -16729 0/imm32/no-imm8 -16730 0/imm32/no-disp32 -16731 0/imm32/output-is-write-only -16732 0x11/imm32/alloc-id:fake -16733 _Primitive-or-lit-with-reg/imm32/next -16734 _Primitive-or-lit-with-reg: # (payload primitive) -16735 0x11/imm32/alloc-id:fake:payload -16736 # var1/reg <- or lit => 81 1/subop/or var1/rm32 lit/imm32 -16737 0x11/imm32/alloc-id:fake -16738 _string-or/imm32/name -16739 0x11/imm32/alloc-id:fake -16740 Single-lit-var/imm32/inouts -16741 0x11/imm32/alloc-id:fake -16742 Single-int-var-in-some-register/imm32/outputs -16743 0x11/imm32/alloc-id:fake -16744 _string_81_subop_or/imm32/subx-name -16745 3/imm32/rm32-is-first-output -16746 0/imm32/no-r32 -16747 1/imm32/imm32-is-first-inout -16748 0/imm32/no-imm8 -16749 0/imm32/no-disp32 -16750 0/imm32/output-is-write-only -16751 0x11/imm32/alloc-id:fake -16752 _Primitive-or-lit-with-mem/imm32/next -16753 _Primitive-or-lit-with-mem: # (payload primitive) -16754 0x11/imm32/alloc-id:fake:payload -16755 # or-with var1, lit => 81 1/subop/or var1/rm32 lit/imm32 -16756 0x11/imm32/alloc-id:fake -16757 _string-or-with/imm32/name -16758 0x11/imm32/alloc-id:fake -16759 Int-var-and-literal/imm32/inouts -16760 0/imm32/no-outputs -16761 0/imm32/no-outputs -16762 0x11/imm32/alloc-id:fake -16763 _string_81_subop_or/imm32/subx-name -16764 1/imm32/rm32-is-first-inout -16765 0/imm32/no-r32 -16766 2/imm32/imm32-is-second-inout -16767 0/imm32/no-imm8 -16768 0/imm32/no-disp32 -16769 0/imm32/output-is-write-only -16770 0x11/imm32/alloc-id:fake -16771 _Primitive-xor-with-eax/imm32/next -16772 # - xor -16773 _Primitive-xor-with-eax: # (payload primitive) -16774 0x11/imm32/alloc-id:fake:payload -16775 # var/eax <- xor lit => 35/xor-with-eax lit/imm32 -16776 0x11/imm32/alloc-id:fake -16777 _string-xor/imm32/name -16778 0x11/imm32/alloc-id:fake -16779 Single-lit-var/imm32/inouts -16780 0x11/imm32/alloc-id:fake -16781 Single-int-var-in-eax/imm32/outputs -16782 0x11/imm32/alloc-id:fake -16783 _string_35_xor_with_eax/imm32/subx-name -16784 0/imm32/no-rm32 -16785 0/imm32/no-r32 -16786 1/imm32/imm32-is-first-inout -16787 0/imm32/no-imm8 -16788 0/imm32/no-disp32 -16789 0/imm32/output-is-write-only -16790 0x11/imm32/alloc-id:fake -16791 _Primitive-xor-reg-with-reg/imm32/next -16792 _Primitive-xor-reg-with-reg: # (payload primitive) -16793 0x11/imm32/alloc-id:fake:payload -16794 # var1/reg <- xor var2/reg => 31/xor-with var1/rm32 var2/r32 -16795 0x11/imm32/alloc-id:fake -16796 _string-xor/imm32/name -16797 0x11/imm32/alloc-id:fake -16798 Single-int-var-in-some-register/imm32/inouts -16799 0x11/imm32/alloc-id:fake -16800 Single-int-var-in-some-register/imm32/outputs -16801 0x11/imm32/alloc-id:fake -16802 _string_31_xor_with/imm32/subx-name -16803 3/imm32/rm32-is-first-output -16804 1/imm32/r32-is-first-inout -16805 0/imm32/no-imm32 -16806 0/imm32/no-imm8 -16807 0/imm32/no-disp32 -16808 0/imm32/output-is-write-only -16809 0x11/imm32/alloc-id:fake -16810 _Primitive-xor-reg-with-mem/imm32/next -16811 _Primitive-xor-reg-with-mem: # (payload primitive) -16812 0x11/imm32/alloc-id:fake:payload -16813 # xor-with var1 var2/reg => 31/xor-with var1 var2/r32 -16814 0x11/imm32/alloc-id:fake -16815 _string-xor-with/imm32/name -16816 0x11/imm32/alloc-id:fake -16817 Two-args-int-stack-int-reg/imm32/inouts -16818 0/imm32/no-outputs -16819 0/imm32/no-outputs -16820 0x11/imm32/alloc-id:fake -16821 _string_31_xor_with/imm32/subx-name -16822 1/imm32/rm32-is-first-inout -16823 2/imm32/r32-is-second-inout -16824 0/imm32/no-imm32 -16825 0/imm32/no-imm8 -16826 0/imm32/no-disp32 -16827 0/imm32/output-is-write-only -16828 0x11/imm32/alloc-id:fake -16829 _Primitive-xor-mem-with-reg/imm32/next -16830 _Primitive-xor-mem-with-reg: # (payload primitive) -16831 0x11/imm32/alloc-id:fake:payload -16832 # var1/reg <- xor var2 => 33/xor var2/rm32 var1/r32 -16833 0x11/imm32/alloc-id:fake -16834 _string-xor/imm32/name -16835 0x11/imm32/alloc-id:fake -16836 Single-int-var-in-mem/imm32/inouts -16837 0x11/imm32/alloc-id:fake -16838 Single-int-var-in-some-register/imm32/outputs -16839 0x11/imm32/alloc-id:fake -16840 _string_33_xor/imm32/subx-name -16841 1/imm32/rm32-is-first-inout -16842 3/imm32/r32-is-first-output -16843 0/imm32/no-imm32 -16844 0/imm32/no-imm8 -16845 0/imm32/no-disp32 -16846 0/imm32/output-is-write-only -16847 0x11/imm32/alloc-id:fake -16848 _Primitive-xor-lit-with-reg/imm32/next -16849 _Primitive-xor-lit-with-reg: # (payload primitive) -16850 0x11/imm32/alloc-id:fake:payload -16851 # var1/reg <- xor lit => 81 6/subop/xor var1/rm32 lit/imm32 -16852 0x11/imm32/alloc-id:fake -16853 _string-xor/imm32/name -16854 0x11/imm32/alloc-id:fake -16855 Single-lit-var/imm32/inouts -16856 0x11/imm32/alloc-id:fake -16857 Single-int-var-in-some-register/imm32/outputs -16858 0x11/imm32/alloc-id:fake -16859 _string_81_subop_xor/imm32/subx-name -16860 3/imm32/rm32-is-first-output -16861 0/imm32/no-r32 -16862 1/imm32/imm32-is-first-inout -16863 0/imm32/no-imm8 -16864 0/imm32/no-disp32 -16865 0/imm32/output-is-write-only -16866 0x11/imm32/alloc-id:fake -16867 _Primitive-xor-lit-with-mem/imm32/next -16868 _Primitive-xor-lit-with-mem: # (payload primitive) -16869 0x11/imm32/alloc-id:fake:payload -16870 # xor-with var1, lit => 81 6/subop/xor var1/rm32 lit/imm32 -16871 0x11/imm32/alloc-id:fake -16872 _string-xor-with/imm32/name -16873 0x11/imm32/alloc-id:fake -16874 Int-var-and-literal/imm32/inouts -16875 0/imm32/no-outputs -16876 0/imm32/no-outputs -16877 0x11/imm32/alloc-id:fake -16878 _string_81_subop_xor/imm32/subx-name -16879 1/imm32/rm32-is-first-inout -16880 0/imm32/no-r32 -16881 2/imm32/imm32-is-second-inout -16882 0/imm32/no-imm8 -16883 0/imm32/no-disp32 -16884 0/imm32/output-is-write-only -16885 0x11/imm32/alloc-id:fake -16886 _Primitive-shift-reg-left-by-lit/imm32/next -16887 _Primitive-shift-reg-left-by-lit: # (payload primitive) -16888 0x11/imm32/alloc-id:fake:payload -16889 # var1/reg <- shift-left lit => c1/shift 4/subop/left var1/rm32 lit/imm32 -16890 0x11/imm32/alloc-id:fake -16891 _string-shift-left/imm32/name -16892 0x11/imm32/alloc-id:fake -16893 Single-lit-var/imm32/inouts -16894 0x11/imm32/alloc-id:fake -16895 Single-int-var-in-some-register/imm32/outputs -16896 0x11/imm32/alloc-id:fake -16897 _string_c1_subop_shift_left/imm32/subx-name -16898 3/imm32/rm32-is-first-output -16899 0/imm32/no-r32 -16900 0/imm32/no-imm32 -16901 1/imm32/imm8-is-first-inout -16902 0/imm32/no-disp32 -16903 0/imm32/output-is-write-only -16904 0x11/imm32/alloc-id:fake -16905 _Primitive-shift-reg-right-by-lit/imm32/next -16906 _Primitive-shift-reg-right-by-lit: # (payload primitive) -16907 0x11/imm32/alloc-id:fake:payload -16908 # var1/reg <- shift-right lit => c1/shift 5/subop/right var1/rm32 lit/imm32 -16909 0x11/imm32/alloc-id:fake -16910 _string-shift-right/imm32/name -16911 0x11/imm32/alloc-id:fake -16912 Single-lit-var/imm32/inouts -16913 0x11/imm32/alloc-id:fake -16914 Single-int-var-in-some-register/imm32/outputs -16915 0x11/imm32/alloc-id:fake -16916 _string_c1_subop_shift_right_padding_zeroes/imm32/subx-name -16917 3/imm32/rm32-is-first-output -16918 0/imm32/no-r32 -16919 0/imm32/no-imm32 -16920 1/imm32/imm8-is-first-inout -16921 0/imm32/no-disp32 -16922 0/imm32/output-is-write-only -16923 0x11/imm32/alloc-id:fake -16924 _Primitive-shift-reg-right-signed-by-lit/imm32/next -16925 _Primitive-shift-reg-right-signed-by-lit: # (payload primitive) -16926 0x11/imm32/alloc-id:fake:payload -16927 # var1/reg <- shift-right-signed lit => c1/shift 7/subop/right-preserving-sign var1/rm32 lit/imm32 -16928 0x11/imm32/alloc-id:fake -16929 _string-shift-right-signed/imm32/name -16930 0x11/imm32/alloc-id:fake -16931 Single-lit-var/imm32/inouts -16932 0x11/imm32/alloc-id:fake -16933 Single-int-var-in-some-register/imm32/outputs -16934 0x11/imm32/alloc-id:fake -16935 _string_c1_subop_shift_right_preserving_sign/imm32/subx-name -16936 3/imm32/rm32-is-first-output -16937 0/imm32/no-r32 -16938 0/imm32/no-imm32 -16939 1/imm32/imm8-is-first-inout -16940 0/imm32/no-disp32 -16941 0/imm32/output-is-write-only -16942 0x11/imm32/alloc-id:fake -16943 _Primitive-shift-mem-left-by-lit/imm32/next -16944 _Primitive-shift-mem-left-by-lit: # (payload primitive) -16945 0x11/imm32/alloc-id:fake:payload -16946 # shift-left var1, lit => c1/shift 4/subop/left var1/rm32 lit/imm32 -16947 0x11/imm32/alloc-id:fake -16948 _string-shift-left/imm32/name -16949 0x11/imm32/alloc-id:fake -16950 Int-var-and-literal/imm32/inouts -16951 0/imm32/no-outputs -16952 0/imm32/no-outputs -16953 0x11/imm32/alloc-id:fake -16954 _string_c1_subop_shift_left/imm32/subx-name -16955 1/imm32/rm32-is-first-inout -16956 0/imm32/no-r32 -16957 0/imm32/no-imm32 -16958 2/imm32/imm8-is-second-inout -16959 0/imm32/no-disp32 -16960 0/imm32/output-is-write-only -16961 0x11/imm32/alloc-id:fake -16962 _Primitive-shift-mem-right-by-lit/imm32/next -16963 _Primitive-shift-mem-right-by-lit: # (payload primitive) -16964 0x11/imm32/alloc-id:fake:payload -16965 # shift-right var1, lit => c1/shift 5/subop/right var1/rm32 lit/imm32 -16966 0x11/imm32/alloc-id:fake -16967 _string-shift-right/imm32/name -16968 0x11/imm32/alloc-id:fake -16969 Int-var-and-literal/imm32/inouts -16970 0/imm32/no-outputs -16971 0/imm32/no-outputs -16972 0x11/imm32/alloc-id:fake -16973 _string_c1_subop_shift_right_padding_zeroes/imm32/subx-name -16974 1/imm32/rm32-is-first-inout -16975 0/imm32/no-r32 -16976 0/imm32/no-imm32 -16977 2/imm32/imm8-is-second-inout -16978 0/imm32/no-disp32 -16979 0/imm32/output-is-write-only -16980 0x11/imm32/alloc-id:fake -16981 _Primitive-shift-mem-right-signed-by-lit/imm32/next -16982 _Primitive-shift-mem-right-signed-by-lit: # (payload primitive) -16983 0x11/imm32/alloc-id:fake:payload -16984 # shift-right-signed var1, lit => c1/shift 7/subop/right-preserving-sign var1/rm32 lit/imm32 -16985 0x11/imm32/alloc-id:fake -16986 _string-shift-right-signed/imm32/name -16987 0x11/imm32/alloc-id:fake -16988 Int-var-and-literal/imm32/inouts -16989 0/imm32/no-outputs -16990 0/imm32/no-outputs -16991 0x11/imm32/alloc-id:fake -16992 _string_c1_subop_shift_right_preserving_sign/imm32/subx-name -16993 1/imm32/rm32-is-first-inout -16994 0/imm32/no-r32 -16995 0/imm32/no-imm32 -16996 2/imm32/imm8-is-second-inout -16997 0/imm32/no-disp32 -16998 0/imm32/output-is-write-only -16999 0x11/imm32/alloc-id:fake -17000 _Primitive-copy-to-eax/imm32/next -17001 # - copy -17002 _Primitive-copy-to-eax: # (payload primitive) -17003 0x11/imm32/alloc-id:fake:payload -17004 # var/eax <- copy lit => b8/copy-to-eax lit/imm32 -17005 0x11/imm32/alloc-id:fake -17006 _string-copy/imm32/name -17007 0x11/imm32/alloc-id:fake -17008 Single-lit-var/imm32/inouts -17009 0x11/imm32/alloc-id:fake -17010 Single-int-var-in-eax/imm32/outputs -17011 0x11/imm32/alloc-id:fake -17012 _string_b8_copy_to_eax/imm32/subx-name -17013 0/imm32/no-rm32 -17014 0/imm32/no-r32 -17015 1/imm32/imm32-is-first-inout -17016 0/imm32/no-imm8 -17017 0/imm32/no-disp32 -17018 1/imm32/output-is-write-only -17019 0x11/imm32/alloc-id:fake -17020 _Primitive-copy-to-ecx/imm32/next -17021 _Primitive-copy-to-ecx: # (payload primitive) -17022 0x11/imm32/alloc-id:fake:payload -17023 # var/ecx <- copy lit => b9/copy-to-ecx lit/imm32 -17024 0x11/imm32/alloc-id:fake -17025 _string-copy/imm32/name -17026 0x11/imm32/alloc-id:fake -17027 Single-lit-var/imm32/inouts -17028 0x11/imm32/alloc-id:fake -17029 Single-int-var-in-ecx/imm32/outputs -17030 0x11/imm32/alloc-id:fake -17031 _string_b9_copy_to_ecx/imm32/subx-name -17032 0/imm32/no-rm32 -17033 0/imm32/no-r32 -17034 1/imm32/imm32-is-first-inout -17035 0/imm32/no-imm8 -17036 0/imm32/no-disp32 -17037 1/imm32/output-is-write-only -17038 0x11/imm32/alloc-id:fake -17039 _Primitive-copy-to-edx/imm32/next -17040 _Primitive-copy-to-edx: # (payload primitive) -17041 0x11/imm32/alloc-id:fake:payload -17042 # var/edx <- copy lit => ba/copy-to-edx lit/imm32 -17043 0x11/imm32/alloc-id:fake -17044 _string-copy/imm32/name -17045 0x11/imm32/alloc-id:fake -17046 Single-lit-var/imm32/inouts -17047 0x11/imm32/alloc-id:fake -17048 Single-int-var-in-edx/imm32/outputs -17049 0x11/imm32/alloc-id:fake -17050 _string_ba_copy_to_edx/imm32/subx-name -17051 0/imm32/no-rm32 -17052 0/imm32/no-r32 -17053 1/imm32/imm32-is-first-inout -17054 0/imm32/no-imm8 -17055 0/imm32/no-disp32 -17056 1/imm32/output-is-write-only -17057 0x11/imm32/alloc-id:fake -17058 _Primitive-copy-to-ebx/imm32/next -17059 _Primitive-copy-to-ebx: # (payload primitive) -17060 0x11/imm32/alloc-id:fake:payload -17061 # var/ebx <- copy lit => bb/copy-to-ebx lit/imm32 -17062 0x11/imm32/alloc-id:fake -17063 _string-copy/imm32/name -17064 0x11/imm32/alloc-id:fake -17065 Single-lit-var/imm32/inouts -17066 0x11/imm32/alloc-id:fake -17067 Single-int-var-in-ebx/imm32/outputs -17068 0x11/imm32/alloc-id:fake -17069 _string_bb_copy_to_ebx/imm32/subx-name -17070 0/imm32/no-rm32 -17071 0/imm32/no-r32 -17072 1/imm32/imm32-is-first-inout -17073 0/imm32/no-imm8 -17074 0/imm32/no-disp32 -17075 1/imm32/output-is-write-only -17076 0x11/imm32/alloc-id:fake -17077 _Primitive-copy-to-esi/imm32/next -17078 _Primitive-copy-to-esi: # (payload primitive) -17079 0x11/imm32/alloc-id:fake:payload -17080 # var/esi <- copy lit => be/copy-to-esi lit/imm32 -17081 0x11/imm32/alloc-id:fake -17082 _string-copy/imm32/name -17083 0x11/imm32/alloc-id:fake -17084 Single-lit-var/imm32/inouts -17085 0x11/imm32/alloc-id:fake -17086 Single-int-var-in-esi/imm32/outputs -17087 0x11/imm32/alloc-id:fake -17088 _string_be_copy_to_esi/imm32/subx-name -17089 0/imm32/no-rm32 -17090 0/imm32/no-r32 -17091 1/imm32/imm32-is-first-inout -17092 0/imm32/no-imm8 -17093 0/imm32/no-disp32 -17094 1/imm32/output-is-write-only -17095 0x11/imm32/alloc-id:fake -17096 _Primitive-copy-to-edi/imm32/next -17097 _Primitive-copy-to-edi: # (payload primitive) -17098 0x11/imm32/alloc-id:fake:payload -17099 # var/edi <- copy lit => bf/copy-to-edi lit/imm32 -17100 0x11/imm32/alloc-id:fake -17101 _string-copy/imm32/name -17102 0x11/imm32/alloc-id:fake -17103 Single-lit-var/imm32/inouts -17104 0x11/imm32/alloc-id:fake -17105 Single-int-var-in-edi/imm32/outputs -17106 0x11/imm32/alloc-id:fake -17107 _string_bf_copy_to_edi/imm32/subx-name -17108 0/imm32/no-rm32 -17109 0/imm32/no-r32 -17110 1/imm32/imm32-is-first-inout -17111 0/imm32/no-imm8 -17112 0/imm32/no-disp32 -17113 1/imm32/output-is-write-only -17114 0x11/imm32/alloc-id:fake -17115 _Primitive-copy-reg-to-reg/imm32/next -17116 _Primitive-copy-reg-to-reg: # (payload primitive) -17117 0x11/imm32/alloc-id:fake:payload -17118 # var1/reg <- copy var2/reg => 89/<- var1/rm32 var2/r32 -17119 0x11/imm32/alloc-id:fake -17120 _string-copy/imm32/name -17121 0x11/imm32/alloc-id:fake -17122 Single-int-var-in-some-register/imm32/inouts -17123 0x11/imm32/alloc-id:fake -17124 Single-int-var-in-some-register/imm32/outputs -17125 0x11/imm32/alloc-id:fake -17126 _string_89_<-/imm32/subx-name -17127 3/imm32/rm32-is-first-output -17128 1/imm32/r32-is-first-inout -17129 0/imm32/no-imm32 -17130 0/imm32/no-imm8 -17131 0/imm32/no-disp32 -17132 1/imm32/output-is-write-only -17133 0x11/imm32/alloc-id:fake -17134 _Primitive-copy-reg-to-mem/imm32/next -17135 _Primitive-copy-reg-to-mem: # (payload primitive) -17136 0x11/imm32/alloc-id:fake:payload -17137 # copy-to var1 var2/reg => 89/<- var1 var2/r32 -17138 0x11/imm32/alloc-id:fake -17139 _string-copy-to/imm32/name -17140 0x11/imm32/alloc-id:fake -17141 Two-args-int-stack-int-reg/imm32/inouts -17142 0/imm32/no-outputs -17143 0/imm32/no-outputs -17144 0x11/imm32/alloc-id:fake -17145 _string_89_<-/imm32/subx-name -17146 1/imm32/rm32-is-first-inout -17147 2/imm32/r32-is-second-inout -17148 0/imm32/no-imm32 -17149 0/imm32/no-imm8 -17150 0/imm32/no-disp32 -17151 1/imm32/output-is-write-only -17152 0x11/imm32/alloc-id:fake -17153 _Primitive-copy-mem-to-reg/imm32/next -17154 _Primitive-copy-mem-to-reg: # (payload primitive) -17155 0x11/imm32/alloc-id:fake:payload -17156 # var1/reg <- copy var2 => 8b/-> var2/rm32 var1/r32 -17157 0x11/imm32/alloc-id:fake -17158 _string-copy/imm32/name -17159 0x11/imm32/alloc-id:fake -17160 Single-int-var-in-mem/imm32/inouts -17161 0x11/imm32/alloc-id:fake -17162 Single-int-var-in-some-register/imm32/outputs -17163 0x11/imm32/alloc-id:fake -17164 _string_8b_->/imm32/subx-name -17165 1/imm32/rm32-is-first-inout -17166 3/imm32/r32-is-first-output -17167 0/imm32/no-imm32 -17168 0/imm32/no-imm8 -17169 0/imm32/no-disp32 -17170 1/imm32/output-is-write-only -17171 0x11/imm32/alloc-id:fake -17172 _Primitive-copy-lit-to-reg/imm32/next -17173 _Primitive-copy-lit-to-reg: # (payload primitive) -17174 0x11/imm32/alloc-id:fake:payload -17175 # var1/reg <- copy lit => c7 0/subop/copy var1/rm32 lit/imm32 -17176 0x11/imm32/alloc-id:fake -17177 _string-copy/imm32/name -17178 0x11/imm32/alloc-id:fake -17179 Single-lit-var/imm32/inouts -17180 0x11/imm32/alloc-id:fake -17181 Single-int-var-in-some-register/imm32/outputs -17182 0x11/imm32/alloc-id:fake -17183 _string_c7_subop_copy/imm32/subx-name -17184 3/imm32/rm32-is-first-output -17185 0/imm32/no-r32 -17186 1/imm32/imm32-is-first-inout -17187 0/imm32/no-imm8 -17188 0/imm32/no-disp32 -17189 1/imm32/output-is-write-only -17190 0x11/imm32/alloc-id:fake -17191 _Primitive-copy-lit-to-mem/imm32/next -17192 _Primitive-copy-lit-to-mem: # (payload primitive) -17193 0x11/imm32/alloc-id:fake:payload -17194 # copy-to var1, lit => c7 0/subop/copy var1/rm32 lit/imm32 -17195 0x11/imm32/alloc-id:fake -17196 _string-copy-to/imm32/name -17197 0x11/imm32/alloc-id:fake -17198 Int-var-and-literal/imm32/inouts -17199 0/imm32/no-outputs -17200 0/imm32/no-outputs -17201 0x11/imm32/alloc-id:fake -17202 _string_c7_subop_copy/imm32/subx-name -17203 1/imm32/rm32-is-first-inout -17204 0/imm32/no-r32 -17205 2/imm32/imm32-is-second-inout -17206 0/imm32/no-imm8 -17207 0/imm32/no-disp32 -17208 1/imm32/output-is-write-only -17209 0x11/imm32/alloc-id:fake -17210 _Primitive-copy-byte-from-reg/imm32/next -17211 # - copy byte -17212 _Primitive-copy-byte-from-reg: -17213 0x11/imm32/alloc-id:fake:payload -17214 # var/reg <- copy-byte var2/reg2 => 8a/byte-> %var2 var/r32 -17215 0x11/imm32/alloc-id:fake -17216 _string-copy-byte/imm32/name -17217 0x11/imm32/alloc-id:fake -17218 Single-byte-var-in-some-register/imm32/inouts -17219 0x11/imm32/alloc-id:fake -17220 Single-byte-var-in-some-register/imm32/outputs -17221 0x11/imm32/alloc-id:fake -17222 _string_8a_copy_byte/imm32/subx-name -17223 1/imm32/rm32-is-first-inout -17224 3/imm32/r32-is-first-output -17225 0/imm32/no-imm32 -17226 0/imm32/no-imm8 -17227 0/imm32/no-disp32 -17228 1/imm32/output-is-write-only -17229 0x11/imm32/alloc-id:fake -17230 _Primitive-copy-byte-from-mem/imm32/next -17231 _Primitive-copy-byte-from-mem: -17232 0x11/imm32/alloc-id:fake:payload -17233 # var/reg <- copy-byte *var2/reg2 => 8a/byte-> *var2 var/r32 -17234 0x11/imm32/alloc-id:fake -17235 _string-copy-byte/imm32/name -17236 0x11/imm32/alloc-id:fake -17237 Single-byte-var-in-mem/imm32/inouts -17238 0x11/imm32/alloc-id:fake -17239 Single-byte-var-in-some-register/imm32/outputs -17240 0x11/imm32/alloc-id:fake -17241 _string_8a_copy_byte/imm32/subx-name -17242 1/imm32/rm32-is-first-inout -17243 3/imm32/r32-is-first-output -17244 0/imm32/no-imm32 -17245 0/imm32/no-imm8 -17246 0/imm32/no-disp32 -17247 1/imm32/output-is-write-only -17248 0x11/imm32/alloc-id:fake -17249 _Primitive-copy-byte-to-mem/imm32/next -17250 _Primitive-copy-byte-to-mem: -17251 0x11/imm32/alloc-id:fake:payload -17252 # copy-byte-to *var1/reg1, var2/reg2 => 88/byte<- *reg1 reg2/r32 -17253 0x11/imm32/alloc-id:fake -17254 _string-copy-byte-to/imm32/name -17255 0x11/imm32/alloc-id:fake -17256 Two-args-byte-stack-byte-reg/imm32/inouts -17257 0/imm32/no-outputs -17258 0/imm32/no-outputs -17259 0x11/imm32/alloc-id:fake -17260 _string_88_copy_byte/imm32/subx-name -17261 1/imm32/rm32-is-first-inout -17262 2/imm32/r32-is-second-inout -17263 0/imm32/no-imm32 -17264 0/imm32/no-imm8 -17265 0/imm32/no-disp32 -17266 0/imm32/output-is-write-only -17267 0x11/imm32/alloc-id:fake -17268 _Primitive-address/imm32/next -17269 # - address -17270 _Primitive-address: # (payload primitive) -17271 0x11/imm32/alloc-id:fake:payload -17272 # var1/reg <- address var2 => 8d/copy-address var2/rm32 var1/r32 -17273 0x11/imm32/alloc-id:fake -17274 _string-address/imm32/name -17275 0x11/imm32/alloc-id:fake -17276 Single-int-var-in-mem/imm32/inouts -17277 0x11/imm32/alloc-id:fake -17278 Single-addr-var-in-some-register/imm32/outputs -17279 0x11/imm32/alloc-id:fake -17280 _string_8d_copy_address/imm32/subx-name -17281 1/imm32/rm32-is-first-inout -17282 3/imm32/r32-is-first-output -17283 0/imm32/no-imm32 -17284 0/imm32/no-imm8 -17285 0/imm32/no-disp32 -17286 1/imm32/output-is-write-only -17287 0x11/imm32/alloc-id:fake -17288 _Primitive-compare-reg-with-reg/imm32/next -17289 # - compare -17290 _Primitive-compare-reg-with-reg: # (payload primitive) -17291 0x11/imm32/alloc-id:fake:payload -17292 # compare var1/reg1 var2/reg2 => 39/compare var1/rm32 var2/r32 -17293 0x11/imm32/alloc-id:fake -17294 _string-compare/imm32/name -17295 0x11/imm32/alloc-id:fake -17296 Two-int-args-in-regs/imm32/inouts -17297 0/imm32/no-outputs -17298 0/imm32/no-outputs -17299 0x11/imm32/alloc-id:fake -17300 _string_39_compare->/imm32/subx-name -17301 1/imm32/rm32-is-first-inout -17302 2/imm32/r32-is-second-inout -17303 0/imm32/no-imm32 -17304 0/imm32/no-imm8 -17305 0/imm32/no-disp32 -17306 0/imm32/output-is-write-only -17307 0x11/imm32/alloc-id:fake -17308 _Primitive-compare-mem-with-reg/imm32/next -17309 _Primitive-compare-mem-with-reg: # (payload primitive) -17310 0x11/imm32/alloc-id:fake:payload -17311 # compare var1 var2/reg => 39/compare var1/rm32 var2/r32 -17312 0x11/imm32/alloc-id:fake -17313 _string-compare/imm32/name -17314 0x11/imm32/alloc-id:fake -17315 Two-args-int-stack-int-reg/imm32/inouts -17316 0/imm32/no-outputs -17317 0/imm32/no-outputs -17318 0x11/imm32/alloc-id:fake -17319 _string_39_compare->/imm32/subx-name -17320 1/imm32/rm32-is-first-inout -17321 2/imm32/r32-is-second-inout -17322 0/imm32/no-imm32 -17323 0/imm32/no-imm8 -17324 0/imm32/no-disp32 -17325 0/imm32/output-is-write-only -17326 0x11/imm32/alloc-id:fake -17327 _Primitive-compare-reg-with-mem/imm32/next -17328 _Primitive-compare-reg-with-mem: # (payload primitive) -17329 0x11/imm32/alloc-id:fake:payload -17330 # compare var1/reg var2 => 3b/compare<- var2/rm32 var1/r32 -17331 0x11/imm32/alloc-id:fake -17332 _string-compare/imm32/name -17333 0x11/imm32/alloc-id:fake -17334 Two-args-int-reg-int-stack/imm32/inouts -17335 0/imm32/no-outputs -17336 0/imm32/no-outputs -17337 0x11/imm32/alloc-id:fake -17338 _string_3b_compare<-/imm32/subx-name -17339 2/imm32/rm32-is-second-inout -17340 1/imm32/r32-is-first-inout -17341 0/imm32/no-imm32 -17342 0/imm32/no-imm8 -17343 0/imm32/no-disp32 -17344 0/imm32/output-is-write-only -17345 0x11/imm32/alloc-id:fake -17346 _Primitive-compare-eax-with-literal/imm32/next -17347 _Primitive-compare-eax-with-literal: # (payload primitive) -17348 0x11/imm32/alloc-id:fake:payload -17349 # compare var1/eax n => 3d/compare-eax-with n/imm32 -17350 0x11/imm32/alloc-id:fake -17351 _string-compare/imm32/name -17352 0x11/imm32/alloc-id:fake -17353 Two-args-int-eax-int-literal/imm32/inouts -17354 0/imm32/no-outputs -17355 0/imm32/no-outputs -17356 0x11/imm32/alloc-id:fake -17357 _string_3d_compare_eax_with/imm32/subx-name -17358 0/imm32/no-rm32 -17359 0/imm32/no-r32 -17360 2/imm32/imm32-is-second-inout -17361 0/imm32/no-imm8 -17362 0/imm32/no-disp32 -17363 0/imm32/output-is-write-only -17364 0x11/imm32/alloc-id:fake -17365 _Primitive-compare-reg-with-literal/imm32/next -17366 _Primitive-compare-reg-with-literal: # (payload primitive) -17367 0x11/imm32/alloc-id:fake:payload -17368 # compare var1/reg n => 81 7/subop/compare %reg n/imm32 -17369 0x11/imm32/alloc-id:fake -17370 _string-compare/imm32/name -17371 0x11/imm32/alloc-id:fake -17372 Int-var-in-register-and-literal/imm32/inouts -17373 0/imm32/no-outputs -17374 0/imm32/no-outputs -17375 0x11/imm32/alloc-id:fake -17376 _string_81_subop_compare/imm32/subx-name -17377 1/imm32/rm32-is-first-inout -17378 0/imm32/no-r32 -17379 2/imm32/imm32-is-second-inout -17380 0/imm32/no-imm8 -17381 0/imm32/no-disp32 -17382 0/imm32/output-is-write-only -17383 0x11/imm32/alloc-id:fake -17384 _Primitive-compare-mem-with-literal/imm32/next -17385 _Primitive-compare-mem-with-literal: # (payload primitive) -17386 0x11/imm32/alloc-id:fake:payload -17387 # compare var1 n => 81 7/subop/compare *(ebp+___) n/imm32 -17388 0x11/imm32/alloc-id:fake -17389 _string-compare/imm32/name -17390 0x11/imm32/alloc-id:fake -17391 Int-var-and-literal/imm32/inouts -17392 0/imm32/no-outputs -17393 0/imm32/no-outputs -17394 0x11/imm32/alloc-id:fake -17395 _string_81_subop_compare/imm32/subx-name -17396 1/imm32/rm32-is-first-inout -17397 0/imm32/no-r32 -17398 2/imm32/imm32-is-second-inout -17399 0/imm32/no-imm8 -17400 0/imm32/no-disp32 -17401 0/imm32/output-is-write-only -17402 0x11/imm32/alloc-id:fake -17403 _Primitive-multiply-reg-by-reg/imm32/next -17404 # - multiply -17405 _Primitive-multiply-reg-by-reg: # (payload primitive) -17406 0x11/imm32/alloc-id:fake:payload -17407 # var1/reg <- multiply var2 => 0f af/multiply var2/rm32 var1/r32 -17408 0x11/imm32/alloc-id:fake -17409 _string-multiply/imm32/name -17410 0x11/imm32/alloc-id:fake -17411 Single-int-var-in-some-register/imm32/inouts -17412 0x11/imm32/alloc-id:fake -17413 Single-int-var-in-some-register/imm32/outputs +14757 $populate-mu-type-offsets-in-inouts:end: +14758 # . restore registers +14759 5f/pop-to-edi +14760 5b/pop-to-ebx +14761 5a/pop-to-edx +14762 59/pop-to-ecx +14763 58/pop-to-eax +14764 # . epilogue +14765 89/<- %esp 5/r32/ebp +14766 5d/pop-to-ebp +14767 c3/return +14768 +14769 emit-subx-stmt-list: # out: (addr buffered-file), stmts: (addr list stmt), vars: (addr stack live-var), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +14770 # . prologue +14771 55/push-ebp +14772 89/<- %ebp 4/r32/esp +14773 # . save registers +14774 50/push-eax +14775 51/push-ecx +14776 53/push-ebx +14777 56/push-esi +14778 # esi = stmts +14779 8b/-> *(ebp+0xc) 6/r32/esi +14780 # +14781 { +14782 $emit-subx-stmt-list:loop: +14783 81 7/subop/compare %esi 0/imm32 +14784 0f 84/jump-if-= break/disp32 +14785 # var curr-stmt/ecx: (addr stmt) = lookup(stmts->value) +14786 (lookup *esi *(esi+4)) # List-value List-value => eax +14787 89/<- %ecx 0/r32/eax +14788 { +14789 $emit-subx-stmt-list:check-for-block: +14790 81 7/subop/compare *ecx 0/imm32/block # Stmt-tag +14791 75/jump-if-!= break/disp8 +14792 $emit-subx-stmt-list:block: +14793 (emit-subx-block *(ebp+8) %ecx *(ebp+0x10) *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c)) +14794 } +14795 { +14796 $emit-subx-stmt-list:check-for-stmt: +14797 81 7/subop/compare *ecx 1/imm32/stmt1 # Stmt-tag +14798 0f 85/jump-if-!= break/disp32 +14799 $emit-subx-stmt-list:stmt1: +14800 { +14801 (is-mu-branch? %ecx) # => eax +14802 3d/compare-eax-and 0/imm32/false +14803 0f 84/jump-if-= break/disp32 +14804 $emit-subx-stmt-list:branch-stmt: +14805 +-- 27 lines: # unconditional loops ----------------------------------------------------------------------------------------------------------------------------------------------------- +14832 +-- 16 lines: # unconditional breaks ---------------------------------------------------------------------------------------------------------------------------------------------------- +14848 +-- 38 lines: # simple conditional branches without a target ---------------------------------------------------------------------------------------------------------------------------- +14886 +-- 19 lines: # conditional branches with an explicit target ---------------------------------------------------------------------------------------------------------------------------- +14905 } +14906 $emit-subx-stmt-list:1-to-1: +14907 (emit-subx-stmt *(ebp+8) %ecx Primitives *(ebp+0x18) *(ebp+0x1c)) +14908 e9/jump $emit-subx-stmt-list:continue/disp32 +14909 } +14910 { +14911 $emit-subx-stmt-list:check-for-var-def: +14912 81 7/subop/compare *ecx 2/imm32/var-def # Stmt-tag +14913 75/jump-if-!= break/disp8 +14914 $emit-subx-stmt-list:var-def: +14915 (emit-subx-var-def *(ebp+8) %ecx) +14916 (push *(ebp+0x10) *(ecx+4)) # Vardef-var +14917 (push *(ebp+0x10) *(ecx+8)) # Vardef-var +14918 (push *(ebp+0x10) 0) # Live-var-register-spilled = 0 for vars on the stack +14919 # +14920 eb/jump $emit-subx-stmt-list:continue/disp8 +14921 } +14922 { +14923 $emit-subx-stmt-list:check-for-reg-var-def: +14924 81 7/subop/compare *ecx 3/imm32/reg-var-def # Stmt-tag +14925 0f 85/jump-if-!= break/disp32 +14926 $emit-subx-stmt-list:reg-var-def: +14927 # TODO: ensure that there's exactly one output +14928 (push-output-and-maybe-emit-spill *(ebp+8) %ecx *(ebp+0x10) %esi *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c)) +14929 # emit the instruction as usual +14930 (emit-subx-stmt *(ebp+8) %ecx Primitives *(ebp+0x18) *(ebp+0x1c)) +14931 # +14932 eb/jump $emit-subx-stmt-list:continue/disp8 +14933 } +14934 $emit-subx-stmt-list:continue: +14935 # TODO: raise an error on unrecognized Stmt-tag +14936 (lookup *(esi+8) *(esi+0xc)) # List-next List-next => eax +14937 89/<- %esi 0/r32/eax +14938 e9/jump loop/disp32 +14939 } +14940 $emit-subx-stmt-list:emit-cleanup: +14941 (emit-cleanup-code-until-depth *(ebp+8) *(ebp+0x10) *Curr-block-depth) +14942 $emit-subx-stmt-list:clean-up: +14943 (clean-up-blocks *(ebp+0x10) *Curr-block-depth *(ebp+0x14)) +14944 $emit-subx-stmt-list:end: +14945 # . restore registers +14946 5e/pop-to-esi +14947 5b/pop-to-ebx +14948 59/pop-to-ecx +14949 58/pop-to-eax +14950 # . epilogue +14951 89/<- %esp 5/r32/ebp +14952 5d/pop-to-ebp +14953 c3/return +14954 +14955 # 'later-stmts' includes 'stmt', but will behave the same even without it; reg-var-def stmts are guaranteed not to write to function outputs. +14956 push-output-and-maybe-emit-spill: # out: (addr buffered-file), stmt: (addr reg-var-def), vars: (addr stack (handle var)), later-stmts: (addr list stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +14957 # . prologue +14958 55/push-ebp +14959 89/<- %ebp 4/r32/esp +14960 # . save registers +14961 50/push-eax +14962 51/push-ecx +14963 52/push-edx +14964 # ecx = stmt +14965 8b/-> *(ebp+0xc) 1/r32/ecx +14966 # var sv/eax: (addr stmt-var) = lookup(curr-stmt->outputs) +14967 (lookup *(ecx+0x14) *(ecx+0x18)) # Regvardef-outputs Regvardef-outputs => eax +14968 # TODO: assert !sv->is-deref? +14969 # var v/ecx: (addr var) = lookup(sv->value) +14970 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +14971 89/<- %ecx 0/r32/eax +14972 # v->block-depth = *Curr-block-depth +14973 8b/-> *Curr-block-depth 0/r32/eax +14974 89/<- *(ecx+0x10) 0/r32/eax # Var-block-depth +14975 #? (write-buffered Stderr "var ") +14976 #? (lookup *ecx *(ecx+4)) +14977 #? (write-buffered Stderr %eax) +14978 #? (write-buffered Stderr " at depth ") +14979 #? (write-int32-hex-buffered Stderr *(ecx+0x10)) +14980 #? (write-buffered Stderr Newline) +14981 #? (flush Stderr) +14982 # ensure that v is in a register +14983 81 7/subop/compare *(ecx+0x18) 0/imm32 # Var-register +14984 0f 84/jump-if-= $push-output-and-maybe-emit-spill:abort/disp32 +14985 # var emit-spill?/edx: boolean = not-yet-spilled-this-block? && will-not-write-some-register?(fn) +14986 (not-yet-spilled-this-block? %ecx *(ebp+0x10)) # => eax +14987 89/<- %edx 0/r32/eax +14988 3d/compare-eax-and 0/imm32/false +14989 0f 84/jump-if-= $push-output-and-maybe-emit-spill:push/disp32 +14990 (will-not-write-some-register? %ecx *(ebp+0x14) *(ebp+0x18)) # => eax +14991 89/<- %edx 0/r32/eax +14992 # check emit-spill? +14993 3d/compare-eax-and 0/imm32/false +14994 0f 84/jump-if-= $push-output-and-maybe-emit-spill:push/disp32 +14995 # TODO: assert(size-of(output) == 4) +14996 # *Curr-local-stack-offset -= 4 +14997 81 5/subop/subtract *Curr-local-stack-offset 4/imm32 +14998 # emit spill +14999 (emit-indent *(ebp+8) *Curr-block-depth) +15000 (write-buffered *(ebp+8) "ff 6/subop/push %") +15001 (lookup *(ecx+0x18) *(ecx+0x1c)) # Var-register Var-register => eax +15002 (write-buffered *(ebp+8) %eax) +15003 (write-buffered *(ebp+8) Newline) +15004 $push-output-and-maybe-emit-spill:push: +15005 8b/-> *(ebp+0xc) 1/r32/ecx +15006 (lookup *(ecx+0x14) *(ecx+0x18)) # Regvardef-outputs Regvardef-outputs => eax +15007 # push(vars, {sv->value, emit-spill?}) +15008 (push *(ebp+0x10) *eax) # Stmt-var-value +15009 (push *(ebp+0x10) *(eax+4)) # Stmt-var-value +15010 (push *(ebp+0x10) %edx) +15011 $push-output-and-maybe-emit-spill:end: +15012 # . restore registers +15013 5a/pop-to-edx +15014 59/pop-to-ecx +15015 58/pop-to-eax +15016 # . epilogue +15017 89/<- %esp 5/r32/ebp +15018 5d/pop-to-ebp +15019 c3/return +15020 +15021 $push-output-and-maybe-emit-spill:abort: +15022 # error("var '" var->name "' initialized from an instruction must live in a register\n") +15023 (write-buffered *(ebp+0x1c) "var '") +15024 (write-buffered *(ebp+0x1c) *eax) # Var-name +15025 (write-buffered *(ebp+0x1c) "' initialized from an instruction must live in a register\n") +15026 (flush *(ebp+0x1c)) +15027 (stop *(ebp+0x20) 1) +15028 # never gets here +15029 +15030 emit-subx-cleanup-and-unconditional-nonlocal-branch: # out: (addr buffered-file), stmt: (addr stmt1), vars: (addr stack live-var) +15031 # . prologue +15032 55/push-ebp +15033 89/<- %ebp 4/r32/esp +15034 # . save registers +15035 50/push-eax +15036 51/push-ecx +15037 # ecx = stmt +15038 8b/-> *(ebp+0xc) 1/r32/ecx +15039 # var target/eax: (addr array byte) = curr-stmt->inouts->value->name +15040 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax +15041 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +15042 (lookup *eax *(eax+4)) # Var-name Var-name => eax +15043 # clean up until target block +15044 (emit-cleanup-code-until-target *(ebp+8) *(ebp+0x10) %eax) +15045 # emit jump to target block +15046 (emit-indent *(ebp+8) *Curr-block-depth) +15047 (write-buffered *(ebp+8) "e9/jump ") +15048 (write-buffered *(ebp+8) %eax) +15049 (lookup *(ecx+4) *(ecx+8)) # Stmt1-operation Stmt1-operation => eax +15050 (string-starts-with? %eax "break") +15051 3d/compare-eax-and 0/imm32/false +15052 { +15053 74/jump-if-= break/disp8 +15054 (write-buffered *(ebp+8) ":break/disp32\n") +15055 } +15056 3d/compare-eax-and 0/imm32/false # just in case the function call modified flags +15057 { +15058 75/jump-if-!= break/disp8 +15059 (write-buffered *(ebp+8) ":loop/disp32\n") +15060 } +15061 $emit-subx-cleanup-and-unconditional-nonlocal-branch:end: +15062 # . restore registers +15063 59/pop-to-ecx +15064 58/pop-to-eax +15065 # . epilogue +15066 89/<- %esp 5/r32/ebp +15067 5d/pop-to-ebp +15068 c3/return +15069 +15070 is-mu-branch?: # stmt: (addr stmt1) -> result/eax: boolean +15071 # . prologue +15072 55/push-ebp +15073 89/<- %ebp 4/r32/esp +15074 # . save registers +15075 51/push-ecx +15076 # ecx = lookup(stmt->operation) +15077 8b/-> *(ebp+8) 1/r32/ecx +15078 (lookup *(ecx+4) *(ecx+8)) # Stmt1-operation Stmt1-operation => eax +15079 89/<- %ecx 0/r32/eax +15080 # if (stmt->operation starts with "loop") return true +15081 (string-starts-with? %ecx "loop") # => eax +15082 3d/compare-eax-and 0/imm32/false +15083 75/jump-if-not-equal $is-mu-branch?:end/disp8 +15084 # otherwise return (stmt->operation starts with "break") +15085 (string-starts-with? %ecx "break") # => eax +15086 $is-mu-branch?:end: +15087 # . restore registers +15088 59/pop-to-ecx +15089 # . epilogue +15090 89/<- %esp 5/r32/ebp +15091 5d/pop-to-ebp +15092 c3/return +15093 +15094 emit-reverse-break: # out: (addr buffered-file), stmt: (addr stmt1) +15095 # . prologue +15096 55/push-ebp +15097 89/<- %ebp 4/r32/esp +15098 # . save registers +15099 50/push-eax +15100 # eax = stmt +15101 8b/-> *(ebp+0xc) 0/r32/eax +15102 # +15103 (lookup *(eax+4) *(eax+8)) # Stmt1-operation Stmt1-operation => eax +15104 (get Reverse-branch %eax 0x10 "reverse-branch: ") # => eax: (addr handle array byte) +15105 (emit-indent *(ebp+8) *Curr-block-depth) +15106 (lookup *eax *(eax+4)) # => eax +15107 (write-buffered *(ebp+8) %eax) +15108 (write-buffered *(ebp+8) " break/disp32\n") +15109 $emit-reverse-break:end: +15110 # . restore registers +15111 58/pop-to-eax +15112 # . epilogue +15113 89/<- %esp 5/r32/ebp +15114 5d/pop-to-ebp +15115 c3/return +15116 +15117 == data +15118 +15119 # Table from Mu branch instructions to the reverse SubX opcodes for them. +15120 Reverse-branch: # (table (handle array byte) (handle array byte)) +15121 # a table is a stream +15122 0x140/imm32/write +15123 0/imm32/read +15124 0x140/imm32/size +15125 # data +15126 0x11/imm32/alloc-id _string-break-if-=/imm32 0x11/imm32/alloc-id _string_0f_85_jump_label/imm32 +15127 0x11/imm32/alloc-id _string-loop-if-=/imm32 0x11/imm32/alloc-id _string_0f_85_jump_label/imm32 +15128 0x11/imm32/alloc-id _string-break-if-!=/imm32 0x11/imm32/alloc-id _string_0f_84_jump_label/imm32 +15129 0x11/imm32/alloc-id _string-loop-if-!=/imm32 0x11/imm32/alloc-id _string_0f_84_jump_label/imm32 +15130 0x11/imm32/alloc-id _string-break-if-</imm32 0x11/imm32/alloc-id _string_0f_8d_jump_label/imm32 +15131 0x11/imm32/alloc-id _string-loop-if-</imm32 0x11/imm32/alloc-id _string_0f_8d_jump_label/imm32 +15132 0x11/imm32/alloc-id _string-break-if->/imm32 0x11/imm32/alloc-id _string_0f_8e_jump_label/imm32 +15133 0x11/imm32/alloc-id _string-loop-if->/imm32 0x11/imm32/alloc-id _string_0f_8e_jump_label/imm32 +15134 0x11/imm32/alloc-id _string-break-if-<=/imm32 0x11/imm32/alloc-id _string_0f_87_jump_label/imm32 +15135 0x11/imm32/alloc-id _string-loop-if-<=/imm32 0x11/imm32/alloc-id _string_0f_87_jump_label/imm32 +15136 0x11/imm32/alloc-id _string-break-if->=/imm32 0x11/imm32/alloc-id _string_0f_8c_jump_label/imm32 +15137 0x11/imm32/alloc-id _string-loop-if->=/imm32 0x11/imm32/alloc-id _string_0f_8c_jump_label/imm32 +15138 0x11/imm32/alloc-id _string-break-if-addr</imm32 0x11/imm32/alloc-id _string_0f_83_jump_label/imm32 +15139 0x11/imm32/alloc-id _string-loop-if-addr</imm32 0x11/imm32/alloc-id _string_0f_83_jump_label/imm32 +15140 0x11/imm32/alloc-id _string-break-if-addr>/imm32 0x11/imm32/alloc-id _string_0f_86_jump_label/imm32 +15141 0x11/imm32/alloc-id _string-loop-if-addr>/imm32 0x11/imm32/alloc-id _string_0f_86_jump_label/imm32 +15142 0x11/imm32/alloc-id _string-break-if-addr<=/imm32 0x11/imm32/alloc-id _string_0f_87_jump_label/imm32 +15143 0x11/imm32/alloc-id _string-loop-if-addr<=/imm32 0x11/imm32/alloc-id _string_0f_87_jump_label/imm32 +15144 0x11/imm32/alloc-id _string-break-if-addr>=/imm32 0x11/imm32/alloc-id _string_0f_82_jump_label/imm32 +15145 0x11/imm32/alloc-id _string-loop-if-addr>=/imm32 0x11/imm32/alloc-id _string_0f_82_jump_label/imm32 +15146 +15147 == code +15148 +15149 emit-unconditional-jump-to-depth: # out: (addr buffered-file), vars: (addr stack live-var), depth: int, label-suffix: (addr array byte) +15150 # . prologue +15151 55/push-ebp +15152 89/<- %ebp 4/r32/esp +15153 # . save registers +15154 50/push-eax +15155 51/push-ecx +15156 52/push-edx +15157 53/push-ebx +15158 56/push-esi +15159 # ecx = vars +15160 8b/-> *(ebp+0xc) 1/r32/ecx +15161 # var eax: int = vars->top +15162 8b/-> *ecx 0/r32/eax +15163 # var curr/esi: (addr handle var) = &vars->data[vars->top - 12] +15164 8d/copy-address *(ecx+eax-4) 6/r32/esi # vars + 8 + vars->top - 12/Live-var-size +15165 # var min/ecx: (addr handle var) = vars->data +15166 8d/copy-address *(ecx+8) 1/r32/ecx +15167 # edx = depth +15168 8b/-> *(ebp+0x10) 2/r32/edx +15169 { +15170 $emit-unconditional-jump-to-depth:loop: +15171 # if (curr < min) break +15172 39/compare %esi 1/r32/ecx +15173 0f 82/jump-if-addr< break/disp32 +15174 # var v/ebx: (addr var) = lookup(*curr) +15175 (lookup *esi *(esi+4)) # => eax +15176 89/<- %ebx 0/r32/eax +15177 # if (v->block-depth < until-block-depth) break +15178 39/compare *(ebx+0x10) 2/r32/edx # Var-block-depth +15179 0f 8c/jump-if-< break/disp32 +15180 { +15181 $emit-unconditional-jump-to-depth:check: +15182 # if v->block-depth != until-block-depth, continue +15183 39/compare *(ebx+0x10) 2/r32/edx # Var-block-depth +15184 0f 85/jump-if-!= break/disp32 +15185 $emit-unconditional-jump-to-depth:depth-found: +15186 # if v is not a literal, continue +15187 (size-of %ebx) # => eax +15188 3d/compare-eax-and 0/imm32 +15189 0f 85/jump-if-!= break/disp32 +15190 $emit-unconditional-jump-to-depth:label-found: +15191 # emit unconditional jump, then return +15192 (emit-indent *(ebp+8) *Curr-block-depth) +15193 (write-buffered *(ebp+8) "e9/jump ") +15194 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax +15195 (write-buffered *(ebp+8) %eax) +15196 (write-buffered *(ebp+8) ":") +15197 (write-buffered *(ebp+8) *(ebp+0x14)) +15198 (write-buffered *(ebp+8) "/disp32\n") +15199 eb/jump $emit-unconditional-jump-to-depth:end/disp8 +15200 } +15201 # curr -= 12 +15202 81 5/subop/subtract %esi 0xc/imm32 +15203 e9/jump loop/disp32 +15204 } +15205 # TODO: error if no label at 'depth' was found +15206 $emit-unconditional-jump-to-depth:end: +15207 # . restore registers +15208 5e/pop-to-esi +15209 5b/pop-to-ebx +15210 5a/pop-to-edx +15211 59/pop-to-ecx +15212 58/pop-to-eax +15213 # . epilogue +15214 89/<- %esp 5/r32/ebp +15215 5d/pop-to-ebp +15216 c3/return +15217 +15218 # emit clean-up code for 'vars' until some block depth +15219 # doesn't actually modify 'vars' so we need traverse manually inside the stack +15220 emit-cleanup-code-until-depth: # out: (addr buffered-file), vars: (addr stack live-var), until-block-depth: int +15221 # . prologue +15222 55/push-ebp +15223 89/<- %ebp 4/r32/esp +15224 # . save registers +15225 50/push-eax +15226 51/push-ecx +15227 52/push-edx +15228 53/push-ebx +15229 56/push-esi +15230 #? (write-buffered Stderr "--- cleanup\n") +15231 #? (flush Stderr) +15232 # ecx = vars +15233 8b/-> *(ebp+0xc) 1/r32/ecx +15234 # var esi: int = vars->top +15235 8b/-> *ecx 6/r32/esi +15236 # var curr/esi: (addr handle var) = &vars->data[vars->top - 12] +15237 8d/copy-address *(ecx+esi-4) 6/r32/esi # vars + 8 + vars->top - 12/Live-var-size +15238 # var min/ecx: (addr handle var) = vars->data +15239 81 0/subop/add %ecx 8/imm32 +15240 # edx = until-block-depth +15241 8b/-> *(ebp+0x10) 2/r32/edx +15242 { +15243 $emit-cleanup-code-until-depth:loop: +15244 # if (curr < min) break +15245 39/compare %esi 1/r32/ecx +15246 0f 82/jump-if-addr< break/disp32 +15247 # var v/ebx: (addr var) = lookup(*curr) +15248 (lookup *esi *(esi+4)) # => eax +15249 89/<- %ebx 0/r32/eax +15250 #? (lookup *ebx *(ebx+4)) # Var-name +15251 #? (write-buffered Stderr "var ") +15252 #? (write-buffered Stderr %eax) +15253 #? (write-buffered Stderr Newline) +15254 #? (flush Stderr) +15255 # if (v->block-depth < until-block-depth) break +15256 39/compare *(ebx+0x10) 2/r32/edx # Var-block-depth +15257 0f 8c/jump-if-< break/disp32 +15258 # if v is in a register +15259 81 7/subop/compare *(ebx+0x18) 0/imm32 # Var-register +15260 { +15261 0f 84/jump-if-= break/disp32 +15262 { +15263 $emit-cleanup-code-until-depth:check-for-previous-spill: +15264 8b/-> *(esi+8) 0/r32/eax # Live-var-register-spilled +15265 3d/compare-eax-and 0/imm32/false +15266 74/jump-if-= break/disp8 +15267 $emit-cleanup-code-until-depth:reclaim-var-in-register: +15268 (emit-indent *(ebp+8) *Curr-block-depth) +15269 (write-buffered *(ebp+8) "8f 0/subop/pop %") +15270 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register Var-register => eax +15271 (write-buffered *(ebp+8) %eax) +15272 (write-buffered *(ebp+8) Newline) +15273 } +15274 eb/jump $emit-cleanup-code-until-depth:continue/disp8 +15275 } +15276 # otherwise v is on the stack +15277 { +15278 75/jump-if-!= break/disp8 +15279 $emit-cleanup-code-until-depth:var-on-stack: +15280 (size-of %ebx) # => eax +15281 # don't emit code for labels +15282 3d/compare-eax-and 0/imm32 +15283 74/jump-if-= break/disp8 +15284 $emit-cleanup-code-until-depth:reclaim-var-on-stack: +15285 (emit-indent *(ebp+8) *Curr-block-depth) +15286 (write-buffered *(ebp+8) "81 0/subop/add %esp ") +15287 (write-int32-hex-buffered *(ebp+8) %eax) +15288 (write-buffered *(ebp+8) "/imm32\n") +15289 } +15290 $emit-cleanup-code-until-depth:continue: +15291 # curr -= 12 +15292 81 5/subop/subtract %esi 0xc/imm32 +15293 e9/jump loop/disp32 +15294 } +15295 $emit-cleanup-code-until-depth:end: +15296 # . restore registers +15297 5e/pop-to-esi +15298 5b/pop-to-ebx +15299 5a/pop-to-edx +15300 59/pop-to-ecx +15301 58/pop-to-eax +15302 # . epilogue +15303 89/<- %esp 5/r32/ebp +15304 5d/pop-to-ebp +15305 c3/return +15306 +15307 # emit clean-up code for 'vars' until a given label is encountered +15308 # doesn't actually modify 'vars' so we need traverse manually inside the stack +15309 emit-cleanup-code-until-target: # out: (addr buffered-file), vars: (addr stack live-var), until-block-label: (addr array byte) +15310 # . prologue +15311 55/push-ebp +15312 89/<- %ebp 4/r32/esp +15313 # . save registers +15314 50/push-eax +15315 51/push-ecx +15316 52/push-edx +15317 53/push-ebx +15318 # ecx = vars +15319 8b/-> *(ebp+0xc) 1/r32/ecx +15320 # var eax: int = vars->top +15321 8b/-> *ecx 0/r32/eax +15322 # var curr/edx: (addr handle var) = &vars->data[vars->top - 12] +15323 8d/copy-address *(ecx+eax-4) 2/r32/edx # vars + 8 + vars->top - 12/Live-var-size +15324 # var min/ecx: (addr handle var) = vars->data +15325 81 0/subop/add %ecx 8/imm32 +15326 { +15327 $emit-cleanup-code-until-target:loop: +15328 # if (curr < min) break +15329 39/compare %edx 1/r32/ecx +15330 0f 82/jump-if-addr< break/disp32 +15331 # var v/ebx: (handle var) = lookup(*curr) +15332 (lookup *edx *(edx+4)) # => eax +15333 89/<- %ebx 0/r32/eax +15334 # if (v->name == until-block-label) break +15335 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax +15336 (string-equal? %eax *(ebp+0x10)) # => eax +15337 3d/compare-eax-and 0/imm32/false +15338 0f 85/jump-if-!= break/disp32 +15339 # if v is in a register +15340 81 7/subop/compare *(ebx+0x18) 0/imm32 # Var-register +15341 { +15342 0f 84/jump-if-= break/disp32 +15343 { +15344 $emit-cleanup-code-until-target:check-for-previous-spill: +15345 8b/-> *(edx+8) 0/r32/eax # Live-var-register-spilled +15346 3d/compare-eax-and 0/imm32/false +15347 74/jump-if-= break/disp8 +15348 $emit-cleanup-code-until-target:reclaim-var-in-register: +15349 (emit-indent *(ebp+8) *Curr-block-depth) +15350 (write-buffered *(ebp+8) "8f 0/subop/pop %") +15351 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register Var-register => eax +15352 (write-buffered *(ebp+8) %eax) +15353 (write-buffered *(ebp+8) Newline) +15354 } +15355 eb/jump $emit-cleanup-code-until-target:continue/disp8 +15356 } +15357 # otherwise v is on the stack +15358 { +15359 75/jump-if-!= break/disp8 +15360 $emit-cleanup-code-until-target:reclaim-var-on-stack: +15361 (size-of %ebx) # => eax +15362 # don't emit code for labels +15363 3d/compare-eax-and 0/imm32 +15364 74/jump-if-= break/disp8 +15365 # +15366 (emit-indent *(ebp+8) *Curr-block-depth) +15367 (write-buffered *(ebp+8) "81 0/subop/add %esp ") +15368 (write-int32-hex-buffered *(ebp+8) %eax) +15369 (write-buffered *(ebp+8) "/imm32\n") +15370 } +15371 $emit-cleanup-code-until-target:continue: +15372 # curr -= 12 +15373 81 5/subop/subtract %edx 0xc/imm32 +15374 e9/jump loop/disp32 +15375 } +15376 $emit-cleanup-code-until-target:end: +15377 # . restore registers +15378 5b/pop-to-ebx +15379 5a/pop-to-edx +15380 59/pop-to-ecx +15381 58/pop-to-eax +15382 # . epilogue +15383 89/<- %esp 5/r32/ebp +15384 5d/pop-to-ebp +15385 c3/return +15386 +15387 # Return true if there isn't a variable in 'vars' with the same block-depth +15388 # and register as 'v'. +15389 # 'v' is guaranteed not to be within 'vars'. +15390 not-yet-spilled-this-block?: # v: (addr var), vars: (addr stack live-var) -> result/eax: boolean +15391 # . prologue +15392 55/push-ebp +15393 89/<- %ebp 4/r32/esp +15394 # . save registers +15395 51/push-ecx +15396 52/push-edx +15397 53/push-ebx +15398 56/push-esi +15399 57/push-edi +15400 # ecx = vars +15401 8b/-> *(ebp+0xc) 1/r32/ecx +15402 # var eax: int = vars->top +15403 8b/-> *ecx 0/r32/eax +15404 # var curr/edx: (addr handle var) = &vars->data[vars->top - 12] +15405 8d/copy-address *(ecx+eax-4) 2/r32/edx # vars + 8 + vars->top - 12/Live-var-size +15406 # var min/ecx: (addr handle var) = vars->data +15407 8d/copy-address *(ecx+8) 1/r32/ecx +15408 # var depth/ebx: int = v->block-depth +15409 8b/-> *(ebp+8) 3/r32/ebx +15410 8b/-> *(ebx+0x10) 3/r32/ebx # Var-block-depth +15411 # var needle/esi: (addr array byte) = v->register +15412 8b/-> *(ebp+8) 6/r32/esi +15413 (lookup *(esi+0x18) *(esi+0x1c)) # Var-register Var-register => eax +15414 89/<- %esi 0/r32/eax +15415 { +15416 $not-yet-spilled-this-block?:loop: +15417 # if (curr < min) break +15418 39/compare %edx 1/r32/ecx +15419 0f 82/jump-if-addr< break/disp32 +15420 # var cand/edi: (addr var) = lookup(*curr) +15421 (lookup *edx *(edx+4)) # => eax +15422 89/<- %edi 0/r32/eax +15423 # if (cand->block-depth < depth) break +15424 39/compare *(edi+0x10) 3/r32/ebx # Var-block-depth +15425 0f 8c/jump-if-< break/disp32 +15426 # var cand-reg/edi: (array array byte) = cand->reg +15427 (lookup *(edi+0x18) *(edi+0x1c)) # Var-register Var-register => eax +15428 89/<- %edi 0/r32/eax +15429 # if (cand-reg == null) continue +15430 { +15431 $not-yet-spilled-this-block?:check-reg: +15432 81 7/subop/compare %edi 0/imm32 +15433 0f 84/jump-if-= break/disp32 +15434 # if (cand-reg == needle) return true +15435 (string-equal? %esi %edi) # => eax +15436 3d/compare-eax-and 0/imm32/false +15437 74/jump-if-= break/disp8 +15438 $not-yet-spilled-this-block?:return-false: +15439 b8/copy-to-eax 0/imm32/false +15440 eb/jump $not-yet-spilled-this-block?:end/disp8 +15441 } +15442 $not-yet-spilled-this-block?:continue: +15443 # curr -= 12 +15444 81 5/subop/subtract %edx 0xc/imm32 +15445 e9/jump loop/disp32 +15446 } +15447 $not-yet-spilled-this-block?:return-true: +15448 # return true +15449 b8/copy-to-eax 1/imm32/true +15450 $not-yet-spilled-this-block?:end: +15451 # . restore registers +15452 5f/pop-to-edi +15453 5e/pop-to-esi +15454 5b/pop-to-ebx +15455 5a/pop-to-edx +15456 59/pop-to-ecx +15457 # . epilogue +15458 89/<- %esp 5/r32/ebp +15459 5d/pop-to-ebp +15460 c3/return +15461 +15462 # could the register of 'v' ever be written to by one of the vars in fn-outputs? +15463 will-not-write-some-register?: # v: (addr var), stmts: (addr list stmt), fn: (addr function) -> result/eax: boolean +15464 # . prologue +15465 55/push-ebp +15466 89/<- %ebp 4/r32/esp +15467 # eax = v +15468 8b/-> *(ebp+8) 0/r32/eax +15469 # var reg/eax: (addr array byte) = lookup(v->register) +15470 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax +15471 # var target/eax: (addr var) = find-register(fn-outputs, reg) +15472 (find-register *(ebp+0x10) %eax) # => eax +15473 # if (target == 0) return true +15474 { +15475 3d/compare-eax-and 0/imm32 +15476 75/jump-if-!= break/disp8 +15477 b8/copy-to-eax 1/imm32/true +15478 eb/jump $will-not-write-some-register?:end/disp8 +15479 } +15480 # return !assigns-in-stmts?(stmts, target) +15481 (assigns-in-stmts? *(ebp+0xc) %eax) # => eax +15482 3d/compare-eax-and 0/imm32/false +15483 # assume: true = 1, so no need to mask with 0x000000ff +15484 0f 94/set-if-= %al +15485 $will-not-write-some-register?:end: +15486 # . epilogue +15487 89/<- %esp 5/r32/ebp +15488 5d/pop-to-ebp +15489 c3/return +15490 +15491 # return fn output with matching register +15492 # always returns false if 'reg' is null +15493 find-register: # fn: (addr function), reg: (addr array byte) -> result/eax: (addr var) +15494 # . prologue +15495 55/push-ebp +15496 89/<- %ebp 4/r32/esp +15497 # . save registers +15498 51/push-ecx +15499 # var curr/ecx: (addr list var) = lookup(fn->outputs) +15500 8b/-> *(ebp+8) 1/r32/ecx +15501 (lookup *(ecx+0x10) *(ecx+0x14)) # Function-outputs Function-outputs => eax +15502 89/<- %ecx 0/r32/eax +15503 { +15504 $find-register:loop: +15505 # if (curr == 0) break +15506 81 7/subop/compare %ecx 0/imm32 +15507 74/jump-if-= break/disp8 +15508 # eax = curr->value->register +15509 (lookup *ecx *(ecx+4)) # List-value List-value => eax +15510 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax +15511 # if (eax == reg) return curr->value +15512 $find-register:compare: +15513 (string-equal? *(ebp+0xc) %eax) # => eax +15514 { +15515 3d/compare-eax-and 0/imm32/false +15516 74/jump-if-= break/disp8 +15517 $find-register:found: +15518 (lookup *ecx *(ecx+4)) # List-value List-value => eax +15519 eb/jump $find-register:end/disp8 +15520 } +15521 # curr = lookup(curr->next) +15522 (lookup *(ecx+8) *(ecx+0xc)) # List-next List-next => eax +15523 89/<- %ecx 0/r32/eax +15524 # +15525 eb/jump loop/disp8 +15526 } +15527 $find-register:end: +15528 # . restore registers +15529 59/pop-to-ecx +15530 # . epilogue +15531 89/<- %esp 5/r32/ebp +15532 5d/pop-to-ebp +15533 c3/return +15534 +15535 assigns-in-stmts?: # stmts: (addr list stmt), v: (addr var) -> result/eax: boolean +15536 # . prologue +15537 55/push-ebp +15538 89/<- %ebp 4/r32/esp +15539 # . save registers +15540 51/push-ecx +15541 # var curr/ecx: (addr list stmt) = stmts +15542 8b/-> *(ebp+8) 1/r32/ecx +15543 { +15544 # if (curr == 0) break +15545 81 7/subop/compare %ecx 0/imm32 +15546 74/jump-if-= break/disp8 +15547 # if assigns-in-stmt?(curr->value, v) return true +15548 (lookup *ecx *(ecx+4)) # List-value List-value => eax +15549 (assigns-in-stmt? %eax *(ebp+0xc)) # => eax +15550 3d/compare-eax-and 0/imm32/false +15551 75/jump-if-!= break/disp8 +15552 # curr = lookup(curr->next) +15553 (lookup *(ecx+8) *(ecx+0xc)) # List-next List-next => eax +15554 89/<- %ecx 0/r32/eax +15555 # +15556 eb/jump loop/disp8 +15557 } +15558 $assigns-in-stmts?:end: +15559 # . restore registers +15560 59/pop-to-ecx +15561 # . epilogue +15562 89/<- %esp 5/r32/ebp +15563 5d/pop-to-ebp +15564 c3/return +15565 +15566 assigns-in-stmt?: # stmt: (addr stmt), v: (addr var) -> result/eax: boolean +15567 # . prologue +15568 55/push-ebp +15569 89/<- %ebp 4/r32/esp +15570 # . save registers +15571 51/push-ecx +15572 # ecx = stmt +15573 8b/-> *(ebp+8) 1/r32/ecx +15574 # if stmt is a stmt1, return assigns-in-stmt-vars?(stmt->outputs, v) +15575 { +15576 81 7/subop/compare *ecx 1/imm32/stmt1 # Stmt-tag +15577 75/jump-if-!= break/disp8 +15578 (lookup *(ecx+0x14) *(ecx+0x18)) # Stmt1-outputs Stmt1-outputs => eax +15579 (assigns-in-stmt-vars? %eax *(ebp+0xc)) # => eax +15580 eb/jump $assigns-in-stmt?:end/disp8 +15581 } +15582 # if stmt is a block, return assigns-in-stmts?(stmt->stmts, v) +15583 { +15584 81 7/subop/compare *ecx 0/imm32/block # Stmt-tag +15585 75/jump-if-!= break/disp8 +15586 (lookup *(ecx+4) *(ecx+8)) # Block-stmts Block-stmts => eax +15587 (assigns-in-stmts? %eax *(ebp+0xc)) # => eax +15588 eb/jump $assigns-in-stmt?:end/disp8 +15589 } +15590 # otherwise return false +15591 b8/copy 0/imm32/false +15592 $assigns-in-stmt?:end: +15593 # . restore registers +15594 59/pop-to-ecx +15595 # . epilogue +15596 89/<- %esp 5/r32/ebp +15597 5d/pop-to-ebp +15598 c3/return +15599 +15600 assigns-in-stmt-vars?: # stmt-var: (addr stmt-var), v: (addr var) -> result/eax: boolean +15601 # . prologue +15602 55/push-ebp +15603 89/<- %ebp 4/r32/esp +15604 # . save registers +15605 51/push-ecx +15606 # var curr/ecx: (addr stmt-var) = stmt-var +15607 8b/-> *(ebp+8) 1/r32/ecx +15608 { +15609 # if (curr == 0) break +15610 81 7/subop/compare %ecx 0/imm32 +15611 74/jump-if-= break/disp8 +15612 # eax = lookup(curr->value) +15613 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax +15614 # if (eax == v && curr->is-deref? == false) return true +15615 { +15616 39/compare *(ebp+0xc) 0/r32/eax +15617 75/jump-if-!= break/disp8 +15618 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref +15619 75/jump-if-!= break/disp8 +15620 b8/copy-to-eax 1/imm32/true +15621 eb/jump $assigns-in-stmt-vars?:end/disp8 +15622 } +15623 # curr = lookup(curr->next) +15624 (lookup *(ecx+8) *(ecx+0xc)) # Stmt-var-next Stmt-var-next => eax +15625 89/<- %ecx 0/r32/eax +15626 # +15627 eb/jump loop/disp8 +15628 } +15629 $assigns-in-stmt-vars?:end: +15630 # . restore registers +15631 59/pop-to-ecx +15632 # . epilogue +15633 89/<- %esp 5/r32/ebp +15634 5d/pop-to-ebp +15635 c3/return +15636 +15637 # is there a var before 'v' with the same block-depth and register on the 'vars' stack? +15638 # v is guaranteed to be within vars +15639 # 'start' is provided as an optimization, a pointer within vars +15640 # *start == v +15641 same-register-spilled-before?: # v: (addr var), vars: (addr stack (handle var)), start: (addr var) -> result/eax: boolean +15642 # . prologue +15643 55/push-ebp +15644 89/<- %ebp 4/r32/esp +15645 # . save registers +15646 51/push-ecx +15647 52/push-edx +15648 53/push-ebx +15649 56/push-esi +15650 57/push-edi +15651 # ecx = v +15652 8b/-> *(ebp+8) 1/r32/ecx +15653 # var reg/edx: (addr array byte) = lookup(v->register) +15654 (lookup *(ecx+0x18) *(ecx+0x1c)) # Var-register Var-register => eax +15655 89/<- %edx 0/r32/eax +15656 # var depth/ebx: int = v->block-depth +15657 8b/-> *(ecx+0x10) 3/r32/ebx # Var-block-depth +15658 # var min/ecx: (addr handle var) = vars->data +15659 8b/-> *(ebp+0xc) 1/r32/ecx +15660 81 0/subop/add %ecx 8/imm32 +15661 # TODO: check that start >= min and start < &vars->data[top] +15662 # TODO: check that *start == v +15663 # var curr/esi: (addr handle var) = start +15664 8b/-> *(ebp+0x10) 6/r32/esi +15665 # curr -= 8 +15666 81 5/subop/subtract %esi 8/imm32 +15667 { +15668 $same-register-spilled-before?:loop: +15669 # if (curr < min) break +15670 39/compare %esi 1/r32/ecx +15671 0f 82/jump-if-addr< break/disp32 +15672 # var x/eax: (addr var) = lookup(*curr) +15673 (lookup *esi *(esi+4)) # => eax +15674 # if (x->block-depth < depth) break +15675 39/compare *(eax+0x10) 3/r32/ebx # Var-block-depth +15676 0f 8c/jump-if-< break/disp32 +15677 # if (x->register == 0) continue +15678 81 7/subop/compare *(eax+0x18) 0/imm32 # Var-register +15679 74/jump-if-= $same-register-spilled-before?:continue/disp8 +15680 # if (x->register == reg) return true +15681 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax +15682 (string-equal? %eax %edx) # => eax +15683 3d/compare-eax-and 0/imm32/false +15684 b8/copy-to-eax 1/imm32/true +15685 75/jump-if-!= $same-register-spilled-before?:end/disp8 +15686 $same-register-spilled-before?:continue: +15687 # curr -= 8 +15688 81 5/subop/subtract %esi 8/imm32 +15689 e9/jump loop/disp32 +15690 } +15691 $same-register-spilled-before?:false: +15692 b8/copy-to-eax 0/imm32/false +15693 $same-register-spilled-before?:end: +15694 # . restore registers +15695 5f/pop-to-edi +15696 5e/pop-to-esi +15697 5b/pop-to-ebx +15698 5a/pop-to-edx +15699 59/pop-to-ecx +15700 # . epilogue +15701 89/<- %esp 5/r32/ebp +15702 5d/pop-to-ebp +15703 c3/return +15704 +15705 # Clean up global state for 'vars' until some block depth (inclusive). +15706 # +15707 # This would be a simple series of pops, if it wasn't for fn outputs, which +15708 # can occur anywhere in the stack. +15709 # So we have to _compact_ the entire array underlying the stack. +15710 # +15711 # We want to allow a fn output register to be written to by locals before the +15712 # output is set. +15713 # So fn outputs can't just be pushed at the start of the function. +15714 # +15715 # We want to allow other locals to shadow a fn output register after the +15716 # output is set. +15717 # So the output can't just always override anything in the stack. Sequence matters. +15718 clean-up-blocks: # vars: (addr stack live-var), until-block-depth: int, fn: (addr function) +15719 # pseudocode: +15720 # to = vars->top (which points outside the stack) +15721 # while true +15722 # if to <= 0 +15723 # break +15724 # var v = vars->data[to-1] +15725 # if v.depth < until and !in-function-outputs?(fn, v) +15726 # break +15727 # --to +15728 # from = to +15729 # while true +15730 # if from >= vars->top +15731 # break +15732 # assert(from >= to) +15733 # v = vars->data[from] +15734 # if in-function-outputs?(fn, v) +15735 # if from > to +15736 # vars->data[to] = vars->data[from] +15737 # ++to +15738 # ++from +15739 # vars->top = to +15740 # +15741 # . prologue +15742 55/push-ebp +15743 89/<- %ebp 4/r32/esp +15744 # . save registers +15745 50/push-eax +15746 52/push-edx +15747 53/push-ebx +15748 56/push-esi +15749 57/push-edi +15750 # ebx = vars +15751 8b/-> *(ebp+8) 3/r32/ebx +15752 # edx = until-block-depth +15753 8b/-> *(ebp+0xc) 2/r32/edx +15754 $clean-up-blocks:phase1: +15755 # var to/edi: int = vars->top +15756 8b/-> *ebx 7/r32/edi +15757 { +15758 $clean-up-blocks:loop1: +15759 # if (to <= 0) break +15760 81 7/subop/compare %edi 0/imm32 +15761 7e/jump-if-<= break/disp8 +15762 # var v/eax: (addr var) = lookup(vars->data[to-1]->var) +15763 8d/copy-address *(ebx+edi-4) 0/r32/eax # vars + 8 + to - 12 +15764 (lookup *eax *(eax+4)) # => eax +15765 # if (v->block-depth >= until-block-depth) continue +15766 39/compare *(eax+0x10) 2/r32/edx # Var-block-depth +15767 { +15768 7d/jump-if->= break/disp8 +15769 # if (!in-function-outputs?(fn, v)) break +15770 (in-function-outputs? *(ebp+0x10) %eax) # => eax +15771 3d/compare-eax-and 0/imm32/false +15772 74/jump-if-= $clean-up-blocks:phase2/disp8 +15773 } +15774 $clean-up-blocks:loop1-continue: +15775 # --to +15776 81 5/subop/subtract %edi 0xc/imm32 +15777 # +15778 eb/jump loop/disp8 +15779 } +15780 $clean-up-blocks:phase2: +15781 # var from/esi: int = to +15782 89/<- %esi 7/r32/edi +15783 { +15784 $clean-up-blocks:loop2: +15785 # if (from >= vars->top) break +15786 3b/compare 6/r32/esi *ebx +15787 7d/jump-if->= break/disp8 +15788 # var v/eax: (addr var) = lookup(vars->data[from]->var) +15789 8d/copy-address *(ebx+esi+8) 0/r32/eax +15790 (lookup *eax *(eax+4)) # => eax +15791 # if !in-function-outputs?(fn, v) continue +15792 (in-function-outputs? *(ebp+0x10) %eax) # => eax +15793 3d/compare-eax-and 0/imm32/false +15794 74/jump-if-= $clean-up-blocks:loop2-continue/disp8 +15795 # invariant: from >= to +15796 # if (from > to) vars->data[to] = vars->data[from] +15797 { +15798 39/compare %esi 7/r32/edi +15799 7e/jump-if-<= break/disp8 +15800 56/push-esi +15801 57/push-edi +15802 # . var from/esi: (addr byte) = &vars->data[from] +15803 8d/copy-address *(ebx+esi+8) 6/r32/esi +15804 # . var to/edi: (addr byte) = &vars->data[to] +15805 8d/copy-address *(ebx+edi+8) 7/r32/edi +15806 # . +15807 8b/-> *esi 0/r32/eax +15808 89/<- *edi 0/r32/eax +15809 8b/-> *(esi+4) 0/r32/eax +15810 89/<- *(edi+4) 0/r32/eax +15811 8b/-> *(esi+8) 0/r32/eax +15812 89/<- *(edi+8) 0/r32/eax +15813 5f/pop-to-edi +15814 5e/pop-to-esi +15815 } +15816 # ++to +15817 81 0/subop/add %edi 0xc/imm32 +15818 $clean-up-blocks:loop2-continue: +15819 # ++from +15820 81 0/subop/add %esi 0xc/imm32 +15821 # +15822 eb/jump loop/disp8 +15823 } +15824 89/<- *ebx 7/r32/edi +15825 $clean-up-blocks:end: +15826 # . restore registers +15827 5f/pop-to-edi +15828 5e/pop-to-esi +15829 5b/pop-to-ebx +15830 5a/pop-to-edx +15831 58/pop-to-eax +15832 # . epilogue +15833 89/<- %esp 5/r32/ebp +15834 5d/pop-to-ebp +15835 c3/return +15836 +15837 in-function-outputs?: # fn: (addr function), target: (addr var) -> result/eax: boolean +15838 # . prologue +15839 55/push-ebp +15840 89/<- %ebp 4/r32/esp +15841 # . save registers +15842 51/push-ecx +15843 # var curr/ecx: (addr list var) = lookup(fn->outputs) +15844 8b/-> *(ebp+8) 1/r32/ecx +15845 (lookup *(ecx+0x10) *(ecx+0x14)) # Function-outputs Function-outputs => eax +15846 89/<- %ecx 0/r32/eax +15847 # while curr != null +15848 { +15849 81 7/subop/compare %ecx 0/imm32 +15850 74/jump-if-= break/disp8 +15851 # var v/eax: (addr var) = lookup(curr->value) +15852 (lookup *ecx *(ecx+4)) # List-value List-value => eax +15853 # if (v == target) return true +15854 39/compare *(ebp+0xc) 0/r32/eax +15855 b8/copy-to-eax 1/imm32/true +15856 74/jump-if-= $in-function-outputs?:end/disp8 +15857 # curr = curr->next +15858 (lookup *(ecx+8) *(ecx+0xc)) # List-next List-next => eax +15859 89/<- %ecx 0/r32/eax +15860 # +15861 eb/jump loop/disp8 +15862 } +15863 b8/copy-to-eax 0/imm32 +15864 $in-function-outputs?:end: +15865 # . restore registers +15866 59/pop-to-ecx +15867 # . epilogue +15868 89/<- %esp 5/r32/ebp +15869 5d/pop-to-ebp +15870 c3/return +15871 +15872 emit-subx-var-def: # out: (addr buffered-file), stmt: (addr stmt) +15873 # . prologue +15874 55/push-ebp +15875 89/<- %ebp 4/r32/esp +15876 # . save registers +15877 50/push-eax +15878 51/push-ecx +15879 52/push-edx +15880 # eax = stmt +15881 8b/-> *(ebp+0xc) 0/r32/eax +15882 # var v/ecx: (addr var) +15883 (lookup *(eax+4) *(eax+8)) # Vardef-var Vardef-var => eax +15884 89/<- %ecx 0/r32/eax +15885 # v->block-depth = *Curr-block-depth +15886 8b/-> *Curr-block-depth 0/r32/eax +15887 89/<- *(ecx+0x10) 0/r32/eax # Var-block-depth +15888 # var n/edx: int = size-of(stmt->var) +15889 (size-of %ecx) # => eax +15890 89/<- %edx 0/r32/eax +15891 # *Curr-local-stack-offset -= n +15892 29/subtract-from *Curr-local-stack-offset 2/r32/edx +15893 # v->offset = *Curr-local-stack-offset +15894 8b/-> *Curr-local-stack-offset 0/r32/eax +15895 89/<- *(ecx+0x14) 0/r32/eax # Var-offset +15896 # if v is an array, do something special to initialize it +15897 { +15898 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax +15899 (is-mu-array? %eax) # => eax +15900 3d/compare-eax-and 0/imm32/false +15901 0f 84/jump-if-= break/disp32 +15902 # var array-size-without-size/edx: int = n-4 +15903 81 5/subop/subtract %edx 4/imm32 +15904 # +15905 (emit-array-data-initialization *(ebp+8) %edx) +15906 e9/jump $emit-subx-var-def:end/disp32 +15907 } +15908 # another special-case for initializing streams +15909 # a stream is an array with 2 extra pointers +15910 { +15911 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax +15912 (is-mu-stream? %eax) # => eax +15913 3d/compare-eax-and 0/imm32/false +15914 0f 84/jump-if-= break/disp32 +15915 # var array-size-without-size/edx: int = n-12 +15916 81 5/subop/subtract %edx 0xc/imm32 +15917 (emit-array-data-initialization *(ebp+8) %edx) +15918 # emit read and write pointers +15919 (emit-indent *(ebp+8) *Curr-block-depth) +15920 (write-buffered *(ebp+8) "68/push 0/imm32\n") +15921 (emit-indent *(ebp+8) *Curr-block-depth) +15922 (write-buffered *(ebp+8) "68/push 0/imm32\n") +15923 # +15924 eb/jump $emit-subx-var-def:end/disp8 +15925 } +15926 # while n > 0 +15927 { +15928 81 7/subop/compare %edx 0/imm32 +15929 7e/jump-if-<= break/disp8 +15930 (emit-indent *(ebp+8) *Curr-block-depth) +15931 (write-buffered *(ebp+8) "68/push 0/imm32\n") +15932 # n -= 4 +15933 81 5/subop/subtract %edx 4/imm32 +15934 # +15935 eb/jump loop/disp8 +15936 } +15937 $emit-subx-var-def:end: +15938 # . restore registers +15939 5a/pop-to-edx +15940 59/pop-to-ecx +15941 58/pop-to-eax +15942 # . epilogue +15943 89/<- %esp 5/r32/ebp +15944 5d/pop-to-ebp +15945 c3/return +15946 +15947 emit-array-data-initialization: # out: (addr buffered-file), n: int +15948 # . prologue +15949 55/push-ebp +15950 89/<- %ebp 4/r32/esp +15951 # +15952 (emit-indent *(ebp+8) *Curr-block-depth) +15953 (write-buffered *(ebp+8) "(push-n-zero-bytes ") +15954 (write-int32-hex-buffered *(ebp+8) *(ebp+0xc)) +15955 (write-buffered *(ebp+8) ")\n") +15956 (emit-indent *(ebp+8) *Curr-block-depth) +15957 (write-buffered *(ebp+8) "68/push ") +15958 (write-int32-hex-buffered *(ebp+8) *(ebp+0xc)) +15959 (write-buffered *(ebp+8) "/imm32\n") +15960 $emit-array-data-initialization:end: +15961 # . epilogue +15962 89/<- %esp 5/r32/ebp +15963 5d/pop-to-ebp +15964 c3/return +15965 +15966 emit-subx-stmt: # out: (addr buffered-file), stmt: (addr stmt), primitives: (addr primitive), err: (addr buffered-file), ed: (addr exit-descriptor) +15967 # . prologue +15968 55/push-ebp +15969 89/<- %ebp 4/r32/esp +15970 # . save registers +15971 50/push-eax +15972 51/push-ecx +15973 # - some special-case primitives that don't actually use the 'primitives' data structure +15974 # var op/ecx: (addr array byte) = lookup(stmt->operation) +15975 8b/-> *(ebp+0xc) 1/r32/ecx +15976 (lookup *(ecx+4) *(ecx+8)) # Stmt1-operation Stmt1-operation => eax +15977 89/<- %ecx 0/r32/eax +15978 # array size +15979 { +15980 # if (!string-equal?(stmt->operation, "length")) break +15981 (string-equal? %ecx "length") # => eax +15982 3d/compare-eax-and 0/imm32 +15983 0f 84/jump-if-= break/disp32 +15984 (translate-mu-length-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18)) +15985 e9/jump $emit-subx-stmt:end/disp32 +15986 } +15987 # index into array +15988 { +15989 # if (!string-equal?(stmt->operation, "index")) break +15990 (string-equal? %ecx "index") # => eax +15991 3d/compare-eax-and 0/imm32 +15992 0f 84/jump-if-= break/disp32 +15993 (translate-mu-index-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18)) +15994 e9/jump $emit-subx-stmt:end/disp32 +15995 } +15996 # compute-offset for index into array +15997 { +15998 # if (!string-equal?(stmt->operation, "compute-offset")) break +15999 (string-equal? %ecx "compute-offset") # => eax +16000 3d/compare-eax-and 0/imm32 +16001 0f 84/jump-if-= break/disp32 +16002 (translate-mu-compute-index-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18)) +16003 e9/jump $emit-subx-stmt:end/disp32 +16004 } +16005 # get field from record +16006 { +16007 # if (!string-equal?(stmt->operation, "get")) break +16008 (string-equal? %ecx "get") # => eax +16009 3d/compare-eax-and 0/imm32 +16010 0f 84/jump-if-= break/disp32 +16011 (translate-mu-get-stmt *(ebp+8) *(ebp+0xc)) +16012 e9/jump $emit-subx-stmt:end/disp32 +16013 } +16014 # allocate scalar +16015 { +16016 # if (!string-equal?(stmt->operation, "allocate")) break +16017 (string-equal? %ecx "allocate") # => eax +16018 3d/compare-eax-and 0/imm32 +16019 0f 84/jump-if-= break/disp32 +16020 (translate-mu-allocate-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18)) +16021 e9/jump $emit-subx-stmt:end/disp32 +16022 } +16023 # allocate array +16024 { +16025 # if (!string-equal?(stmt->operation, "populate")) break +16026 (string-equal? %ecx "populate") # => eax +16027 3d/compare-eax-and 0/imm32 +16028 0f 84/jump-if-= break/disp32 +16029 (translate-mu-populate-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18)) +16030 e9/jump $emit-subx-stmt:end/disp32 +16031 } +16032 # allocate stream +16033 { +16034 # if (!string-equal?(stmt->operation, "populate-stream")) break +16035 (string-equal? %ecx "populate-stream") # => eax +16036 3d/compare-eax-and 0/imm32 +16037 0f 84/jump-if-= break/disp32 +16038 (translate-mu-populate-stream-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18)) +16039 e9/jump $emit-subx-stmt:end/disp32 +16040 } +16041 # read from stream +16042 { +16043 # if (!string-equal?(stmt->operation, "read-from-stream")) break +16044 (string-equal? %ecx "read-from-stream") # => eax +16045 3d/compare-eax-and 0/imm32 +16046 0f 84/jump-if-= break/disp32 +16047 (translate-mu-read-from-stream-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18)) +16048 e9/jump $emit-subx-stmt:end/disp32 +16049 } +16050 # write to stream +16051 { +16052 # if (!string-equal?(stmt->operation, "write-to-stream")) break +16053 (string-equal? %ecx "write-to-stream") # => eax +16054 3d/compare-eax-and 0/imm32 +16055 0f 84/jump-if-= break/disp32 +16056 (translate-mu-write-to-stream-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18)) +16057 e9/jump $emit-subx-stmt:end/disp32 +16058 } +16059 # - if stmt matches a primitive, emit it +16060 { +16061 $emit-subx-stmt:check-for-primitive: +16062 # var curr/eax: (addr primitive) +16063 (find-matching-primitive *(ebp+0x10) *(ebp+0xc)) # primitives, stmt => eax +16064 3d/compare-eax-and 0/imm32 +16065 74/jump-if-= break/disp8 +16066 $emit-subx-stmt:primitive: +16067 (emit-subx-primitive *(ebp+8) *(ebp+0xc) %eax) # out, stmt, curr +16068 e9/jump $emit-subx-stmt:end/disp32 +16069 } +16070 # - otherwise emit a call +16071 # TODO: type-checking +16072 $emit-subx-stmt:call: +16073 (emit-call *(ebp+8) *(ebp+0xc)) +16074 $emit-subx-stmt:end: +16075 # . restore registers +16076 59/pop-to-ecx +16077 58/pop-to-eax +16078 # . epilogue +16079 89/<- %esp 5/r32/ebp +16080 5d/pop-to-ebp +16081 c3/return +16082 +16083 translate-mu-length-stmt: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) +16084 # . prologue +16085 55/push-ebp +16086 89/<- %ebp 4/r32/esp +16087 # . save registers +16088 50/push-eax +16089 51/push-ecx +16090 52/push-edx +16091 53/push-ebx +16092 56/push-esi +16093 # esi = stmt +16094 8b/-> *(ebp+0xc) 6/r32/esi +16095 # var base/ebx: (addr var) = stmt->inouts[0]->value +16096 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax +16097 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +16098 89/<- %ebx 0/r32/eax +16099 # var elemsize/ecx: int = array-element-size(base) +16100 (array-element-size %ebx *(ebp+0x10) *(ebp+0x14)) # => eax +16101 89/<- %ecx 0/r32/eax +16102 # var outreg/edx: (addr array byte) = stmt->outputs[0]->value->register +16103 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax +16104 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +16105 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax +16106 89/<- %edx 0/r32/eax +16107 # if elemsize == 1 +16108 { +16109 81 7/subop/compare %ecx 1/imm32 +16110 75/jump-if-!= break/disp8 +16111 $translate-mu-length-stmt:size-1: +16112 (emit-save-size-to *(ebp+8) %ebx %edx) +16113 e9/jump $translate-mu-length-stmt:end/disp32 +16114 } +16115 # if elemsize is a power of 2 less than 256 +16116 { +16117 (power-of-2? %ecx *(ebp+0x10) *(ebp+0x14)) # => eax +16118 3d/compare-eax-and 0/imm32/false +16119 74/jump-if-= break/disp8 +16120 81 7/subop/compare %ecx 0xff/imm32 +16121 7f/jump-if-> break/disp8 +16122 $translate-mu-length-stmt:size-power-of-2: +16123 (emit-save-size-to *(ebp+8) %ebx %edx) +16124 (emit-divide-by-shift-right *(ebp+8) %edx %ecx) +16125 e9/jump $translate-mu-length-stmt:end/disp32 +16126 } +16127 # otherwise, the complex case +16128 # . emit register spills +16129 { +16130 $translate-mu-length-stmt:complex: +16131 (string-equal? %edx "eax") # => eax +16132 3d/compare-eax-and 0/imm32/false +16133 75/break-if-!= break/disp8 +16134 (emit-indent *(ebp+8) *Curr-block-depth) +16135 (write-buffered *(ebp+8) "50/push-eax\n") +16136 } +16137 { +16138 (string-equal? %edx "ecx") # => eax +16139 3d/compare-eax-and 0/imm32/false +16140 75/break-if-!= break/disp8 +16141 (emit-indent *(ebp+8) *Curr-block-depth) +16142 (write-buffered *(ebp+8) "51/push-ecx\n") +16143 } +16144 { +16145 (string-equal? %edx "edx") # => eax +16146 3d/compare-eax-and 0/imm32/false +16147 75/break-if-!= break/disp8 +16148 (emit-indent *(ebp+8) *Curr-block-depth) +16149 (write-buffered *(ebp+8) "52/push-edx\n") +16150 } +16151 # . +16152 (emit-save-size-to *(ebp+8) %ebx "eax") +16153 (emit-indent *(ebp+8) *Curr-block-depth) +16154 (write-buffered *(ebp+8) "31/xor %edx 2/r32/edx\n") +16155 (emit-indent *(ebp+8) *Curr-block-depth) +16156 (write-buffered *(ebp+8) "b9/copy-to-ecx ") +16157 (write-int32-hex-buffered *(ebp+8) %ecx) +16158 (write-buffered *(ebp+8) "/imm32\n") +16159 (emit-indent *(ebp+8) *Curr-block-depth) +16160 (write-buffered *(ebp+8) "f7 7/subop/idiv-eax-edx-by %ecx\n") +16161 { +16162 (string-equal? %edx "eax") # => eax +16163 3d/compare-eax-and 0/imm32/false +16164 75/break-if-!= break/disp8 +16165 (emit-indent *(ebp+8) *Curr-block-depth) +16166 (write-buffered *(ebp+8) "89/<- %") +16167 (write-buffered *(ebp+8) %edx) +16168 (write-buffered *(ebp+8) " 0/r32/eax\n") +16169 } +16170 # . emit register restores +16171 { +16172 (string-equal? %edx "edx") # => eax +16173 3d/compare-eax-and 0/imm32/false +16174 75/break-if-!= break/disp8 +16175 (emit-indent *(ebp+8) *Curr-block-depth) +16176 (write-buffered *(ebp+8) "5a/pop-to-edx\n") +16177 } +16178 { +16179 (string-equal? %edx "ecx") # => eax +16180 3d/compare-eax-and 0/imm32/false +16181 75/break-if-!= break/disp8 +16182 (emit-indent *(ebp+8) *Curr-block-depth) +16183 (write-buffered *(ebp+8) "59/pop-to-ecx\n") +16184 } +16185 { +16186 (string-equal? %edx "eax") # => eax +16187 3d/compare-eax-and 0/imm32/false +16188 75/break-if-!= break/disp8 +16189 (emit-indent *(ebp+8) *Curr-block-depth) +16190 (write-buffered *(ebp+8) "58/pop-to-eax\n") +16191 } +16192 $translate-mu-length-stmt:end: +16193 # . restore registers +16194 5e/pop-to-esi +16195 5b/pop-to-ebx +16196 5a/pop-to-edx +16197 59/pop-to-ecx +16198 58/pop-to-eax +16199 # . epilogue +16200 89/<- %esp 5/r32/ebp +16201 5d/pop-to-ebp +16202 c3/return +16203 +16204 array-element-size: # arr: (addr var), err: (addr buffered-file), ed: (addr exit-descriptor) -> result/eax: int +16205 # . prologue +16206 55/push-ebp +16207 89/<- %ebp 4/r32/esp +16208 # +16209 (array-element-type-id *(ebp+8) *(ebp+0xc) *(ebp+0x10)) # => eax +16210 (size-of-type-id-as-array-element %eax) # => eax +16211 $array-element-size:end: +16212 # . epilogue +16213 89/<- %esp 5/r32/ebp +16214 5d/pop-to-ebp +16215 c3/return +16216 +16217 array-element-type-id: # v: (addr var), err: (addr buffered-file), ed: (addr exit-descriptor) -> result/eax: type-id +16218 # precondition: n is positive +16219 # . prologue +16220 55/push-ebp +16221 89/<- %ebp 4/r32/esp +16222 # +16223 8b/-> *(ebp+8) 0/r32/eax +16224 # var t/eax: (addr type-tree) +16225 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +16226 # if t == 0 abort +16227 3d/compare-eax-with 0/imm32 +16228 0f 84/jump-if-== $array-element-type-id:error0/disp32 +16229 # if t->is-atom? abort +16230 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom +16231 0f 85/jump-if-!= $array-element-type-id:error1/disp32 +16232 # if (t->left == addr) t = t->right +16233 { +16234 50/push-eax +16235 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +16236 (is-simple-mu-type? %eax 2) # addr => eax +16237 3d/compare-eax-with 0/imm32/false +16238 58/pop-to-eax +16239 74/jump-if-= break/disp8 +16240 $array-element-type-id:skip-addr: +16241 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax +16242 } +16243 # if t == 0 abort +16244 3d/compare-eax-with 0/imm32 +16245 0f 84/jump-if-= $array-element-type-id:error2/disp32 +16246 # if t->is-atom? abort +16247 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom +16248 0f 85/jump-if-!= $array-element-type-id:error2/disp32 +16249 # if t->left != array abort +16250 { +16251 50/push-eax +16252 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +16253 (is-simple-mu-type? %eax 3) # array => eax +16254 3d/compare-eax-with 0/imm32/false +16255 58/pop-to-eax +16256 $array-element-type-id:no-array: +16257 0f 84/jump-if-= $array-element-type-id:error2/disp32 +16258 } +16259 $array-element-type-id:skip-array: +16260 # t = t->right +16261 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax +16262 # if t == 0 abort +16263 3d/compare-eax-with 0/imm32 +16264 0f 84/jump-if-= $array-element-type-id:error2/disp32 +16265 # if t->is-atom? abort +16266 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom +16267 0f 85/jump-if-!= $array-element-type-id:error2/disp32 +16268 # return t->left->value +16269 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +16270 8b/-> *(eax+4) 0/r32/eax # Type-tree-value +16271 $array-element-type-id:end: +16272 # . epilogue +16273 89/<- %esp 5/r32/ebp +16274 5d/pop-to-ebp +16275 c3/return +16276 +16277 $array-element-type-id:error0: +16278 (write-buffered *(ebp+0xc) "array-element-type-id: var '") +16279 50/push-eax +16280 8b/-> *(ebp+8) 0/r32/eax +16281 (lookup *eax *(eax+4)) # Var-name Var-name => eax +16282 (write-buffered *(ebp+0xc) %eax) +16283 58/pop-to-eax +16284 (write-buffered *(ebp+0xc) "' has no type\n") +16285 (flush *(ebp+0xc)) +16286 (stop *(ebp+0x10) 1) +16287 # never gets here +16288 +16289 $array-element-type-id:error1: +16290 (write-buffered *(ebp+0xc) "array-element-type-id: var '") +16291 50/push-eax +16292 8b/-> *(ebp+8) 0/r32/eax +16293 (lookup *eax *(eax+4)) # Var-name Var-name => eax +16294 (write-buffered *(ebp+0xc) %eax) +16295 58/pop-to-eax +16296 (write-buffered *(ebp+0xc) "' has atomic type ") +16297 (write-int32-hex-buffered *(ebp+0xc) *(eax+4)) # Type-tree-value +16298 (write-buffered *(ebp+0xc) Newline) +16299 (flush *(ebp+0xc)) +16300 (stop *(ebp+0x10) 1) +16301 # never gets here +16302 +16303 $array-element-type-id:error2: +16304 (write-buffered *(ebp+0xc) "array-element-type-id: var '") +16305 50/push-eax +16306 8b/-> *(ebp+8) 0/r32/eax +16307 (lookup *eax *(eax+4)) # Var-name Var-name => eax +16308 (write-buffered *(ebp+0xc) %eax) +16309 58/pop-to-eax +16310 (write-buffered *(ebp+0xc) "' has non-array type\n") +16311 (flush *(ebp+0xc)) +16312 (stop *(ebp+0x10) 1) +16313 # never gets here +16314 +16315 size-of-type-id-as-array-element: # t: type-id -> result/eax: int +16316 # . prologue +16317 55/push-ebp +16318 89/<- %ebp 4/r32/esp +16319 # eax = t +16320 8b/-> *(ebp+8) 0/r32/eax +16321 # if t is 'byte', size is 1 +16322 3d/compare-eax-and 8/imm32/byte +16323 { +16324 75/jump-if-!= break/disp8 +16325 b8/copy-to-eax 1/imm32 +16326 eb/jump $size-of-type-id-as-array-element:end/disp8 +16327 } +16328 # otherwise proceed as usual +16329 (size-of-type-id %eax) # => eax +16330 $size-of-type-id-as-array-element:end: +16331 # . epilogue +16332 89/<- %esp 5/r32/ebp +16333 5d/pop-to-ebp +16334 c3/return +16335 +16336 emit-save-size-to: # out: (addr buffered-file), base: (addr var), outreg: (addr array byte) +16337 # . prologue +16338 55/push-ebp +16339 89/<- %ebp 4/r32/esp +16340 # . save registers +16341 50/push-eax +16342 53/push-ebx +16343 # ebx = base +16344 8b/-> *(ebp+0xc) 3/r32/ebx +16345 (emit-indent *(ebp+8) *Curr-block-depth) +16346 (write-buffered *(ebp+8) "8b/-> *") +16347 # if base is an (addr array ...) in a register +16348 { +16349 81 7/subop/compare *(ebx+0x18)) 0/imm32 # Var-register +16350 74/jump-if-= break/disp8 +16351 $emit-save-size-to:emit-base-from-register: +16352 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register Var-register => eax +16353 (write-buffered *(ebp+8) %eax) +16354 eb/jump $emit-save-size-to:emit-output/disp8 +16355 } +16356 # otherwise if base is an (array ...) on the stack +16357 { +16358 81 7/subop/compare *(ebx+0x14)) 0/imm32 # Var-offset +16359 74/jump-if-= break/disp8 +16360 $emit-save-size-to:emit-base-from-stack: +16361 (write-buffered *(ebp+8) "(ebp+") +16362 (write-int32-hex-buffered *(ebp+8) *(ebx+0x14)) # Var-offset +16363 (write-buffered *(ebp+8) ")") +16364 } +16365 $emit-save-size-to:emit-output: +16366 (write-buffered *(ebp+8) " ") +16367 (get Mu-registers *(ebp+0x10) 0xc "Mu-registers") # => eax +16368 (write-int32-hex-buffered *(ebp+8) *eax) +16369 (write-buffered *(ebp+8) "/r32\n") +16370 $emit-save-size-to:end: +16371 # . restore registers +16372 5b/pop-to-ebx +16373 58/pop-to-eax +16374 # . epilogue +16375 89/<- %esp 5/r32/ebp +16376 5d/pop-to-ebp +16377 c3/return +16378 +16379 emit-divide-by-shift-right: # out: (addr buffered-file), reg: (addr array byte), size: int +16380 # . prologue +16381 55/push-ebp +16382 89/<- %ebp 4/r32/esp +16383 # . save registers +16384 50/push-eax +16385 # +16386 (emit-indent *(ebp+8) *Curr-block-depth) +16387 (write-buffered *(ebp+8) "c1/shift 5/subop/>> %") +16388 (write-buffered *(ebp+8) *(ebp+0xc)) +16389 (write-buffered *(ebp+8) Space) +16390 (num-shift-rights *(ebp+0x10)) # => eax +16391 (write-int32-hex-buffered *(ebp+8) %eax) +16392 (write-buffered *(ebp+8) "/imm8\n") +16393 $emit-divide-by-shift-right:end: +16394 # . restore registers +16395 58/pop-to-eax +16396 # . epilogue +16397 89/<- %esp 5/r32/ebp +16398 5d/pop-to-ebp +16399 c3/return +16400 +16401 translate-mu-index-stmt: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) +16402 # . prologue +16403 55/push-ebp +16404 89/<- %ebp 4/r32/esp +16405 # . save registers +16406 51/push-ecx +16407 # ecx = stmt +16408 8b/-> *(ebp+0xc) 1/r32/ecx +16409 # var base/ecx: (addr var) = stmt->inouts[0] +16410 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax +16411 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +16412 89/<- %ecx 0/r32/eax +16413 # if (var->register) do one thing +16414 { +16415 81 7/subop/compare *(ecx+0x18) 0/imm32 # Var-register +16416 74/jump-if-= break/disp8 +16417 # TODO: ensure there's no dereference +16418 (translate-mu-index-stmt-with-array-in-register *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +16419 eb/jump $translate-mu-index-stmt:end/disp8 +16420 } +16421 # if (var->offset) do a different thing +16422 { +16423 81 7/subop/compare *(ecx+0x14) 0/imm32 # Var-offset +16424 74/jump-if-= break/disp8 +16425 # TODO: ensure there's no dereference +16426 (translate-mu-index-stmt-with-array-on-stack *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +16427 eb/jump $translate-mu-index-stmt:end/disp8 +16428 } +16429 $translate-mu-index-stmt:end: +16430 # . restore registers +16431 59/pop-to-ecx +16432 # . epilogue +16433 89/<- %esp 5/r32/ebp +16434 5d/pop-to-ebp +16435 c3/return +16436 +16437 $translate-mu-index-stmt-with-array:error1: +16438 (write-buffered *(ebp+0x10) "couldn't translate an index instruction. second (index) input must either lie in a register or be a literal\n") +16439 (flush *(ebp+0x10)) +16440 (stop *(ebp+0x14) 1) +16441 # never gets here +16442 +16443 $translate-mu-index-stmt-with-array:error2: +16444 (write-buffered *(ebp+0x10) "couldn't translate an index instruction. second (index) input when in a register must be an int or offset\n") +16445 (flush *(ebp+0x10)) +16446 (stop *(ebp+0x14) 1) +16447 # never gets here +16448 +16449 translate-mu-index-stmt-with-array-in-register: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) +16450 # . prologue +16451 55/push-ebp +16452 89/<- %ebp 4/r32/esp +16453 # . save registers +16454 50/push-eax +16455 51/push-ecx +16456 52/push-edx +16457 53/push-ebx +16458 # +16459 (emit-indent *(ebp+8) *Curr-block-depth) +16460 (write-buffered *(ebp+8) "8d/copy-address *(") +16461 # TODO: ensure inouts[0] is in a register and not dereferenced +16462 $translate-mu-index-stmt-with-array-in-register:emit-base: +16463 # ecx = stmt +16464 8b/-> *(ebp+0xc) 1/r32/ecx +16465 # var base/ebx: (addr var) = inouts[0] +16466 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax +16467 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +16468 89/<- %ebx 0/r32/eax +16469 # print base->register " + " +16470 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register Var-register => eax +16471 (write-buffered *(ebp+8) %eax) +16472 (write-buffered *(ebp+8) " + ") +16473 # var index/edx: (addr var) = inouts[1] +16474 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax +16475 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax +16476 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +16477 89/<- %edx 0/r32/eax +16478 # if index->register +16479 81 7/subop/compare *(edx+0x18) 0/imm32 # Var-register +16480 { +16481 0f 84/jump-if-= break/disp32 +16482 $translate-mu-index-stmt-with-array-in-register:emit-register-index: +16483 # if index is an int +16484 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax +16485 (is-simple-mu-type? %eax 1) # int => eax +16486 3d/compare-eax-and 0/imm32/false +16487 { +16488 0f 84/jump-if-= break/disp32 +16489 $translate-mu-index-stmt-with-array-in-register:emit-int-register-index: +16490 # print index->register "<<" log2(array-element-size(base)) " + 4) " +16491 # . index->register "<<" +16492 (lookup *(edx+0x18) *(edx+0x1c)) # Var-register Var-register => eax +16493 (write-buffered *(ebp+8) %eax) +16494 (write-buffered *(ebp+8) "<<") +16495 # . log2(array-element-size(base->type)) +16496 # TODO: ensure size is a power of 2 +16497 (array-element-size %ebx *(ebp+0x10) *(ebp+0x14)) # => eax +16498 (num-shift-rights %eax) # => eax +16499 (write-int32-hex-buffered *(ebp+8) %eax) +16500 e9/jump $translate-mu-index-stmt-with-array-in-register:emit-register-index-done/disp32 +16501 } +16502 # if index->type is any other atom, abort +16503 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax +16504 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom +16505 0f 85/jump-if-!= $translate-mu-index-stmt-with-array:error2/disp32 +16506 # if index has type (offset ...) +16507 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +16508 (is-simple-mu-type? %eax 7) # => eax +16509 3d/compare-eax-and 0/imm32/false +16510 { +16511 0f 84/jump-if-= break/disp32 +16512 # print index->register +16513 $translate-mu-index-stmt-with-array-in-register:emit-offset-register-index: +16514 (lookup *(edx+0x18) *(edx+0x1c)) # Var-register Var-register => eax +16515 (write-buffered *(ebp+8) %eax) +16516 } +16517 $translate-mu-index-stmt-with-array-in-register:emit-register-index-done: +16518 (write-buffered *(ebp+8) " + 4) ") +16519 e9/jump $translate-mu-index-stmt-with-array-in-register:emit-output/disp32 +16520 } +16521 # otherwise if index is a literal +16522 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax +16523 (is-simple-mu-type? %eax 0) # => eax +16524 3d/compare-eax-and 0/imm32/false +16525 { +16526 0f 84/jump-if-= break/disp32 +16527 $translate-mu-index-stmt-with-array-in-register:emit-literal-index: +16528 # var index-value/edx: int = parse-hex-int(index->name) +16529 (lookup *edx *(edx+4)) # Var-name Var-name => eax +16530 (parse-hex-int %eax) # => eax +16531 89/<- %edx 0/r32/eax +16532 # offset = idx-value * array-element-size(base->type) +16533 (array-element-size %ebx *(ebp+0x10) *(ebp+0x14)) # => eax +16534 f7 4/subop/multiply-into-eax %edx # clobbers edx +16535 # offset += 4 for array size +16536 05/add-to-eax 4/imm32 +16537 # TODO: check edx for overflow +16538 # print offset +16539 (write-int32-hex-buffered *(ebp+8) %eax) +16540 (write-buffered *(ebp+8) ") ") +16541 e9/jump $translate-mu-index-stmt-with-array-in-register:emit-output/disp32 +16542 } +16543 # otherwise abort +16544 e9/jump $translate-mu-index-stmt-with-array:error1/disp32 +16545 $translate-mu-index-stmt-with-array-in-register:emit-output: +16546 # outputs[0] "/r32" +16547 8b/-> *(ebp+0xc) 1/r32/ecx +16548 (lookup *(ecx+0x14) *(ecx+0x18)) # Stmt1-outputs Stmt1-outputs => eax +16549 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +16550 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax +16551 (get Mu-registers %eax 0xc "Mu-registers") # => eax: (addr int) +16552 (write-int32-hex-buffered *(ebp+8) *eax) +16553 (write-buffered *(ebp+8) "/r32\n") +16554 $translate-mu-index-stmt-with-array-in-register:end: +16555 # . restore registers +16556 5b/pop-to-ebx +16557 5a/pop-to-edx +16558 59/pop-to-ecx +16559 58/pop-to-eax +16560 # . epilogue +16561 89/<- %esp 5/r32/ebp +16562 5d/pop-to-ebp +16563 c3/return +16564 +16565 translate-mu-index-stmt-with-array-on-stack: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) +16566 # . prologue +16567 55/push-ebp +16568 89/<- %ebp 4/r32/esp +16569 # . save registers +16570 50/push-eax +16571 51/push-ecx +16572 52/push-edx +16573 53/push-ebx +16574 # +16575 (emit-indent *(ebp+8) *Curr-block-depth) +16576 (write-buffered *(ebp+8) "8d/copy-address *(ebp + ") +16577 # var curr/edx: (addr stmt-var) = lookup(stmt->inouts) +16578 8b/-> *(ebp+0xc) 0/r32/eax +16579 (lookup *(eax+0xc) *(eax+0x10)) # Stmt1-inouts Stmt1-inouts => eax +16580 89/<- %edx 0/r32/eax +16581 # var base/ecx: (addr var) = lookup(curr->value) +16582 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +16583 89/<- %ecx 0/r32/eax +16584 # var curr2/eax: (addr stmt-var) = lookup(curr->next) +16585 (lookup *(edx+8) *(edx+0xc)) # Stmt-var-next Stmt-var-next => eax +16586 # var index/edx: (handle var) = curr2->value +16587 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +16588 89/<- %edx 0/r32/eax +16589 # if index->register +16590 81 7/subop/compare *(edx+0x18) 0/imm32 # Var-register +16591 { +16592 0f 84/jump-if-= break/disp32 +16593 $translate-mu-index-stmt-with-array-on-stack:emit-register-index: +16594 # if index is an int +16595 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax +16596 (is-simple-mu-type? %eax 1) # int => eax +16597 3d/compare-eax-and 0/imm32/false +16598 { +16599 0f 84/jump-if-= break/disp32 +16600 $translate-mu-index-stmt-with-array-on-stack:emit-int-register-index: +16601 # print index->register "<<" log2(array-element-size(base)) " + " base->offset+4 +16602 # . inouts[1]->register "<<" +16603 (lookup *(edx+0x18) *(edx+0x1c)) # Var-register Var-register => eax +16604 (write-buffered *(ebp+8) %eax) +16605 (write-buffered *(ebp+8) "<<") +16606 # . log2(array-element-size(base)) +16607 # TODO: ensure size is a power of 2 +16608 (array-element-size %ecx *(ebp+0x10) *(ebp+0x14)) # => eax +16609 (num-shift-rights %eax) # => eax +16610 (write-int32-hex-buffered *(ebp+8) %eax) +16611 # +16612 (write-buffered *(ebp+8) " + ") +16613 # +16614 8b/-> *(ecx+0x14) 0/r32/eax # Var-offset +16615 05/add-to-eax 4/imm32 # for array length +16616 (write-int32-hex-buffered *(ebp+8) %eax) +16617 e9/jump $translate-mu-index-stmt-with-array-on-stack:emit-register-index-done/disp32 +16618 } +16619 # if index->type is any other atom, abort +16620 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax +16621 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom +16622 0f 85/jump-if-!= $translate-mu-index-stmt-with-array:error2/disp32 +16623 # if index has type (offset ...) +16624 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +16625 (is-simple-mu-type? %eax 7) # => eax +16626 3d/compare-eax-and 0/imm32/false +16627 { +16628 0f 84/jump-if-= break/disp32 +16629 # print index->register +16630 $translate-mu-index-stmt-with-array-on-stack:emit-offset-register-index: +16631 (lookup *(edx+0x18) *(edx+0x1c)) # Var-register Var-register => eax +16632 (write-buffered *(ebp+8) %eax) +16633 } +16634 $translate-mu-index-stmt-with-array-on-stack:emit-register-index-done: +16635 (write-buffered *(ebp+8) ") ") +16636 e9/jump $translate-mu-index-stmt-with-array-on-stack:emit-output/disp32 +16637 } +16638 # otherwise if index is a literal +16639 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax +16640 (is-simple-mu-type? %eax 0) # => eax +16641 3d/compare-eax-and 0/imm32/false +16642 { +16643 0f 84/jump-if-= break/disp32 +16644 $translate-mu-index-stmt-with-array-on-stack:emit-literal-index: +16645 # var idx-value/edx: int = parse-hex-int(index->name) +16646 (lookup *edx *(edx+4)) # Var-name Var-name => eax +16647 (parse-hex-int %eax) # Var-name => eax +16648 89/<- %edx 0/r32/eax +16649 # offset = idx-value * array-element-size(base) +16650 (array-element-size %ecx *(ebp+0x10) *(ebp+0x14)) # => eax +16651 f7 4/subop/multiply-into-eax %edx # clobbers edx +16652 # offset += base->offset +16653 03/add *(ecx+0x14) 0/r32/eax # Var-offset +16654 # offset += 4 for array size +16655 05/add-to-eax 4/imm32 +16656 # TODO: check edx for overflow +16657 # print offset +16658 (write-int32-hex-buffered *(ebp+8) %eax) +16659 (write-buffered *(ebp+8) ") ") +16660 e9/jump $translate-mu-index-stmt-with-array-on-stack:emit-output/disp32 +16661 } +16662 # otherwise abort +16663 e9/jump $translate-mu-index-stmt-with-array:error1/disp32 +16664 $translate-mu-index-stmt-with-array-on-stack:emit-output: +16665 # outputs[0] "/r32" +16666 8b/-> *(ebp+0xc) 0/r32/eax +16667 (lookup *(eax+0x14) *(eax+0x18)) # Stmt1-outputs Stmt1-outputs => eax +16668 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +16669 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax +16670 (get Mu-registers %eax 0xc "Mu-registers") # => eax: (addr int) +16671 (write-int32-hex-buffered *(ebp+8) *eax) +16672 (write-buffered *(ebp+8) "/r32\n") +16673 $translate-mu-index-stmt-with-array-on-stack:end: +16674 # . restore registers +16675 5b/pop-to-ebx +16676 5a/pop-to-edx +16677 59/pop-to-ecx +16678 58/pop-to-eax +16679 # . epilogue +16680 89/<- %esp 5/r32/ebp +16681 5d/pop-to-ebp +16682 c3/return +16683 +16684 translate-mu-compute-index-stmt: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) +16685 # . prologue +16686 55/push-ebp +16687 89/<- %ebp 4/r32/esp +16688 # . save registers +16689 50/push-eax +16690 51/push-ecx +16691 52/push-edx +16692 53/push-ebx +16693 # +16694 (emit-indent *(ebp+8) *Curr-block-depth) +16695 (write-buffered *(ebp+8) "69/multiply") +16696 # ecx = stmt +16697 8b/-> *(ebp+0xc) 1/r32/ecx +16698 # var first-inout/ebx: (addr stmt-var) = stmt->inouts[0] +16699 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax +16700 89/<- %ebx 0/r32/eax +16701 $translate-mu-compute-index-stmt:emit-index: +16702 (lookup *(ebx+8) *(ebx+0xc)) # Stmt-var-next Stmt-var-next => eax +16703 (emit-subx-var-as-rm32 *(ebp+8) %eax) +16704 (write-buffered *(ebp+8) Space) +16705 $translate-mu-compute-index-stmt:emit-elem-size: +16706 # var base/ebx: (addr var) +16707 (lookup *ebx *(ebx+4)) # Stmt-var-value Stmt-var-value => eax +16708 89/<- %ebx 0/r32/eax +16709 # print array-element-size(base) +16710 (array-element-size %ebx *(ebp+0x10) *(ebp+0x14)) # => eax +16711 (write-int32-hex-buffered *(ebp+8) %eax) +16712 (write-buffered *(ebp+8) "/imm32 ") +16713 $translate-mu-compute-index-stmt:emit-output: +16714 # outputs[0] "/r32" +16715 (lookup *(ecx+0x14) *(ecx+0x18)) # Stmt1-outputs Stmt1-outputs => eax +16716 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +16717 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax +16718 (get Mu-registers %eax 0xc "Mu-registers") # => eax: (addr int) +16719 (write-int32-hex-buffered *(ebp+8) *eax) +16720 (write-buffered *(ebp+8) "/r32\n") +16721 $translate-mu-compute-index-stmt:end: +16722 # . restore registers +16723 5b/pop-to-ebx +16724 5a/pop-to-edx +16725 59/pop-to-ecx +16726 58/pop-to-eax +16727 # . epilogue +16728 89/<- %esp 5/r32/ebp +16729 5d/pop-to-ebp +16730 c3/return +16731 +16732 translate-mu-get-stmt: # out: (addr buffered-file), stmt: (addr stmt) +16733 # . prologue +16734 55/push-ebp +16735 89/<- %ebp 4/r32/esp +16736 # . save registers +16737 50/push-eax +16738 51/push-ecx +16739 52/push-edx +16740 # +16741 (emit-indent *(ebp+8) *Curr-block-depth) +16742 (write-buffered *(ebp+8) "8d/copy-address ") +16743 # ecx = stmt +16744 8b/-> *(ebp+0xc) 1/r32/ecx +16745 # var offset/edx: int = get offset of stmt +16746 (mu-get-offset %ecx) # => eax +16747 89/<- %edx 0/r32/eax +16748 # var base/eax: (addr var) = stmt->inouts->value +16749 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax +16750 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +16751 # if base is in a register +16752 81 7/subop/compare *(eax+0x18) 0/imm32 # Var-register +16753 { +16754 0f 84/jump-if-= break/disp32 +16755 $translate-mu-get-stmt:emit-register-input: +16756 # emit "*(" base->register " + " offset ") " +16757 (write-buffered *(ebp+8) "*(") +16758 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax +16759 (write-buffered *(ebp+8) %eax) +16760 (write-buffered *(ebp+8) " + ") +16761 (write-int32-hex-buffered *(ebp+8) %edx) +16762 (write-buffered *(ebp+8) ") ") +16763 e9/jump $translate-mu-get-stmt:emit-output/disp32 +16764 } +16765 # otherwise base is on the stack +16766 { +16767 $translate-mu-get-stmt:emit-stack-input: +16768 # emit "*(ebp + " inouts[0]->stack-offset + offset ") " +16769 (write-buffered *(ebp+8) "*(ebp+") +16770 03/add *(eax+0x14) 2/r32/edx # Var-offset +16771 (write-int32-hex-buffered *(ebp+8) %edx) +16772 (write-buffered *(ebp+8) ") ") +16773 eb/jump $translate-mu-get-stmt:emit-output/disp8 +16774 } +16775 $translate-mu-get-stmt:emit-output: +16776 # var output/eax: (addr var) = stmt->outputs->value +16777 (lookup *(ecx+0x14) *(ecx+0x18)) # Stmt1-outputs Stmt1-outputs => eax +16778 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +16779 # emit offset->register "/r32" +16780 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax +16781 (get Mu-registers %eax 0xc "Mu-registers") # => eax: (addr int) +16782 (write-int32-hex-buffered *(ebp+8) *eax) +16783 (write-buffered *(ebp+8) "/r32\n") +16784 $translate-mu-get-stmt:end: +16785 # . restore registers +16786 5a/pop-to-edx +16787 59/pop-to-ecx +16788 58/pop-to-eax +16789 # . epilogue +16790 89/<- %esp 5/r32/ebp +16791 5d/pop-to-ebp +16792 c3/return +16793 +16794 translate-mu-allocate-stmt: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) +16795 # . prologue +16796 55/push-ebp +16797 89/<- %ebp 4/r32/esp +16798 # . save registers +16799 50/push-eax +16800 56/push-esi +16801 57/push-edi +16802 # esi = stmt +16803 8b/-> *(ebp+0xc) 6/r32/esi +16804 # var target/edi: (addr stmt-var) = stmt->inouts[0] +16805 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax +16806 89/<- %edi 0/r32/eax +16807 # +16808 (emit-indent *(ebp+8) *Curr-block-depth) +16809 (write-buffered *(ebp+8) "(allocate Heap ") +16810 (addr-handle-payload-size %edi *(ebp+0x10) *(ebp+0x14)) # => eax +16811 (write-int32-hex-buffered *(ebp+8) %eax) +16812 (emit-subx-call-operand *(ebp+8) %edi) +16813 (write-buffered *(ebp+8) ")\n") +16814 $translate-mu-allocate-stmt:end: +16815 # . restore registers +16816 5f/pop-to-edi +16817 5e/pop-to-esi +16818 58/pop-to-eax +16819 # . epilogue +16820 89/<- %esp 5/r32/ebp +16821 5d/pop-to-ebp +16822 c3/return +16823 +16824 addr-handle-payload-size: # s: (addr stmt-var), err: (addr buffered-file), ed: (addr exit-descriptor) -> result/eax: int +16825 # . prologue +16826 55/push-ebp +16827 89/<- %ebp 4/r32/esp +16828 # var t/eax: (addr type-tree) = s->value->type +16829 8b/-> *(ebp+8) 0/r32/eax +16830 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +16831 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +16832 # TODO: check eax != 0 +16833 # TODO: check !t->is-atom? +16834 # TODO: check t->left == addr +16835 # t = t->right +16836 $addr-handle-payload-size:skip-addr: +16837 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax +16838 # TODO: check eax != 0 +16839 # TODO: check !t->is-atom? +16840 # TODO: check t->left == handle +16841 # t = t->right +16842 $addr-handle-payload-size:skip-handle: +16843 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax +16844 # TODO: check eax != 0 +16845 # if !t->is-atom? t = t->left +16846 81 7/subop/compare *eax 0/imm32/false +16847 { +16848 75/jump-if-!= break/disp8 +16849 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +16850 } +16851 # TODO: check t->is-atom? +16852 # return size(t->value) +16853 (size-of-type-id *(eax+4)) # Type-tree-value => eax +16854 $addr-handle-payload-size:end: +16855 # . epilogue +16856 89/<- %esp 5/r32/ebp +16857 5d/pop-to-ebp +16858 c3/return +16859 +16860 addr-payload-size: # s: (addr stmt-var), err: (addr buffered-file), ed: (addr exit-descriptor) -> result/eax: int +16861 # . prologue +16862 55/push-ebp +16863 89/<- %ebp 4/r32/esp +16864 # var t/eax: (addr type-tree) = s->value->type +16865 8b/-> *(ebp+8) 0/r32/eax +16866 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +16867 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +16868 # TODO: check eax != 0 +16869 # TODO: check !t->is-atom? +16870 # TODO: check t->left == addr +16871 # t = t->right +16872 $addr-payload-size:skip-addr: +16873 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax +16874 # TODO: check eax != 0 +16875 # if !t->is-atom? t = t->left +16876 81 7/subop/compare *eax 0/imm32/false +16877 { +16878 75/jump-if-!= break/disp8 +16879 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +16880 } +16881 # TODO: check t->is-atom? +16882 # return size(t->value) +16883 (size-of-type-id *(eax+4)) # Type-tree-value => eax +16884 $addr-payload-size:end: +16885 # . epilogue +16886 89/<- %esp 5/r32/ebp +16887 5d/pop-to-ebp +16888 c3/return +16889 +16890 translate-mu-populate-stmt: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) +16891 # . prologue +16892 55/push-ebp +16893 89/<- %ebp 4/r32/esp +16894 # . save registers +16895 50/push-eax +16896 51/push-ecx +16897 56/push-esi +16898 57/push-edi +16899 # esi = stmt +16900 8b/-> *(ebp+0xc) 6/r32/esi +16901 # var target/edi: (addr stmt-var) = stmt->inouts[0] +16902 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax +16903 89/<- %edi 0/r32/eax +16904 # var len/ecx: (addr stmt-var) = stmt->inouts[1] +16905 (lookup *(edi+8) *(edi+0xc)) # Stmt-var-next Stmt-var-next => eax +16906 89/<- %ecx 0/r32/eax +16907 # +16908 (emit-indent *(ebp+8) *Curr-block-depth) +16909 (write-buffered *(ebp+8) "(allocate-array2 Heap ") +16910 (addr-handle-array-payload-size %edi *(ebp+0x10) *(ebp+0x14)) # => eax +16911 (write-int32-hex-buffered *(ebp+8) %eax) +16912 (emit-subx-call-operand *(ebp+8) %ecx) +16913 (emit-subx-call-operand *(ebp+8) %edi) +16914 (write-buffered *(ebp+8) ")\n") +16915 $translate-mu-populate-stmt:end: +16916 # . restore registers +16917 5f/pop-to-edi +16918 5e/pop-to-esi +16919 59/pop-to-ecx +16920 58/pop-to-eax +16921 # . epilogue +16922 89/<- %esp 5/r32/ebp +16923 5d/pop-to-ebp +16924 c3/return +16925 +16926 translate-mu-populate-stream-stmt: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) +16927 # . prologue +16928 55/push-ebp +16929 89/<- %ebp 4/r32/esp +16930 # . save registers +16931 50/push-eax +16932 51/push-ecx +16933 56/push-esi +16934 57/push-edi +16935 # esi = stmt +16936 8b/-> *(ebp+0xc) 6/r32/esi +16937 # var target/edi: (addr stmt-var) = stmt->inouts[0] +16938 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax +16939 89/<- %edi 0/r32/eax +16940 # var len/ecx: (addr stmt-var) = stmt->inouts[1] +16941 (lookup *(edi+8) *(edi+0xc)) # Stmt-var-next Stmt-var-next => eax +16942 89/<- %ecx 0/r32/eax +16943 # +16944 (emit-indent *(ebp+8) *Curr-block-depth) +16945 (write-buffered *(ebp+8) "(new-stream Heap ") +16946 (addr-handle-stream-payload-size %edi *(ebp+0x10) *(ebp+0x14)) # => eax +16947 (write-int32-hex-buffered *(ebp+8) %eax) +16948 (emit-subx-call-operand *(ebp+8) %ecx) +16949 (emit-subx-call-operand *(ebp+8) %edi) +16950 (write-buffered *(ebp+8) ")\n") +16951 $translate-mu-populate-stream-stmt:end: +16952 # . restore registers +16953 5f/pop-to-edi +16954 5e/pop-to-esi +16955 59/pop-to-ecx +16956 58/pop-to-eax +16957 # . epilogue +16958 89/<- %esp 5/r32/ebp +16959 5d/pop-to-ebp +16960 c3/return +16961 +16962 translate-mu-read-from-stream-stmt: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) +16963 # . prologue +16964 55/push-ebp +16965 89/<- %ebp 4/r32/esp +16966 # . save registers +16967 50/push-eax +16968 51/push-ecx +16969 56/push-esi +16970 57/push-edi +16971 # esi = stmt +16972 8b/-> *(ebp+0xc) 6/r32/esi +16973 # var stream/ecx: (addr stmt-var) = stmt->inouts[0] +16974 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax +16975 89/<- %ecx 0/r32/eax +16976 # var target/edi: (addr stmt-var) = stmt->inouts[1] +16977 (lookup *(ecx+8) *(ecx+0xc)) # Stmt-var-next Stmt-var-next => eax +16978 89/<- %edi 0/r32/eax +16979 # +16980 (emit-indent *(ebp+8) *Curr-block-depth) +16981 (write-buffered *(ebp+8) "(read-from-stream") +16982 (emit-subx-call-operand *(ebp+8) %ecx) +16983 (emit-subx-call-operand *(ebp+8) %edi) +16984 (write-buffered *(ebp+8) Space) +16985 (addr-payload-size %edi *(ebp+0x10) *(ebp+0x14)) # => eax +16986 (write-int32-hex-buffered *(ebp+8) %eax) +16987 (write-buffered *(ebp+8) ")\n") +16988 $translate-mu-read-from-stream-stmt:end: +16989 # . restore registers +16990 5f/pop-to-edi +16991 5e/pop-to-esi +16992 59/pop-to-ecx +16993 58/pop-to-eax +16994 # . epilogue +16995 89/<- %esp 5/r32/ebp +16996 5d/pop-to-ebp +16997 c3/return +16998 +16999 translate-mu-write-to-stream-stmt: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) +17000 # . prologue +17001 55/push-ebp +17002 89/<- %ebp 4/r32/esp +17003 # . save registers +17004 50/push-eax +17005 51/push-ecx +17006 56/push-esi +17007 57/push-edi +17008 # esi = stmt +17009 8b/-> *(ebp+0xc) 6/r32/esi +17010 # var stream/ecx: (addr stmt-var) = stmt->inouts[0] +17011 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax +17012 89/<- %ecx 0/r32/eax +17013 # var target/edi: (addr stmt-var) = stmt->inouts[1] +17014 (lookup *(ecx+8) *(ecx+0xc)) # Stmt-var-next Stmt-var-next => eax +17015 89/<- %edi 0/r32/eax +17016 # +17017 (emit-indent *(ebp+8) *Curr-block-depth) +17018 (write-buffered *(ebp+8) "(write-to-stream") +17019 (emit-subx-call-operand *(ebp+8) %ecx) +17020 (flush *(ebp+8)) +17021 (emit-subx-call-operand *(ebp+8) %edi) +17022 (flush *(ebp+8)) +17023 (write-buffered *(ebp+8) Space) +17024 (flush *(ebp+8)) +17025 (addr-payload-size %edi *(ebp+0x10) *(ebp+0x14)) # => eax +17026 (write-int32-hex-buffered *(ebp+8) %eax) +17027 (write-buffered *(ebp+8) ")\n") +17028 $translate-mu-write-to-stream-stmt:end: +17029 # . restore registers +17030 5f/pop-to-edi +17031 5e/pop-to-esi +17032 59/pop-to-ecx +17033 58/pop-to-eax +17034 # . epilogue +17035 89/<- %esp 5/r32/ebp +17036 5d/pop-to-ebp +17037 c3/return +17038 +17039 addr-handle-array-payload-size: # s: (addr stmt-var), err: (addr buffered-file), ed: (addr exit-descriptor) -> result/eax: int +17040 # . prologue +17041 55/push-ebp +17042 89/<- %ebp 4/r32/esp +17043 # var t/eax: (addr type-tree) = s->value->type +17044 8b/-> *(ebp+8) 0/r32/eax +17045 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +17046 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +17047 # TODO: check eax != 0 +17048 # TODO: check !t->is-atom? +17049 # TODO: check t->left == addr +17050 # t = t->right +17051 $addr-handle-array-payload-size:skip-addr: +17052 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax +17053 # TODO: check eax != 0 +17054 # TODO: check !t->is-atom? +17055 # TODO: check t->left == handle +17056 # t = t->right +17057 $addr-handle-array-payload-size:skip-handle: +17058 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax +17059 # TODO: check eax != 0 +17060 # TODO: check !t->is-atom? +17061 # TODO: check t->left == array +17062 # t = t->right +17063 $addr-handle-array-payload-size:skip-array: +17064 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax +17065 # TODO: check eax != 0 +17066 # if !t->is-atom? t = t->left +17067 81 7/subop/compare *eax 0/imm32/false +17068 { +17069 75/jump-if-!= break/disp8 +17070 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +17071 } +17072 $addr-handle-array-payload-size:compute-size: +17073 # TODO: check t->is-atom? +17074 # return size(t->value) +17075 (size-of-type-id-as-array-element *(eax+4)) # Type-tree-value => eax +17076 $addr-handle-array-payload-size:end: +17077 # . epilogue +17078 89/<- %esp 5/r32/ebp +17079 5d/pop-to-ebp +17080 c3/return +17081 +17082 addr-handle-stream-payload-size: # s: (addr stmt-var), err: (addr buffered-file), ed: (addr exit-descriptor) -> result/eax: int +17083 # . prologue +17084 55/push-ebp +17085 89/<- %ebp 4/r32/esp +17086 # var t/eax: (addr type-tree) = s->value->type +17087 8b/-> *(ebp+8) 0/r32/eax +17088 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +17089 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +17090 # TODO: check eax != 0 +17091 # TODO: check !t->is-atom? +17092 # TODO: check t->left == addr +17093 # t = t->right +17094 $addr-handle-stream-payload-size:skip-addr: +17095 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax +17096 # TODO: check eax != 0 +17097 # TODO: check !t->is-atom? +17098 # TODO: check t->left == handle +17099 # t = t->right +17100 $addr-handle-stream-payload-size:skip-handle: +17101 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax +17102 # TODO: check eax != 0 +17103 # TODO: check !t->is-atom? +17104 # TODO: check t->left == stream +17105 # t = t->right +17106 $addr-handle-stream-payload-size:skip-stream: +17107 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax +17108 # TODO: check eax != 0 +17109 # if !t->is-atom? t = t->left +17110 81 7/subop/compare *eax 0/imm32/false +17111 { +17112 75/jump-if-!= break/disp8 +17113 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +17114 } +17115 $addr-handle-stream-payload-size:compute-size: +17116 # TODO: check t->is-atom? +17117 # return size(t->value) +17118 (size-of-type-id-as-array-element *(eax+4)) # Type-tree-value => eax +17119 $addr-handle-stream-payload-size:end: +17120 # . epilogue +17121 89/<- %esp 5/r32/ebp +17122 5d/pop-to-ebp +17123 c3/return +17124 +17125 power-of-2?: # n: int, err: (addr buffered-file), ed: (addr exit-descriptor) -> result/eax: boolean +17126 # precondition: n is positive +17127 # . prologue +17128 55/push-ebp +17129 89/<- %ebp 4/r32/esp +17130 # eax = n +17131 8b/-> *(ebp+8) 0/r32/eax +17132 # if (n < 0) abort +17133 3d/compare-eax-with 0/imm32 +17134 0f 8c/jump-if-< $power-of-2?:abort/disp32 +17135 # var tmp/eax: int = n-1 +17136 48/decrement-eax +17137 # var tmp2/eax: int = n & tmp +17138 23/and-> *(ebp+8) 0/r32/eax +17139 # return (tmp2 == 0) +17140 3d/compare-eax-and 0/imm32 +17141 0f 94/set-byte-if-= %al +17142 81 4/subop/and %eax 0xff/imm32 +17143 $power-of-2?:end: +17144 # . epilogue +17145 89/<- %esp 5/r32/ebp +17146 5d/pop-to-ebp +17147 c3/return +17148 +17149 $power-of-2?:abort: +17150 (write-buffered *(ebp+0xc) "power-of-2?: negative number\n") +17151 (flush *(ebp+0xc)) +17152 (stop *(ebp+0x10) 1) +17153 # never gets here +17154 +17155 num-shift-rights: # n: int -> result/eax: int +17156 # precondition: n is a positive power of 2 +17157 # . prologue +17158 55/push-ebp +17159 89/<- %ebp 4/r32/esp +17160 # . save registers +17161 51/push-ecx +17162 # var curr/ecx: int = n +17163 8b/-> *(ebp+8) 1/r32/ecx +17164 # result = 0 +17165 b8/copy-to-eax 0/imm32 +17166 { +17167 # if (curr <= 1) break +17168 81 7/subop/compare %ecx 1/imm32 +17169 7e/jump-if-<= break/disp8 +17170 40/increment-eax +17171 c1/shift 5/subop/arithmetic-right %ecx 1/imm8 +17172 eb/jump loop/disp8 +17173 } +17174 $num-shift-rights:end: +17175 # . restore registers +17176 59/pop-to-ecx +17177 # . epilogue +17178 89/<- %esp 5/r32/ebp +17179 5d/pop-to-ebp +17180 c3/return +17181 +17182 mu-get-offset: # stmt: (addr stmt) -> result/eax: int +17183 # . prologue +17184 55/push-ebp +17185 89/<- %ebp 4/r32/esp +17186 # var second-inout/eax: (addr stmt-var) = stmt->inouts->next +17187 8b/-> *(ebp+8) 0/r32/eax +17188 (lookup *(eax+0xc) *(eax+0x10)) # Stmt1-inouts Stmt1-inouts => eax +17189 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax +17190 # var output-var/eax: (addr var) = second-inout->value +17191 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +17192 #? (write-buffered Stderr "mu-get-offset: ") +17193 #? (write-int32-hex-buffered Stderr %eax) +17194 #? (write-buffered Stderr " name: ") +17195 #? 50/push-eax +17196 #? (lookup *eax *(eax+4)) # Var-name +17197 #? (write-buffered Stderr %eax) +17198 #? 58/pop-to-eax +17199 #? (write-buffered Stderr Newline) +17200 #? (flush Stderr) +17201 # return output-var->stack-offset +17202 8b/-> *(eax+0x14) 0/r32/eax # Var-offset +17203 #? (write-buffered Stderr "=> ") +17204 #? (write-int32-hex-buffered Stderr %eax) +17205 #? (write-buffered Stderr Newline) +17206 #? (flush Stderr) +17207 $emit-get-offset:end: +17208 # . epilogue +17209 89/<- %esp 5/r32/ebp +17210 5d/pop-to-ebp +17211 c3/return +17212 +17213 emit-subx-block: # out: (addr buffered-file), block: (addr block), vars: (addr stack live-var), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +17214 # . prologue +17215 55/push-ebp +17216 89/<- %ebp 4/r32/esp +17217 # . save registers +17218 50/push-eax +17219 51/push-ecx +17220 56/push-esi +17221 # esi = block +17222 8b/-> *(ebp+0xc) 6/r32/esi +17223 # block->var->block-depth = *Curr-block-depth +17224 (lookup *(esi+0xc) *(esi+0x10)) # Block-var Block-var => eax +17225 8b/-> *Curr-block-depth 1/r32/ecx +17226 89/<- *(eax+0x10) 1/r32/ecx # Var-block-depth +17227 # var stmts/eax: (addr list stmt) = lookup(block->statements) +17228 (lookup *(esi+4) *(esi+8)) # Block-stmts Block-stmts => eax +17229 # +17230 { +17231 $emit-subx-block:check-empty: +17232 3d/compare-eax-and 0/imm32 +17233 0f 84/jump-if-= break/disp32 +17234 (emit-indent *(ebp+8) *Curr-block-depth) +17235 (write-buffered *(ebp+8) "{\n") +17236 # var v/ecx: (addr var) = lookup(block->var) +17237 (lookup *(esi+0xc) *(esi+0x10)) # Block-var Block-var => eax +17238 89/<- %ecx 0/r32/eax +17239 # +17240 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax +17241 (write-buffered *(ebp+8) %eax) +17242 (write-buffered *(ebp+8) ":loop:\n") +17243 ff 0/subop/increment *Curr-block-depth +17244 (push *(ebp+0x10) *(esi+0xc)) # Block-var +17245 (push *(ebp+0x10) *(esi+0x10)) # Block-var +17246 (push *(ebp+0x10) 0) # false +17247 # emit block->statements +17248 (lookup *(esi+4) *(esi+8)) # Block-stmts Block-stmts => eax +17249 (emit-subx-stmt-list *(ebp+8) %eax *(ebp+0x10) *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c)) +17250 (pop *(ebp+0x10)) # => eax +17251 (pop *(ebp+0x10)) # => eax +17252 (pop *(ebp+0x10)) # => eax +17253 ff 1/subop/decrement *Curr-block-depth +17254 (emit-indent *(ebp+8) *Curr-block-depth) +17255 (write-buffered *(ebp+8) "}\n") +17256 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax +17257 (write-buffered *(ebp+8) %eax) +17258 (write-buffered *(ebp+8) ":break:\n") +17259 } +17260 $emit-subx-block:end: +17261 # . restore registers +17262 5e/pop-to-esi +17263 59/pop-to-ecx +17264 58/pop-to-eax +17265 # . epilogue +17266 89/<- %esp 5/r32/ebp +17267 5d/pop-to-ebp +17268 c3/return +17269 +17270 # Primitives supported +17271 # See mu_instructions for a summary of this linked-list data structure. +17272 # +17273 # For each operation, put variants with hard-coded registers before flexible ones. +17274 # +17275 # Unfortunately, our restrictions on addresses require that various fields in +17276 # primitives be handles, which complicates these definitions. +17277 # - we need to insert dummy fields all over the place for fake alloc-ids +17278 # - we can't use our syntax sugar of quoted literals for string fields +17279 # +17280 # Fake alloc-ids are needed because our type definitions up top require +17281 # handles but it's clearer to statically allocate these long-lived objects. +17282 # Fake alloc-ids are perfectly safe, but they can't be reclaimed. +17283 # +17284 # Every 'object' below starts with a fake alloc-id. It may also contain other +17285 # fake alloc-ids for various handle fields. +17286 # +17287 # I think of objects starting with a fake alloc-id as having type 'payload'. +17288 # It's not really intended to be created dynamically; for that use `allocate` +17289 # as usual. +17290 # +17291 # Idea for a notation to simplify such definitions: +17292 # _Primitive-increment-eax: # (payload primitive) +17293 # 0x11/alloc-id:fake:payload +17294 # 0x11 @(0x11 "increment") # name +17295 # 0 0 # inouts +17296 # 0x11 @(0x11/payload +17297 # 0x11 @(0x11/payload # List-value +17298 # 0 0 # Var-name +17299 # 0x11 @(0x11 # Var-type +17300 # 1/is-atom +17301 # 1/value 0/unused # Type-tree-left +17302 # 0 0 # Type-tree-right +17303 # ) +17304 # 1 # block-depth +17305 # 0 # stack-offset +17306 # 0x11 @(0x11 "eax") # Var-register +17307 # ) +17308 # 0 0) # List-next +17309 # ... +17310 # _Primitive-increment-ecx/imm32/next +17311 # ... +17312 # Awfully complex and non-obvious. But also clearly signals there's something +17313 # to learn here, so may be worth trying. +17314 # +17315 # '@' is just an initial thought. Punctuation used so far in Mu: () * % # / " +17316 # +17317 # For now we'll continue to just use comments and manually ensure they stay up +17318 # to date. +17319 == data +17320 Primitives: # (addr primitive) +17321 # - increment/decrement +17322 _Primitive-increment-eax: # (addr primitive) +17323 # var/eax <- increment => 40/increment-eax +17324 0x11/imm32/alloc-id:fake +17325 _string-increment/imm32/name +17326 0/imm32/no-inouts +17327 0/imm32/no-inouts +17328 0x11/imm32/alloc-id:fake +17329 Single-int-var-in-eax/imm32/outputs +17330 0x11/imm32/alloc-id:fake +17331 _string_40_increment_eax/imm32/subx-name +17332 0/imm32/no-rm32 +17333 0/imm32/no-r32 +17334 0/imm32/no-imm32 +17335 0/imm32/no-imm8 +17336 0/imm32/no-disp32 +17337 0/imm32/output-is-write-only +17338 0x11/imm32/alloc-id:fake +17339 _Primitive-increment-ecx/imm32/next +17340 _Primitive-increment-ecx: # (payload primitive) +17341 0x11/imm32/alloc-id:fake:payload +17342 # var/ecx <- increment => 41/increment-ecx +17343 0x11/imm32/alloc-id:fake +17344 _string-increment/imm32/name +17345 0/imm32/no-inouts +17346 0/imm32/no-inouts +17347 0x11/imm32/alloc-id:fake +17348 Single-int-var-in-ecx/imm32/outputs +17349 0x11/imm32/alloc-id:fake +17350 _string_41_increment_ecx/imm32/subx-name +17351 0/imm32/no-rm32 +17352 0/imm32/no-r32 +17353 0/imm32/no-imm32 +17354 0/imm32/no-imm8 +17355 0/imm32/no-disp32 +17356 0/imm32/output-is-write-only +17357 0x11/imm32/alloc-id:fake +17358 _Primitive-increment-edx/imm32/next +17359 _Primitive-increment-edx: # (payload primitive) +17360 0x11/imm32/alloc-id:fake:payload +17361 # var/edx <- increment => 42/increment-edx +17362 0x11/imm32/alloc-id:fake +17363 _string-increment/imm32/name +17364 0/imm32/no-inouts +17365 0/imm32/no-inouts +17366 0x11/imm32/alloc-id:fake +17367 Single-int-var-in-edx/imm32/outputs +17368 0x11/imm32/alloc-id:fake +17369 _string_42_increment_edx/imm32/subx-name +17370 0/imm32/no-rm32 +17371 0/imm32/no-r32 +17372 0/imm32/no-imm32 +17373 0/imm32/no-imm8 +17374 0/imm32/no-disp32 +17375 0/imm32/output-is-write-only +17376 0x11/imm32/alloc-id:fake +17377 _Primitive-increment-ebx/imm32/next +17378 _Primitive-increment-ebx: # (payload primitive) +17379 0x11/imm32/alloc-id:fake:payload +17380 # var/ebx <- increment => 43/increment-ebx +17381 0x11/imm32/alloc-id:fake +17382 _string-increment/imm32/name +17383 0/imm32/no-inouts +17384 0/imm32/no-inouts +17385 0x11/imm32/alloc-id:fake +17386 Single-int-var-in-ebx/imm32/outputs +17387 0x11/imm32/alloc-id:fake +17388 _string_43_increment_ebx/imm32/subx-name +17389 0/imm32/no-rm32 +17390 0/imm32/no-r32 +17391 0/imm32/no-imm32 +17392 0/imm32/no-imm8 +17393 0/imm32/no-disp32 +17394 0/imm32/output-is-write-only +17395 0x11/imm32/alloc-id:fake +17396 _Primitive-increment-esi/imm32/next +17397 _Primitive-increment-esi: # (payload primitive) +17398 0x11/imm32/alloc-id:fake:payload +17399 # var/esi <- increment => 46/increment-esi +17400 0x11/imm32/alloc-id:fake +17401 _string-increment/imm32/name +17402 0/imm32/no-inouts +17403 0/imm32/no-inouts +17404 0x11/imm32/alloc-id:fake +17405 Single-int-var-in-esi/imm32/outputs +17406 0x11/imm32/alloc-id:fake +17407 _string_46_increment_esi/imm32/subx-name +17408 0/imm32/no-rm32 +17409 0/imm32/no-r32 +17410 0/imm32/no-imm32 +17411 0/imm32/no-imm8 +17412 0/imm32/no-disp32 +17413 0/imm32/output-is-write-only 17414 0x11/imm32/alloc-id:fake -17415 _string_0f_af_multiply/imm32/subx-name -17416 1/imm32/rm32-is-first-inout -17417 3/imm32/r32-is-first-output -17418 0/imm32/no-imm32 -17419 0/imm32/no-imm8 -17420 0/imm32/no-disp32 -17421 0/imm32/output-is-write-only -17422 0x11/imm32/alloc-id:fake -17423 _Primitive-multiply-reg-by-mem/imm32/next -17424 _Primitive-multiply-reg-by-mem: # (payload primitive) -17425 0x11/imm32/alloc-id:fake:payload -17426 # var1/reg <- multiply var2 => 0f af/multiply var2/rm32 var1/r32 -17427 0x11/imm32/alloc-id:fake -17428 _string-multiply/imm32/name -17429 0x11/imm32/alloc-id:fake -17430 Single-int-var-in-mem/imm32/inouts -17431 0x11/imm32/alloc-id:fake -17432 Single-int-var-in-some-register/imm32/outputs +17415 _Primitive-increment-edi/imm32/next +17416 _Primitive-increment-edi: # (payload primitive) +17417 0x11/imm32/alloc-id:fake:payload +17418 # var/edi <- increment => 47/increment-edi +17419 0x11/imm32/alloc-id:fake +17420 _string-increment/imm32/name +17421 0/imm32/no-inouts +17422 0/imm32/no-inouts +17423 0x11/imm32/alloc-id:fake +17424 Single-int-var-in-edi/imm32/outputs +17425 0x11/imm32/alloc-id:fake +17426 _string_47_increment_edi/imm32/subx-name +17427 0/imm32/no-rm32 +17428 0/imm32/no-r32 +17429 0/imm32/no-imm32 +17430 0/imm32/no-imm8 +17431 0/imm32/no-disp32 +17432 0/imm32/output-is-write-only 17433 0x11/imm32/alloc-id:fake -17434 _string_0f_af_multiply/imm32/subx-name -17435 1/imm32/rm32-is-first-inout -17436 3/imm32/r32-is-first-output -17437 0/imm32/no-imm32 -17438 0/imm32/no-imm8 -17439 0/imm32/no-disp32 -17440 0/imm32/output-is-write-only -17441 0x11/imm32/alloc-id:fake -17442 _Primitive-break-if-addr</imm32/next -17443 # - branches -17444 _Primitive-break-if-addr<: # (payload primitive) -17445 0x11/imm32/alloc-id:fake:payload -17446 0x11/imm32/alloc-id:fake -17447 _string-break-if-addr</imm32/name -17448 0/imm32/no-inouts -17449 0/imm32/no-inouts -17450 0/imm32/no-outputs -17451 0/imm32/no-outputs +17434 _Primitive-decrement-eax/imm32/next +17435 _Primitive-decrement-eax: # (payload primitive) +17436 0x11/imm32/alloc-id:fake:payload +17437 # var/eax <- decrement => 48/decrement-eax +17438 0x11/imm32/alloc-id:fake +17439 _string-decrement/imm32/name +17440 0/imm32/no-inouts +17441 0/imm32/no-inouts +17442 0x11/imm32/alloc-id:fake +17443 Single-int-var-in-eax/imm32/outputs +17444 0x11/imm32/alloc-id:fake +17445 _string_48_decrement_eax/imm32/subx-name +17446 0/imm32/no-rm32 +17447 0/imm32/no-r32 +17448 0/imm32/no-imm32 +17449 0/imm32/no-imm8 +17450 0/imm32/no-disp32 +17451 0/imm32/output-is-write-only 17452 0x11/imm32/alloc-id:fake -17453 _string_0f_82_jump_break/imm32/subx-name -17454 0/imm32/no-rm32 -17455 0/imm32/no-r32 -17456 0/imm32/no-imm32 -17457 0/imm32/no-imm8 -17458 0/imm32/no-disp32 -17459 0/imm32/no-output -17460 0x11/imm32/alloc-id:fake -17461 _Primitive-break-if-addr>=/imm32/next -17462 _Primitive-break-if-addr>=: # (payload primitive) -17463 0x11/imm32/alloc-id:fake:payload -17464 0x11/imm32/alloc-id:fake -17465 _string-break-if-addr>=/imm32/name -17466 0/imm32/no-inouts -17467 0/imm32/no-inouts -17468 0/imm32/no-outputs -17469 0/imm32/no-outputs -17470 0x11/imm32/alloc-id:fake -17471 _string_0f_83_jump_break/imm32/subx-name -17472 0/imm32/no-rm32 -17473 0/imm32/no-r32 -17474 0/imm32/no-imm32 -17475 0/imm32/no-imm8 -17476 0/imm32/no-disp32 -17477 0/imm32/no-output -17478 0x11/imm32/alloc-id:fake -17479 _Primitive-break-if-=/imm32/next -17480 _Primitive-break-if-=: # (payload primitive) -17481 0x11/imm32/alloc-id:fake:payload +17453 _Primitive-decrement-ecx/imm32/next +17454 _Primitive-decrement-ecx: # (payload primitive) +17455 0x11/imm32/alloc-id:fake:payload +17456 # var/ecx <- decrement => 49/decrement-ecx +17457 0x11/imm32/alloc-id:fake +17458 _string-decrement/imm32/name +17459 0/imm32/no-inouts +17460 0/imm32/no-inouts +17461 0x11/imm32/alloc-id:fake +17462 Single-int-var-in-ecx/imm32/outputs +17463 0x11/imm32/alloc-id:fake +17464 _string_49_decrement_ecx/imm32/subx-name +17465 0/imm32/no-rm32 +17466 0/imm32/no-r32 +17467 0/imm32/no-imm32 +17468 0/imm32/no-imm8 +17469 0/imm32/no-disp32 +17470 0/imm32/output-is-write-only +17471 0x11/imm32/alloc-id:fake +17472 _Primitive-decrement-edx/imm32/next +17473 _Primitive-decrement-edx: # (payload primitive) +17474 0x11/imm32/alloc-id:fake:payload +17475 # var/edx <- decrement => 4a/decrement-edx +17476 0x11/imm32/alloc-id:fake +17477 _string-decrement/imm32/name +17478 0/imm32/no-inouts +17479 0/imm32/no-inouts +17480 0x11/imm32/alloc-id:fake +17481 Single-int-var-in-edx/imm32/outputs 17482 0x11/imm32/alloc-id:fake -17483 _string-break-if-=/imm32/name -17484 0/imm32/no-inouts -17485 0/imm32/no-inouts -17486 0/imm32/no-outputs -17487 0/imm32/no-outputs -17488 0x11/imm32/alloc-id:fake -17489 _string_0f_84_jump_break/imm32/subx-name -17490 0/imm32/no-rm32 -17491 0/imm32/no-r32 -17492 0/imm32/no-imm32 -17493 0/imm32/no-imm8 -17494 0/imm32/no-disp32 -17495 0/imm32/no-output -17496 0x11/imm32/alloc-id:fake -17497 _Primitive-break-if-!=/imm32/next -17498 _Primitive-break-if-!=: # (payload primitive) -17499 0x11/imm32/alloc-id:fake:payload -17500 0x11/imm32/alloc-id:fake -17501 _string-break-if-!=/imm32/name -17502 0/imm32/no-inouts -17503 0/imm32/no-inouts -17504 0/imm32/no-outputs -17505 0/imm32/no-outputs -17506 0x11/imm32/alloc-id:fake -17507 _string_0f_85_jump_break/imm32/subx-name -17508 0/imm32/no-rm32 -17509 0/imm32/no-r32 -17510 0/imm32/no-imm32 -17511 0/imm32/no-imm8 -17512 0/imm32/no-disp32 -17513 0/imm32/no-output +17483 _string_4a_decrement_edx/imm32/subx-name +17484 0/imm32/no-rm32 +17485 0/imm32/no-r32 +17486 0/imm32/no-imm32 +17487 0/imm32/no-imm8 +17488 0/imm32/no-disp32 +17489 0/imm32/output-is-write-only +17490 0x11/imm32/alloc-id:fake +17491 _Primitive-decrement-ebx/imm32/next +17492 _Primitive-decrement-ebx: # (payload primitive) +17493 0x11/imm32/alloc-id:fake:payload +17494 # var/ebx <- decrement => 4b/decrement-ebx +17495 0x11/imm32/alloc-id:fake +17496 _string-decrement/imm32/name +17497 0/imm32/no-inouts +17498 0/imm32/no-inouts +17499 0x11/imm32/alloc-id:fake +17500 Single-int-var-in-ebx/imm32/outputs +17501 0x11/imm32/alloc-id:fake +17502 _string_4b_decrement_ebx/imm32/subx-name +17503 0/imm32/no-rm32 +17504 0/imm32/no-r32 +17505 0/imm32/no-imm32 +17506 0/imm32/no-imm8 +17507 0/imm32/no-disp32 +17508 0/imm32/output-is-write-only +17509 0x11/imm32/alloc-id:fake +17510 _Primitive-decrement-esi/imm32/next +17511 _Primitive-decrement-esi: # (payload primitive) +17512 0x11/imm32/alloc-id:fake:payload +17513 # var/esi <- decrement => 4e/decrement-esi 17514 0x11/imm32/alloc-id:fake -17515 _Primitive-break-if-addr<=/imm32/next -17516 _Primitive-break-if-addr<=: # (payload primitive) -17517 0x11/imm32/alloc-id:fake:payload +17515 _string-decrement/imm32/name +17516 0/imm32/no-inouts +17517 0/imm32/no-inouts 17518 0x11/imm32/alloc-id:fake -17519 _string-break-if-addr<=/imm32/name -17520 0/imm32/no-inouts -17521 0/imm32/no-inouts -17522 0/imm32/no-outputs -17523 0/imm32/no-outputs -17524 0x11/imm32/alloc-id:fake -17525 _string_0f_86_jump_break/imm32/subx-name -17526 0/imm32/no-rm32 -17527 0/imm32/no-r32 -17528 0/imm32/no-imm32 -17529 0/imm32/no-imm8 -17530 0/imm32/no-disp32 -17531 0/imm32/no-output -17532 0x11/imm32/alloc-id:fake -17533 _Primitive-break-if-addr>/imm32/next -17534 _Primitive-break-if-addr>: # (payload primitive) -17535 0x11/imm32/alloc-id:fake:payload -17536 0x11/imm32/alloc-id:fake -17537 _string-break-if-addr>/imm32/name -17538 0/imm32/no-inouts -17539 0/imm32/no-inouts -17540 0/imm32/no-outputs -17541 0/imm32/no-outputs -17542 0x11/imm32/alloc-id:fake -17543 _string_0f_87_jump_break/imm32/subx-name -17544 0/imm32/no-rm32 -17545 0/imm32/no-r32 -17546 0/imm32/no-imm32 -17547 0/imm32/no-imm8 -17548 0/imm32/no-disp32 -17549 0/imm32/no-output -17550 0x11/imm32/alloc-id:fake -17551 _Primitive-break-if-</imm32/next -17552 _Primitive-break-if-<: # (payload primitive) -17553 0x11/imm32/alloc-id:fake:payload +17519 Single-int-var-in-esi/imm32/outputs +17520 0x11/imm32/alloc-id:fake +17521 _string_4e_decrement_esi/imm32/subx-name +17522 0/imm32/no-rm32 +17523 0/imm32/no-r32 +17524 0/imm32/no-imm32 +17525 0/imm32/no-imm8 +17526 0/imm32/no-disp32 +17527 0/imm32/output-is-write-only +17528 0x11/imm32/alloc-id:fake +17529 _Primitive-decrement-edi/imm32/next +17530 _Primitive-decrement-edi: # (payload primitive) +17531 0x11/imm32/alloc-id:fake:payload +17532 # var/edi <- decrement => 4f/decrement-edi +17533 0x11/imm32/alloc-id:fake +17534 _string-decrement/imm32/name +17535 0/imm32/no-inouts +17536 0/imm32/no-inouts +17537 0x11/imm32/alloc-id:fake +17538 Single-int-var-in-edi/imm32/outputs +17539 0x11/imm32/alloc-id:fake +17540 _string_4f_decrement_edi/imm32/subx-name +17541 0/imm32/no-rm32 +17542 0/imm32/no-r32 +17543 0/imm32/no-imm32 +17544 0/imm32/no-imm8 +17545 0/imm32/no-disp32 +17546 0/imm32/output-is-write-only +17547 0x11/imm32/alloc-id:fake +17548 _Primitive-increment-mem/imm32/next +17549 _Primitive-increment-mem: # (payload primitive) +17550 0x11/imm32/alloc-id:fake:payload +17551 # increment var => ff 0/subop/increment *(ebp+__) +17552 0x11/imm32/alloc-id:fake +17553 _string-increment/imm32/name 17554 0x11/imm32/alloc-id:fake -17555 _string-break-if-</imm32/name -17556 0/imm32/no-inouts -17557 0/imm32/no-inouts -17558 0/imm32/no-outputs -17559 0/imm32/no-outputs -17560 0x11/imm32/alloc-id:fake -17561 _string_0f_8c_jump_break/imm32/subx-name -17562 0/imm32/no-rm32 -17563 0/imm32/no-r32 -17564 0/imm32/no-imm32 -17565 0/imm32/no-imm8 -17566 0/imm32/no-disp32 -17567 0/imm32/no-output -17568 0x11/imm32/alloc-id:fake -17569 _Primitive-break-if->=/imm32/next -17570 _Primitive-break-if->=: # (payload primitive) -17571 0x11/imm32/alloc-id:fake:payload -17572 0x11/imm32/alloc-id:fake -17573 _string-break-if->=/imm32/name +17555 Single-int-var-in-mem/imm32/inouts +17556 0/imm32/no-outputs +17557 0/imm32/no-outputs +17558 0x11/imm32/alloc-id:fake +17559 _string_ff_subop_increment/imm32/subx-name +17560 1/imm32/rm32-is-first-inout +17561 0/imm32/no-r32 +17562 0/imm32/no-imm32 +17563 0/imm32/no-imm8 +17564 0/imm32/no-disp32 +17565 0/imm32/output-is-write-only +17566 0x11/imm32/alloc-id:fake +17567 _Primitive-increment-reg/imm32/next +17568 _Primitive-increment-reg: # (payload primitive) +17569 0x11/imm32/alloc-id:fake:payload +17570 # var/reg <- increment => ff 0/subop/increment %__ +17571 0x11/imm32/alloc-id:fake +17572 _string-increment/imm32/name +17573 0/imm32/no-inouts 17574 0/imm32/no-inouts -17575 0/imm32/no-inouts -17576 0/imm32/no-outputs -17577 0/imm32/no-outputs -17578 0x11/imm32/alloc-id:fake -17579 _string_0f_8d_jump_break/imm32/subx-name -17580 0/imm32/no-rm32 -17581 0/imm32/no-r32 -17582 0/imm32/no-imm32 -17583 0/imm32/no-imm8 -17584 0/imm32/no-disp32 -17585 0/imm32/no-output -17586 0x11/imm32/alloc-id:fake -17587 _Primitive-break-if-<=/imm32/next -17588 _Primitive-break-if-<=: # (payload primitive) -17589 0x11/imm32/alloc-id:fake:payload +17575 0x11/imm32/alloc-id:fake +17576 Single-int-var-in-some-register/imm32/outputs +17577 0x11/imm32/alloc-id:fake +17578 _string_ff_subop_increment/imm32/subx-name +17579 3/imm32/rm32-is-first-output +17580 0/imm32/no-r32 +17581 0/imm32/no-imm32 +17582 0/imm32/no-imm8 +17583 0/imm32/no-disp32 +17584 0/imm32/output-is-write-only +17585 0x11/imm32/alloc-id:fake +17586 _Primitive-decrement-mem/imm32/next +17587 _Primitive-decrement-mem: # (payload primitive) +17588 0x11/imm32/alloc-id:fake:payload +17589 # decrement var => ff 1/subop/decrement *(ebp+__) 17590 0x11/imm32/alloc-id:fake -17591 _string-break-if-<=/imm32/name -17592 0/imm32/no-inouts -17593 0/imm32/no-inouts +17591 _string-decrement/imm32/name +17592 0x11/imm32/alloc-id:fake +17593 Single-int-var-in-mem/imm32/inouts 17594 0/imm32/no-outputs 17595 0/imm32/no-outputs 17596 0x11/imm32/alloc-id:fake -17597 _string_0f_8e_jump_break/imm32/subx-name -17598 0/imm32/no-rm32 +17597 _string_ff_subop_decrement/imm32/subx-name +17598 1/imm32/rm32-is-first-inout 17599 0/imm32/no-r32 17600 0/imm32/no-imm32 17601 0/imm32/no-imm8 17602 0/imm32/no-disp32 -17603 0/imm32/no-output +17603 0/imm32/output-is-write-only 17604 0x11/imm32/alloc-id:fake -17605 _Primitive-break-if->/imm32/next -17606 _Primitive-break-if->: # (payload primitive) +17605 _Primitive-decrement-reg/imm32/next +17606 _Primitive-decrement-reg: # (payload primitive) 17607 0x11/imm32/alloc-id:fake:payload -17608 0x11/imm32/alloc-id:fake -17609 _string-break-if->/imm32/name -17610 0/imm32/no-inouts +17608 # var/reg <- decrement => ff 1/subop/decrement %__ +17609 0x11/imm32/alloc-id:fake +17610 _string-decrement/imm32/name 17611 0/imm32/no-inouts -17612 0/imm32/no-outputs -17613 0/imm32/no-outputs -17614 0x11/imm32/alloc-id:fake -17615 _string_0f_8f_jump_break/imm32/subx-name -17616 0/imm32/no-rm32 -17617 0/imm32/no-r32 -17618 0/imm32/no-imm32 -17619 0/imm32/no-imm8 -17620 0/imm32/no-disp32 -17621 0/imm32/no-output -17622 0x11/imm32/alloc-id:fake -17623 _Primitive-break/imm32/next -17624 _Primitive-break: # (payload primitive) -17625 0x11/imm32/alloc-id:fake:payload -17626 0x11/imm32/alloc-id:fake -17627 _string-break/imm32/name -17628 0/imm32/no-inouts -17629 0/imm32/no-inouts -17630 0/imm32/no-outputs -17631 0/imm32/no-outputs -17632 0x11/imm32/alloc-id:fake -17633 _string_e9_jump_break/imm32/subx-name -17634 0/imm32/no-rm32 -17635 0/imm32/no-r32 -17636 0/imm32/no-imm32 -17637 0/imm32/no-imm8 -17638 0/imm32/no-disp32 -17639 0/imm32/no-output -17640 0x11/imm32/alloc-id:fake -17641 _Primitive-loop-if-addr</imm32/next -17642 _Primitive-loop-if-addr<: # (payload primitive) -17643 0x11/imm32/alloc-id:fake:payload -17644 0x11/imm32/alloc-id:fake -17645 _string-loop-if-addr</imm32/name -17646 0/imm32/no-inouts -17647 0/imm32/no-inouts -17648 0/imm32/no-outputs -17649 0/imm32/no-outputs +17612 0/imm32/no-inouts +17613 0x11/imm32/alloc-id:fake +17614 Single-int-var-in-some-register/imm32/outputs +17615 0x11/imm32/alloc-id:fake +17616 _string_ff_subop_decrement/imm32/subx-name +17617 3/imm32/rm32-is-first-output +17618 0/imm32/no-r32 +17619 0/imm32/no-imm32 +17620 0/imm32/no-imm8 +17621 0/imm32/no-disp32 +17622 0/imm32/output-is-write-only +17623 0x11/imm32/alloc-id:fake +17624 _Primitive-add-to-eax/imm32/next +17625 # - add +17626 _Primitive-add-to-eax: # (payload primitive) +17627 0x11/imm32/alloc-id:fake:payload +17628 # var/eax <- add lit => 05/add-to-eax lit/imm32 +17629 0x11/imm32/alloc-id:fake +17630 _string-add/imm32/name +17631 0x11/imm32/alloc-id:fake +17632 Single-lit-var/imm32/inouts +17633 0x11/imm32/alloc-id:fake +17634 Single-int-var-in-eax/imm32/outputs +17635 0x11/imm32/alloc-id:fake +17636 _string_05_add_to_eax/imm32/subx-name +17637 0/imm32/no-rm32 +17638 0/imm32/no-r32 +17639 1/imm32/imm32-is-first-inout +17640 0/imm32/no-imm8 +17641 0/imm32/no-disp32 +17642 0/imm32/output-is-write-only +17643 0x11/imm32/alloc-id:fake +17644 _Primitive-add-reg-to-reg/imm32/next +17645 _Primitive-add-reg-to-reg: # (payload primitive) +17646 0x11/imm32/alloc-id:fake:payload +17647 # var1/reg <- add var2/reg => 01/add-to var1/rm32 var2/r32 +17648 0x11/imm32/alloc-id:fake +17649 _string-add/imm32/name 17650 0x11/imm32/alloc-id:fake -17651 _string_0f_82_jump_loop/imm32/subx-name -17652 0/imm32/no-rm32 -17653 0/imm32/no-r32 -17654 0/imm32/no-imm32 -17655 0/imm32/no-imm8 -17656 0/imm32/no-disp32 -17657 0/imm32/no-output -17658 0x11/imm32/alloc-id:fake -17659 _Primitive-loop-if-addr>=/imm32/next -17660 _Primitive-loop-if-addr>=: # (payload primitive) -17661 0x11/imm32/alloc-id:fake:payload +17651 Single-int-var-in-some-register/imm32/inouts +17652 0x11/imm32/alloc-id:fake +17653 Single-int-var-in-some-register/imm32/outputs +17654 0x11/imm32/alloc-id:fake +17655 _string_01_add_to/imm32/subx-name +17656 3/imm32/rm32-is-first-output +17657 1/imm32/r32-is-first-inout +17658 0/imm32/no-imm32 +17659 0/imm32/no-imm8 +17660 0/imm32/no-disp32 +17661 0/imm32/output-is-write-only 17662 0x11/imm32/alloc-id:fake -17663 _string-loop-if-addr>=/imm32/name -17664 0/imm32/no-inouts -17665 0/imm32/no-inouts -17666 0/imm32/no-outputs -17667 0/imm32/no-outputs -17668 0x11/imm32/alloc-id:fake -17669 _string_0f_83_jump_loop/imm32/subx-name -17670 0/imm32/no-rm32 -17671 0/imm32/no-r32 -17672 0/imm32/no-imm32 -17673 0/imm32/no-imm8 -17674 0/imm32/no-disp32 -17675 0/imm32/no-output -17676 0x11/imm32/alloc-id:fake -17677 _Primitive-loop-if-=/imm32/next -17678 _Primitive-loop-if-=: # (payload primitive) -17679 0x11/imm32/alloc-id:fake:payload -17680 0x11/imm32/alloc-id:fake -17681 _string-loop-if-=/imm32/name -17682 0/imm32/no-inouts -17683 0/imm32/no-inouts -17684 0/imm32/no-outputs -17685 0/imm32/no-outputs +17663 _Primitive-add-reg-to-mem/imm32/next +17664 _Primitive-add-reg-to-mem: # (payload primitive) +17665 0x11/imm32/alloc-id:fake:payload +17666 # add-to var1 var2/reg => 01/add-to var1 var2/r32 +17667 0x11/imm32/alloc-id:fake +17668 _string-add-to/imm32/name +17669 0x11/imm32/alloc-id:fake +17670 Two-args-int-stack-int-reg/imm32/inouts +17671 0/imm32/no-outputs +17672 0/imm32/no-outputs +17673 0x11/imm32/alloc-id:fake +17674 _string_01_add_to/imm32/subx-name +17675 1/imm32/rm32-is-first-inout +17676 2/imm32/r32-is-second-inout +17677 0/imm32/no-imm32 +17678 0/imm32/no-imm8 +17679 0/imm32/no-disp32 +17680 0/imm32/output-is-write-only +17681 0x11/imm32/alloc-id:fake +17682 _Primitive-add-mem-to-reg/imm32/next +17683 _Primitive-add-mem-to-reg: # (payload primitive) +17684 0x11/imm32/alloc-id:fake:payload +17685 # var1/reg <- add var2 => 03/add var2/rm32 var1/r32 17686 0x11/imm32/alloc-id:fake -17687 _string_0f_84_jump_loop/imm32/subx-name -17688 0/imm32/no-rm32 -17689 0/imm32/no-r32 -17690 0/imm32/no-imm32 -17691 0/imm32/no-imm8 -17692 0/imm32/no-disp32 -17693 0/imm32/no-output -17694 0x11/imm32/alloc-id:fake -17695 _Primitive-loop-if-!=/imm32/next -17696 _Primitive-loop-if-!=: # (payload primitive) -17697 0x11/imm32/alloc-id:fake:payload -17698 0x11/imm32/alloc-id:fake -17699 _string-loop-if-!=/imm32/name -17700 0/imm32/no-inouts -17701 0/imm32/no-inouts -17702 0/imm32/no-outputs -17703 0/imm32/no-outputs -17704 0x11/imm32/alloc-id:fake -17705 _string_0f_85_jump_loop/imm32/subx-name -17706 0/imm32/no-rm32 -17707 0/imm32/no-r32 -17708 0/imm32/no-imm32 -17709 0/imm32/no-imm8 -17710 0/imm32/no-disp32 -17711 0/imm32/no-output -17712 0x11/imm32/alloc-id:fake -17713 _Primitive-loop-if-addr<=/imm32/next -17714 _Primitive-loop-if-addr<=: # (payload primitive) -17715 0x11/imm32/alloc-id:fake:payload -17716 0x11/imm32/alloc-id:fake -17717 _string-loop-if-addr<=/imm32/name -17718 0/imm32/no-inouts -17719 0/imm32/no-inouts -17720 0/imm32/no-outputs -17721 0/imm32/no-outputs -17722 0x11/imm32/alloc-id:fake -17723 _string_0f_86_jump_loop/imm32/subx-name -17724 0/imm32/no-rm32 -17725 0/imm32/no-r32 -17726 0/imm32/no-imm32 -17727 0/imm32/no-imm8 -17728 0/imm32/no-disp32 -17729 0/imm32/no-output +17687 _string-add/imm32/name +17688 0x11/imm32/alloc-id:fake +17689 Single-int-var-in-mem/imm32/inouts +17690 0x11/imm32/alloc-id:fake +17691 Single-int-var-in-some-register/imm32/outputs +17692 0x11/imm32/alloc-id:fake +17693 _string_03_add/imm32/subx-name +17694 1/imm32/rm32-is-first-inout +17695 3/imm32/r32-is-first-output +17696 0/imm32/no-imm32 +17697 0/imm32/no-imm8 +17698 0/imm32/no-disp32 +17699 0/imm32/output-is-write-only +17700 0x11/imm32/alloc-id:fake +17701 _Primitive-add-lit-to-reg/imm32/next +17702 _Primitive-add-lit-to-reg: # (payload primitive) +17703 0x11/imm32/alloc-id:fake:payload +17704 # var1/reg <- add lit => 81 0/subop/add var1/rm32 lit/imm32 +17705 0x11/imm32/alloc-id:fake +17706 _string-add/imm32/name +17707 0x11/imm32/alloc-id:fake +17708 Single-lit-var/imm32/inouts +17709 0x11/imm32/alloc-id:fake +17710 Single-int-var-in-some-register/imm32/outputs +17711 0x11/imm32/alloc-id:fake +17712 _string_81_subop_add/imm32/subx-name +17713 3/imm32/rm32-is-first-output +17714 0/imm32/no-r32 +17715 1/imm32/imm32-is-first-inout +17716 0/imm32/no-imm8 +17717 0/imm32/no-disp32 +17718 0/imm32/output-is-write-only +17719 0x11/imm32/alloc-id:fake +17720 _Primitive-add-lit-to-mem/imm32/next +17721 _Primitive-add-lit-to-mem: # (payload primitive) +17722 0x11/imm32/alloc-id:fake:payload +17723 # add-to var1, lit => 81 0/subop/add var1/rm32 lit/imm32 +17724 0x11/imm32/alloc-id:fake +17725 _string-add-to/imm32/name +17726 0x11/imm32/alloc-id:fake +17727 Int-var-and-literal/imm32/inouts +17728 0/imm32/no-outputs +17729 0/imm32/no-outputs 17730 0x11/imm32/alloc-id:fake -17731 _Primitive-loop-if-addr>/imm32/next -17732 _Primitive-loop-if-addr>: # (payload primitive) -17733 0x11/imm32/alloc-id:fake:payload -17734 0x11/imm32/alloc-id:fake -17735 _string-loop-if-addr>/imm32/name -17736 0/imm32/no-inouts -17737 0/imm32/no-inouts -17738 0/imm32/no-outputs -17739 0/imm32/no-outputs -17740 0x11/imm32/alloc-id:fake -17741 _string_0f_87_jump_loop/imm32/subx-name -17742 0/imm32/no-rm32 -17743 0/imm32/no-r32 -17744 0/imm32/no-imm32 -17745 0/imm32/no-imm8 -17746 0/imm32/no-disp32 -17747 0/imm32/no-output +17731 _string_81_subop_add/imm32/subx-name +17732 1/imm32/rm32-is-first-inout +17733 0/imm32/no-r32 +17734 2/imm32/imm32-is-second-inout +17735 0/imm32/no-imm8 +17736 0/imm32/no-disp32 +17737 0/imm32/output-is-write-only +17738 0x11/imm32/alloc-id:fake +17739 _Primitive-subtract-from-eax/imm32/next +17740 # - subtract +17741 _Primitive-subtract-from-eax: # (payload primitive) +17742 0x11/imm32/alloc-id:fake:payload +17743 # var/eax <- subtract lit => 2d/subtract-from-eax lit/imm32 +17744 0x11/imm32/alloc-id:fake +17745 _string-subtract/imm32/name +17746 0x11/imm32/alloc-id:fake +17747 Single-lit-var/imm32/inouts 17748 0x11/imm32/alloc-id:fake -17749 _Primitive-loop-if-</imm32/next -17750 _Primitive-loop-if-<: # (payload primitive) -17751 0x11/imm32/alloc-id:fake:payload -17752 0x11/imm32/alloc-id:fake -17753 _string-loop-if-</imm32/name -17754 0/imm32/no-inouts -17755 0/imm32/no-inouts -17756 0/imm32/no-outputs -17757 0/imm32/no-outputs +17749 Single-int-var-in-eax/imm32/outputs +17750 0x11/imm32/alloc-id:fake +17751 _string_2d_subtract_from_eax/imm32/subx-name +17752 0/imm32/no-rm32 +17753 0/imm32/no-r32 +17754 1/imm32/imm32-is-first-inout +17755 0/imm32/no-imm8 +17756 0/imm32/no-disp32 +17757 0/imm32/output-is-write-only 17758 0x11/imm32/alloc-id:fake -17759 _string_0f_8c_jump_loop/imm32/subx-name -17760 0/imm32/no-rm32 -17761 0/imm32/no-r32 -17762 0/imm32/no-imm32 -17763 0/imm32/no-imm8 -17764 0/imm32/no-disp32 -17765 0/imm32/no-output -17766 0x11/imm32/alloc-id:fake -17767 _Primitive-loop-if->=/imm32/next -17768 _Primitive-loop-if->=: # (payload primitive) -17769 0x11/imm32/alloc-id:fake:payload -17770 0x11/imm32/alloc-id:fake -17771 _string-loop-if->=/imm32/name -17772 0/imm32/no-inouts -17773 0/imm32/no-inouts -17774 0/imm32/no-outputs -17775 0/imm32/no-outputs -17776 0x11/imm32/alloc-id:fake -17777 _string_0f_8d_jump_loop/imm32/subx-name -17778 0/imm32/no-rm32 -17779 0/imm32/no-r32 -17780 0/imm32/no-imm32 -17781 0/imm32/no-imm8 -17782 0/imm32/no-disp32 -17783 0/imm32/no-output +17759 _Primitive-subtract-reg-from-reg/imm32/next +17760 _Primitive-subtract-reg-from-reg: # (payload primitive) +17761 0x11/imm32/alloc-id:fake:payload +17762 # var1/reg <- subtract var2/reg => 29/subtract-from var1/rm32 var2/r32 +17763 0x11/imm32/alloc-id:fake +17764 _string-subtract/imm32/name +17765 0x11/imm32/alloc-id:fake +17766 Single-int-var-in-some-register/imm32/inouts +17767 0x11/imm32/alloc-id:fake +17768 Single-int-var-in-some-register/imm32/outputs +17769 0x11/imm32/alloc-id:fake +17770 _string_29_subtract_from/imm32/subx-name +17771 3/imm32/rm32-is-first-output +17772 1/imm32/r32-is-first-inout +17773 0/imm32/no-imm32 +17774 0/imm32/no-imm8 +17775 0/imm32/no-disp32 +17776 0/imm32/output-is-write-only +17777 0x11/imm32/alloc-id:fake +17778 _Primitive-subtract-reg-from-mem/imm32/next +17779 _Primitive-subtract-reg-from-mem: # (payload primitive) +17780 0x11/imm32/alloc-id:fake:payload +17781 # subtract-from var1 var2/reg => 29/subtract-from var1 var2/r32 +17782 0x11/imm32/alloc-id:fake +17783 _string-subtract-from/imm32/name 17784 0x11/imm32/alloc-id:fake -17785 _Primitive-loop-if-<=/imm32/next -17786 _Primitive-loop-if-<=: # (payload primitive) -17787 0x11/imm32/alloc-id:fake:payload +17785 Two-args-int-stack-int-reg/imm32/inouts +17786 0/imm32/no-outputs +17787 0/imm32/no-outputs 17788 0x11/imm32/alloc-id:fake -17789 _string-loop-if-<=/imm32/name -17790 0/imm32/no-inouts -17791 0/imm32/no-inouts -17792 0/imm32/no-outputs -17793 0/imm32/no-outputs -17794 0x11/imm32/alloc-id:fake -17795 _string_0f_8e_jump_loop/imm32/subx-name -17796 0/imm32/no-rm32 -17797 0/imm32/no-r32 -17798 0/imm32/no-imm32 -17799 0/imm32/no-imm8 -17800 0/imm32/no-disp32 -17801 0/imm32/no-output -17802 0x11/imm32/alloc-id:fake -17803 _Primitive-loop-if->/imm32/next -17804 _Primitive-loop-if->: # (payload primitive) -17805 0x11/imm32/alloc-id:fake:payload -17806 0x11/imm32/alloc-id:fake -17807 _string-loop-if->/imm32/name -17808 0/imm32/no-inouts -17809 0/imm32/no-inouts -17810 0/imm32/no-outputs -17811 0/imm32/no-outputs -17812 0x11/imm32/alloc-id:fake -17813 _string_0f_8f_jump_loop/imm32/subx-name -17814 0/imm32/no-rm32 -17815 0/imm32/no-r32 -17816 0/imm32/no-imm32 -17817 0/imm32/no-imm8 -17818 0/imm32/no-disp32 -17819 0/imm32/no-output +17789 _string_29_subtract_from/imm32/subx-name +17790 1/imm32/rm32-is-first-inout +17791 2/imm32/r32-is-second-inout +17792 0/imm32/no-imm32 +17793 0/imm32/no-imm8 +17794 0/imm32/no-disp32 +17795 0/imm32/output-is-write-only +17796 0x11/imm32/alloc-id:fake +17797 _Primitive-subtract-mem-from-reg/imm32/next +17798 _Primitive-subtract-mem-from-reg: # (payload primitive) +17799 0x11/imm32/alloc-id:fake:payload +17800 # var1/reg <- subtract var2 => 2b/subtract var2/rm32 var1/r32 +17801 0x11/imm32/alloc-id:fake +17802 _string-subtract/imm32/name +17803 0x11/imm32/alloc-id:fake +17804 Single-int-var-in-mem/imm32/inouts +17805 0x11/imm32/alloc-id:fake +17806 Single-int-var-in-some-register/imm32/outputs +17807 0x11/imm32/alloc-id:fake +17808 _string_2b_subtract/imm32/subx-name +17809 1/imm32/rm32-is-first-inout +17810 3/imm32/r32-is-first-output +17811 0/imm32/no-imm32 +17812 0/imm32/no-imm8 +17813 0/imm32/no-disp32 +17814 0/imm32/output-is-write-only +17815 0x11/imm32/alloc-id:fake +17816 _Primitive-subtract-lit-from-reg/imm32/next +17817 _Primitive-subtract-lit-from-reg: # (payload primitive) +17818 0x11/imm32/alloc-id:fake:payload +17819 # var1/reg <- subtract lit => 81 5/subop/subtract var1/rm32 lit/imm32 17820 0x11/imm32/alloc-id:fake -17821 _Primitive-loop/imm32/next # we probably don't need an unconditional break -17822 _Primitive-loop: # (payload primitive) -17823 0x11/imm32/alloc-id:fake:payload +17821 _string-subtract/imm32/name +17822 0x11/imm32/alloc-id:fake +17823 Single-lit-var/imm32/inouts 17824 0x11/imm32/alloc-id:fake -17825 _string-loop/imm32/name -17826 0/imm32/no-inouts -17827 0/imm32/no-inouts -17828 0/imm32/no-outputs -17829 0/imm32/no-outputs -17830 0x11/imm32/alloc-id:fake -17831 _string_e9_jump_loop/imm32/subx-name -17832 0/imm32/no-rm32 -17833 0/imm32/no-r32 -17834 0/imm32/no-imm32 -17835 0/imm32/no-imm8 -17836 0/imm32/no-disp32 -17837 0/imm32/no-output -17838 0x11/imm32/alloc-id:fake -17839 _Primitive-break-if-addr<-named/imm32/next -17840 # - branches to named blocks -17841 _Primitive-break-if-addr<-named: # (payload primitive) -17842 0x11/imm32/alloc-id:fake:payload -17843 0x11/imm32/alloc-id:fake -17844 _string-break-if-addr</imm32/name +17825 Single-int-var-in-some-register/imm32/outputs +17826 0x11/imm32/alloc-id:fake +17827 _string_81_subop_subtract/imm32/subx-name +17828 3/imm32/rm32-is-first-output +17829 0/imm32/no-r32 +17830 1/imm32/imm32-is-first-inout +17831 0/imm32/no-imm8 +17832 0/imm32/no-disp32 +17833 0/imm32/output-is-write-only +17834 0x11/imm32/alloc-id:fake +17835 _Primitive-subtract-lit-from-mem/imm32/next +17836 _Primitive-subtract-lit-from-mem: # (payload primitive) +17837 0x11/imm32/alloc-id:fake:payload +17838 # subtract-from var1, lit => 81 5/subop/subtract var1/rm32 lit/imm32 +17839 0x11/imm32/alloc-id:fake +17840 _string-subtract-from/imm32/name +17841 0x11/imm32/alloc-id:fake +17842 Int-var-and-literal/imm32/inouts +17843 0/imm32/no-outputs +17844 0/imm32/no-outputs 17845 0x11/imm32/alloc-id:fake -17846 Single-lit-var/imm32/inouts -17847 0/imm32/no-outputs -17848 0/imm32/no-outputs -17849 0x11/imm32/alloc-id:fake -17850 _string_0f_82_jump_label/imm32/subx-name -17851 0/imm32/no-rm32 -17852 0/imm32/no-r32 -17853 0/imm32/no-imm32 -17854 0/imm32/no-imm8 -17855 1/imm32/disp32-is-first-inout -17856 0/imm32/no-output -17857 0x11/imm32/alloc-id:fake -17858 _Primitive-break-if-addr>=-named/imm32/next -17859 _Primitive-break-if-addr>=-named: # (payload primitive) -17860 0x11/imm32/alloc-id:fake:payload +17846 _string_81_subop_subtract/imm32/subx-name +17847 1/imm32/rm32-is-first-inout +17848 0/imm32/no-r32 +17849 2/imm32/imm32-is-second-inout +17850 0/imm32/no-imm8 +17851 0/imm32/no-disp32 +17852 0/imm32/output-is-write-only +17853 0x11/imm32/alloc-id:fake +17854 _Primitive-and-with-eax/imm32/next +17855 # - and +17856 _Primitive-and-with-eax: # (payload primitive) +17857 0x11/imm32/alloc-id:fake:payload +17858 # var/eax <- and lit => 25/and-with-eax lit/imm32 +17859 0x11/imm32/alloc-id:fake +17860 _string-and/imm32/name 17861 0x11/imm32/alloc-id:fake -17862 _string-break-if-addr>=/imm32/name +17862 Single-lit-var/imm32/inouts 17863 0x11/imm32/alloc-id:fake -17864 Single-lit-var/imm32/inouts -17865 0/imm32/no-outputs -17866 0/imm32/no-outputs -17867 0x11/imm32/alloc-id:fake -17868 _string_0f_83_jump_label/imm32/subx-name -17869 0/imm32/no-rm32 -17870 0/imm32/no-r32 -17871 0/imm32/no-imm32 -17872 0/imm32/no-imm8 -17873 1/imm32/disp32-is-first-inout -17874 0/imm32/no-output -17875 0x11/imm32/alloc-id:fake -17876 _Primitive-break-if-=-named/imm32/next -17877 _Primitive-break-if-=-named: # (payload primitive) -17878 0x11/imm32/alloc-id:fake:payload -17879 0x11/imm32/alloc-id:fake -17880 _string-break-if-=/imm32/name -17881 0x11/imm32/alloc-id:fake -17882 Single-lit-var/imm32/inouts -17883 0/imm32/no-outputs -17884 0/imm32/no-outputs -17885 0x11/imm32/alloc-id:fake -17886 _string_0f_84_jump_label/imm32/subx-name -17887 0/imm32/no-rm32 -17888 0/imm32/no-r32 -17889 0/imm32/no-imm32 -17890 0/imm32/no-imm8 -17891 1/imm32/disp32-is-first-inout -17892 0/imm32/no-output -17893 0x11/imm32/alloc-id:fake -17894 _Primitive-break-if-!=-named/imm32/next -17895 _Primitive-break-if-!=-named: # (payload primitive) -17896 0x11/imm32/alloc-id:fake:payload +17864 Single-int-var-in-eax/imm32/outputs +17865 0x11/imm32/alloc-id:fake +17866 _string_25_and_with_eax/imm32/subx-name +17867 0/imm32/no-rm32 +17868 0/imm32/no-r32 +17869 1/imm32/imm32-is-first-inout +17870 0/imm32/no-imm8 +17871 0/imm32/no-disp32 +17872 0/imm32/output-is-write-only +17873 0x11/imm32/alloc-id:fake +17874 _Primitive-and-reg-with-reg/imm32/next +17875 _Primitive-and-reg-with-reg: # (payload primitive) +17876 0x11/imm32/alloc-id:fake:payload +17877 # var1/reg <- and var2/reg => 21/and-with var1/rm32 var2/r32 +17878 0x11/imm32/alloc-id:fake +17879 _string-and/imm32/name +17880 0x11/imm32/alloc-id:fake +17881 Single-int-var-in-some-register/imm32/inouts +17882 0x11/imm32/alloc-id:fake +17883 Single-int-var-in-some-register/imm32/outputs +17884 0x11/imm32/alloc-id:fake +17885 _string_21_and_with/imm32/subx-name +17886 3/imm32/rm32-is-first-output +17887 1/imm32/r32-is-first-inout +17888 0/imm32/no-imm32 +17889 0/imm32/no-imm8 +17890 0/imm32/no-disp32 +17891 0/imm32/output-is-write-only +17892 0x11/imm32/alloc-id:fake +17893 _Primitive-and-reg-with-mem/imm32/next +17894 _Primitive-and-reg-with-mem: # (payload primitive) +17895 0x11/imm32/alloc-id:fake:payload +17896 # and-with var1 var2/reg => 21/and-with var1 var2/r32 17897 0x11/imm32/alloc-id:fake -17898 _string-break-if-!=/imm32/name +17898 _string-and-with/imm32/name 17899 0x11/imm32/alloc-id:fake -17900 Single-lit-var/imm32/inouts +17900 Two-args-int-stack-int-reg/imm32/inouts 17901 0/imm32/no-outputs 17902 0/imm32/no-outputs 17903 0x11/imm32/alloc-id:fake -17904 _string_0f_85_jump_label/imm32/subx-name -17905 0/imm32/no-rm32 -17906 0/imm32/no-r32 +17904 _string_21_and_with/imm32/subx-name +17905 1/imm32/rm32-is-first-inout +17906 2/imm32/r32-is-second-inout 17907 0/imm32/no-imm32 17908 0/imm32/no-imm8 -17909 1/imm32/disp32-is-first-inout -17910 0/imm32/no-output +17909 0/imm32/no-disp32 +17910 0/imm32/output-is-write-only 17911 0x11/imm32/alloc-id:fake -17912 _Primitive-break-if-addr<=-named/imm32/next -17913 _Primitive-break-if-addr<=-named: # (payload primitive) +17912 _Primitive-and-mem-with-reg/imm32/next +17913 _Primitive-and-mem-with-reg: # (payload primitive) 17914 0x11/imm32/alloc-id:fake:payload -17915 0x11/imm32/alloc-id:fake -17916 _string-break-if-addr<=/imm32/name -17917 0x11/imm32/alloc-id:fake -17918 Single-lit-var/imm32/inouts -17919 0/imm32/no-outputs -17920 0/imm32/no-outputs -17921 0x11/imm32/alloc-id:fake -17922 _string_0f_86_jump_label/imm32/subx-name -17923 0/imm32/no-rm32 -17924 0/imm32/no-r32 -17925 0/imm32/no-imm32 -17926 0/imm32/no-imm8 -17927 1/imm32/disp32-is-first-inout -17928 0/imm32/no-output -17929 0x11/imm32/alloc-id:fake -17930 _Primitive-break-if-addr>-named/imm32/next -17931 _Primitive-break-if-addr>-named: # (payload primitive) -17932 0x11/imm32/alloc-id:fake:payload -17933 0x11/imm32/alloc-id:fake -17934 _string-break-if-addr>/imm32/name +17915 # var1/reg <- and var2 => 23/and var2/rm32 var1/r32 +17916 0x11/imm32/alloc-id:fake +17917 _string-and/imm32/name +17918 0x11/imm32/alloc-id:fake +17919 Single-int-var-in-mem/imm32/inouts +17920 0x11/imm32/alloc-id:fake +17921 Single-int-var-in-some-register/imm32/outputs +17922 0x11/imm32/alloc-id:fake +17923 _string_23_and/imm32/subx-name +17924 1/imm32/rm32-is-first-inout +17925 3/imm32/r32-is-first-output +17926 0/imm32/no-imm32 +17927 0/imm32/no-imm8 +17928 0/imm32/no-disp32 +17929 0/imm32/output-is-write-only +17930 0x11/imm32/alloc-id:fake +17931 _Primitive-and-lit-with-reg/imm32/next +17932 _Primitive-and-lit-with-reg: # (payload primitive) +17933 0x11/imm32/alloc-id:fake:payload +17934 # var1/reg <- and lit => 81 4/subop/and var1/rm32 lit/imm32 17935 0x11/imm32/alloc-id:fake -17936 Single-lit-var/imm32/inouts -17937 0/imm32/no-outputs -17938 0/imm32/no-outputs +17936 _string-and/imm32/name +17937 0x11/imm32/alloc-id:fake +17938 Single-lit-var/imm32/inouts 17939 0x11/imm32/alloc-id:fake -17940 _string_0f_87_jump_label/imm32/subx-name -17941 0/imm32/no-rm32 -17942 0/imm32/no-r32 -17943 0/imm32/no-imm32 -17944 0/imm32/no-imm8 -17945 1/imm32/disp32-is-first-inout -17946 0/imm32/no-output -17947 0x11/imm32/alloc-id:fake -17948 _Primitive-break-if-<-named/imm32/next -17949 _Primitive-break-if-<-named: # (payload primitive) -17950 0x11/imm32/alloc-id:fake:payload -17951 0x11/imm32/alloc-id:fake -17952 _string-break-if-</imm32/name -17953 0x11/imm32/alloc-id:fake -17954 Single-lit-var/imm32/inouts -17955 0/imm32/no-outputs -17956 0/imm32/no-outputs -17957 0x11/imm32/alloc-id:fake -17958 _string_0f_8c_jump_label/imm32/subx-name -17959 0/imm32/no-rm32 -17960 0/imm32/no-r32 -17961 0/imm32/no-imm32 -17962 0/imm32/no-imm8 -17963 1/imm32/disp32-is-first-inout -17964 0/imm32/no-output -17965 0x11/imm32/alloc-id:fake -17966 _Primitive-break-if->=-named/imm32/next -17967 _Primitive-break-if->=-named: # (payload primitive) -17968 0x11/imm32/alloc-id:fake:payload -17969 0x11/imm32/alloc-id:fake -17970 _string-break-if->=/imm32/name -17971 0x11/imm32/alloc-id:fake -17972 Single-lit-var/imm32/inouts -17973 0/imm32/no-outputs -17974 0/imm32/no-outputs -17975 0x11/imm32/alloc-id:fake -17976 _string_0f_8d_jump_label/imm32/subx-name -17977 0/imm32/no-rm32 -17978 0/imm32/no-r32 -17979 0/imm32/no-imm32 -17980 0/imm32/no-imm8 -17981 1/imm32/disp32-is-first-inout -17982 0/imm32/no-output -17983 0x11/imm32/alloc-id:fake -17984 _Primitive-break-if-<=-named/imm32/next -17985 _Primitive-break-if-<=-named: # (payload primitive) -17986 0x11/imm32/alloc-id:fake:payload -17987 0x11/imm32/alloc-id:fake -17988 _string-break-if-<=/imm32/name -17989 0x11/imm32/alloc-id:fake -17990 Single-lit-var/imm32/inouts -17991 0/imm32/no-outputs -17992 0/imm32/no-outputs +17940 Single-int-var-in-some-register/imm32/outputs +17941 0x11/imm32/alloc-id:fake +17942 _string_81_subop_and/imm32/subx-name +17943 3/imm32/rm32-is-first-output +17944 0/imm32/no-r32 +17945 1/imm32/imm32-is-first-inout +17946 0/imm32/no-imm8 +17947 0/imm32/no-disp32 +17948 0/imm32/output-is-write-only +17949 0x11/imm32/alloc-id:fake +17950 _Primitive-and-lit-with-mem/imm32/next +17951 _Primitive-and-lit-with-mem: # (payload primitive) +17952 0x11/imm32/alloc-id:fake:payload +17953 # and-with var1, lit => 81 4/subop/and var1/rm32 lit/imm32 +17954 0x11/imm32/alloc-id:fake +17955 _string-and-with/imm32/name +17956 0x11/imm32/alloc-id:fake +17957 Int-var-and-literal/imm32/inouts +17958 0/imm32/no-outputs +17959 0/imm32/no-outputs +17960 0x11/imm32/alloc-id:fake +17961 _string_81_subop_and/imm32/subx-name +17962 1/imm32/rm32-is-first-inout +17963 0/imm32/no-r32 +17964 2/imm32/imm32-is-second-inout +17965 0/imm32/no-imm8 +17966 0/imm32/no-disp32 +17967 0/imm32/output-is-write-only +17968 0x11/imm32/alloc-id:fake +17969 _Primitive-or-with-eax/imm32/next +17970 # - or +17971 _Primitive-or-with-eax: # (payload primitive) +17972 0x11/imm32/alloc-id:fake:payload +17973 # var/eax <- or lit => 0d/or-with-eax lit/imm32 +17974 0x11/imm32/alloc-id:fake +17975 _string-or/imm32/name +17976 0x11/imm32/alloc-id:fake +17977 Single-lit-var/imm32/inouts +17978 0x11/imm32/alloc-id:fake +17979 Single-int-var-in-eax/imm32/outputs +17980 0x11/imm32/alloc-id:fake +17981 _string_0d_or_with_eax/imm32/subx-name +17982 0/imm32/no-rm32 +17983 0/imm32/no-r32 +17984 1/imm32/imm32-is-first-inout +17985 0/imm32/no-imm8 +17986 0/imm32/no-disp32 +17987 0/imm32/output-is-write-only +17988 0x11/imm32/alloc-id:fake +17989 _Primitive-or-reg-with-reg/imm32/next +17990 _Primitive-or-reg-with-reg: # (payload primitive) +17991 0x11/imm32/alloc-id:fake:payload +17992 # var1/reg <- or var2/reg => 09/or-with var1/rm32 var2/r32 17993 0x11/imm32/alloc-id:fake -17994 _string_0f_8e_jump_label/imm32/subx-name -17995 0/imm32/no-rm32 -17996 0/imm32/no-r32 -17997 0/imm32/no-imm32 -17998 0/imm32/no-imm8 -17999 1/imm32/disp32-is-first-inout -18000 0/imm32/no-output -18001 0x11/imm32/alloc-id:fake -18002 _Primitive-break-if->-named/imm32/next -18003 _Primitive-break-if->-named: # (payload primitive) -18004 0x11/imm32/alloc-id:fake:payload -18005 0x11/imm32/alloc-id:fake -18006 _string-break-if->/imm32/name +17994 _string-or/imm32/name +17995 0x11/imm32/alloc-id:fake +17996 Single-int-var-in-some-register/imm32/inouts +17997 0x11/imm32/alloc-id:fake +17998 Single-int-var-in-some-register/imm32/outputs +17999 0x11/imm32/alloc-id:fake +18000 _string_09_or_with/imm32/subx-name +18001 3/imm32/rm32-is-first-output +18002 1/imm32/r32-is-first-inout +18003 0/imm32/no-imm32 +18004 0/imm32/no-imm8 +18005 0/imm32/no-disp32 +18006 0/imm32/output-is-write-only 18007 0x11/imm32/alloc-id:fake -18008 Single-lit-var/imm32/inouts -18009 0/imm32/no-outputs -18010 0/imm32/no-outputs -18011 0x11/imm32/alloc-id:fake -18012 _string_0f_8f_jump_label/imm32/subx-name -18013 0/imm32/no-rm32 -18014 0/imm32/no-r32 -18015 0/imm32/no-imm32 -18016 0/imm32/no-imm8 -18017 1/imm32/disp32-is-first-inout -18018 0/imm32/no-output -18019 0x11/imm32/alloc-id:fake -18020 _Primitive-break-named/imm32/next -18021 _Primitive-break-named: # (payload primitive) -18022 0x11/imm32/alloc-id:fake:payload -18023 0x11/imm32/alloc-id:fake -18024 _string-break/imm32/name -18025 0x11/imm32/alloc-id:fake -18026 Single-lit-var/imm32/inouts -18027 0/imm32/no-outputs -18028 0/imm32/no-outputs -18029 0x11/imm32/alloc-id:fake -18030 _string_e9_jump_label/imm32/subx-name -18031 0/imm32/no-rm32 -18032 0/imm32/no-r32 -18033 0/imm32/no-imm32 -18034 0/imm32/no-imm8 -18035 1/imm32/disp32-is-first-inout -18036 0/imm32/no-output +18008 _Primitive-or-reg-with-mem/imm32/next +18009 _Primitive-or-reg-with-mem: # (payload primitive) +18010 0x11/imm32/alloc-id:fake:payload +18011 # or-with var1 var2/reg => 09/or-with var1 var2/r32 +18012 0x11/imm32/alloc-id:fake +18013 _string-or-with/imm32/name +18014 0x11/imm32/alloc-id:fake +18015 Two-args-int-stack-int-reg/imm32/inouts +18016 0/imm32/no-outputs +18017 0/imm32/no-outputs +18018 0x11/imm32/alloc-id:fake +18019 _string_09_or_with/imm32/subx-name +18020 1/imm32/rm32-is-first-inout +18021 2/imm32/r32-is-second-inout +18022 0/imm32/no-imm32 +18023 0/imm32/no-imm8 +18024 0/imm32/no-disp32 +18025 0/imm32/output-is-write-only +18026 0x11/imm32/alloc-id:fake +18027 _Primitive-or-mem-with-reg/imm32/next +18028 _Primitive-or-mem-with-reg: # (payload primitive) +18029 0x11/imm32/alloc-id:fake:payload +18030 # var1/reg <- or var2 => 0b/or var2/rm32 var1/r32 +18031 0x11/imm32/alloc-id:fake +18032 _string-or/imm32/name +18033 0x11/imm32/alloc-id:fake +18034 Single-int-var-in-mem/imm32/inouts +18035 0x11/imm32/alloc-id:fake +18036 Single-int-var-in-some-register/imm32/outputs 18037 0x11/imm32/alloc-id:fake -18038 _Primitive-loop-if-addr<-named/imm32/next -18039 _Primitive-loop-if-addr<-named: # (payload primitive) -18040 0x11/imm32/alloc-id:fake:payload -18041 0x11/imm32/alloc-id:fake -18042 _string-loop-if-addr</imm32/name -18043 0x11/imm32/alloc-id:fake -18044 Single-lit-var/imm32/inouts -18045 0/imm32/no-outputs -18046 0/imm32/no-outputs -18047 0x11/imm32/alloc-id:fake -18048 _string_0f_82_jump_label/imm32/subx-name -18049 0/imm32/no-rm32 -18050 0/imm32/no-r32 -18051 0/imm32/no-imm32 -18052 0/imm32/no-imm8 -18053 1/imm32/disp32-is-first-inout -18054 0/imm32/no-output -18055 0x11/imm32/alloc-id:fake -18056 _Primitive-loop-if-addr>=-named/imm32/next -18057 _Primitive-loop-if-addr>=-named: # (payload primitive) -18058 0x11/imm32/alloc-id:fake:payload -18059 0x11/imm32/alloc-id:fake -18060 _string-loop-if-addr>=/imm32/name -18061 0x11/imm32/alloc-id:fake -18062 Single-lit-var/imm32/inouts -18063 0/imm32/no-outputs -18064 0/imm32/no-outputs -18065 0x11/imm32/alloc-id:fake -18066 _string_0f_83_jump_label/imm32/subx-name -18067 0/imm32/no-rm32 -18068 0/imm32/no-r32 -18069 0/imm32/no-imm32 -18070 0/imm32/no-imm8 -18071 1/imm32/disp32-is-first-inout -18072 0/imm32/no-output -18073 0x11/imm32/alloc-id:fake -18074 _Primitive-loop-if-=-named/imm32/next -18075 _Primitive-loop-if-=-named: # (payload primitive) -18076 0x11/imm32/alloc-id:fake:payload -18077 0x11/imm32/alloc-id:fake -18078 _string-loop-if-=/imm32/name -18079 0x11/imm32/alloc-id:fake -18080 Single-lit-var/imm32/inouts -18081 0/imm32/no-outputs -18082 0/imm32/no-outputs +18038 _string_0b_or/imm32/subx-name +18039 1/imm32/rm32-is-first-inout +18040 3/imm32/r32-is-first-output +18041 0/imm32/no-imm32 +18042 0/imm32/no-imm8 +18043 0/imm32/no-disp32 +18044 0/imm32/output-is-write-only +18045 0x11/imm32/alloc-id:fake +18046 _Primitive-or-lit-with-reg/imm32/next +18047 _Primitive-or-lit-with-reg: # (payload primitive) +18048 0x11/imm32/alloc-id:fake:payload +18049 # var1/reg <- or lit => 81 1/subop/or var1/rm32 lit/imm32 +18050 0x11/imm32/alloc-id:fake +18051 _string-or/imm32/name +18052 0x11/imm32/alloc-id:fake +18053 Single-lit-var/imm32/inouts +18054 0x11/imm32/alloc-id:fake +18055 Single-int-var-in-some-register/imm32/outputs +18056 0x11/imm32/alloc-id:fake +18057 _string_81_subop_or/imm32/subx-name +18058 3/imm32/rm32-is-first-output +18059 0/imm32/no-r32 +18060 1/imm32/imm32-is-first-inout +18061 0/imm32/no-imm8 +18062 0/imm32/no-disp32 +18063 0/imm32/output-is-write-only +18064 0x11/imm32/alloc-id:fake +18065 _Primitive-or-lit-with-mem/imm32/next +18066 _Primitive-or-lit-with-mem: # (payload primitive) +18067 0x11/imm32/alloc-id:fake:payload +18068 # or-with var1, lit => 81 1/subop/or var1/rm32 lit/imm32 +18069 0x11/imm32/alloc-id:fake +18070 _string-or-with/imm32/name +18071 0x11/imm32/alloc-id:fake +18072 Int-var-and-literal/imm32/inouts +18073 0/imm32/no-outputs +18074 0/imm32/no-outputs +18075 0x11/imm32/alloc-id:fake +18076 _string_81_subop_or/imm32/subx-name +18077 1/imm32/rm32-is-first-inout +18078 0/imm32/no-r32 +18079 2/imm32/imm32-is-second-inout +18080 0/imm32/no-imm8 +18081 0/imm32/no-disp32 +18082 0/imm32/output-is-write-only 18083 0x11/imm32/alloc-id:fake -18084 _string_0f_84_jump_label/imm32/subx-name -18085 0/imm32/no-rm32 -18086 0/imm32/no-r32 -18087 0/imm32/no-imm32 -18088 0/imm32/no-imm8 -18089 1/imm32/disp32-is-first-inout -18090 0/imm32/no-output +18084 _Primitive-xor-with-eax/imm32/next +18085 # - xor +18086 _Primitive-xor-with-eax: # (payload primitive) +18087 0x11/imm32/alloc-id:fake:payload +18088 # var/eax <- xor lit => 35/xor-with-eax lit/imm32 +18089 0x11/imm32/alloc-id:fake +18090 _string-xor/imm32/name 18091 0x11/imm32/alloc-id:fake -18092 _Primitive-loop-if-!=-named/imm32/next -18093 _Primitive-loop-if-!=-named: # (payload primitive) -18094 0x11/imm32/alloc-id:fake:payload +18092 Single-lit-var/imm32/inouts +18093 0x11/imm32/alloc-id:fake +18094 Single-int-var-in-eax/imm32/outputs 18095 0x11/imm32/alloc-id:fake -18096 _string-loop-if-!=/imm32/name -18097 0x11/imm32/alloc-id:fake -18098 Single-lit-var/imm32/inouts -18099 0/imm32/no-outputs -18100 0/imm32/no-outputs -18101 0x11/imm32/alloc-id:fake -18102 _string_0f_85_jump_label/imm32/subx-name -18103 0/imm32/no-rm32 -18104 0/imm32/no-r32 -18105 0/imm32/no-imm32 -18106 0/imm32/no-imm8 -18107 1/imm32/disp32-is-first-inout -18108 0/imm32/no-output -18109 0x11/imm32/alloc-id:fake -18110 _Primitive-loop-if-addr<=-named/imm32/next -18111 _Primitive-loop-if-addr<=-named: # (payload primitive) -18112 0x11/imm32/alloc-id:fake:payload -18113 0x11/imm32/alloc-id:fake -18114 _string-loop-if-addr<=/imm32/name -18115 0x11/imm32/alloc-id:fake -18116 Single-lit-var/imm32/inouts -18117 0/imm32/no-outputs -18118 0/imm32/no-outputs -18119 0x11/imm32/alloc-id:fake -18120 _string_0f_86_jump_label/imm32/subx-name -18121 0/imm32/no-rm32 -18122 0/imm32/no-r32 -18123 0/imm32/no-imm32 -18124 0/imm32/no-imm8 -18125 1/imm32/disp32-is-first-inout -18126 0/imm32/no-output +18096 _string_35_xor_with_eax/imm32/subx-name +18097 0/imm32/no-rm32 +18098 0/imm32/no-r32 +18099 1/imm32/imm32-is-first-inout +18100 0/imm32/no-imm8 +18101 0/imm32/no-disp32 +18102 0/imm32/output-is-write-only +18103 0x11/imm32/alloc-id:fake +18104 _Primitive-xor-reg-with-reg/imm32/next +18105 _Primitive-xor-reg-with-reg: # (payload primitive) +18106 0x11/imm32/alloc-id:fake:payload +18107 # var1/reg <- xor var2/reg => 31/xor-with var1/rm32 var2/r32 +18108 0x11/imm32/alloc-id:fake +18109 _string-xor/imm32/name +18110 0x11/imm32/alloc-id:fake +18111 Single-int-var-in-some-register/imm32/inouts +18112 0x11/imm32/alloc-id:fake +18113 Single-int-var-in-some-register/imm32/outputs +18114 0x11/imm32/alloc-id:fake +18115 _string_31_xor_with/imm32/subx-name +18116 3/imm32/rm32-is-first-output +18117 1/imm32/r32-is-first-inout +18118 0/imm32/no-imm32 +18119 0/imm32/no-imm8 +18120 0/imm32/no-disp32 +18121 0/imm32/output-is-write-only +18122 0x11/imm32/alloc-id:fake +18123 _Primitive-xor-reg-with-mem/imm32/next +18124 _Primitive-xor-reg-with-mem: # (payload primitive) +18125 0x11/imm32/alloc-id:fake:payload +18126 # xor-with var1 var2/reg => 31/xor-with var1 var2/r32 18127 0x11/imm32/alloc-id:fake -18128 _Primitive-loop-if-addr>-named/imm32/next -18129 _Primitive-loop-if-addr>-named: # (payload primitive) -18130 0x11/imm32/alloc-id:fake:payload -18131 0x11/imm32/alloc-id:fake -18132 _string-loop-if-addr>/imm32/name +18128 _string-xor-with/imm32/name +18129 0x11/imm32/alloc-id:fake +18130 Two-args-int-stack-int-reg/imm32/inouts +18131 0/imm32/no-outputs +18132 0/imm32/no-outputs 18133 0x11/imm32/alloc-id:fake -18134 Single-lit-var/imm32/inouts -18135 0/imm32/no-outputs -18136 0/imm32/no-outputs -18137 0x11/imm32/alloc-id:fake -18138 _string_0f_87_jump_label/imm32/subx-name -18139 0/imm32/no-rm32 -18140 0/imm32/no-r32 -18141 0/imm32/no-imm32 -18142 0/imm32/no-imm8 -18143 1/imm32/disp32-is-first-inout -18144 0/imm32/no-output -18145 0x11/imm32/alloc-id:fake -18146 _Primitive-loop-if-<-named/imm32/next -18147 _Primitive-loop-if-<-named: # (payload primitive) -18148 0x11/imm32/alloc-id:fake:payload -18149 0x11/imm32/alloc-id:fake -18150 _string-loop-if-</imm32/name -18151 0x11/imm32/alloc-id:fake -18152 Single-lit-var/imm32/inouts -18153 0/imm32/no-outputs -18154 0/imm32/no-outputs -18155 0x11/imm32/alloc-id:fake -18156 _string_0f_8c_jump_label/imm32/subx-name -18157 0/imm32/no-rm32 -18158 0/imm32/no-r32 -18159 0/imm32/no-imm32 -18160 0/imm32/no-imm8 -18161 1/imm32/disp32-is-first-inout -18162 0/imm32/no-output -18163 0x11/imm32/alloc-id:fake -18164 _Primitive-loop-if->=-named/imm32/next -18165 _Primitive-loop-if->=-named: # (payload primitive) -18166 0x11/imm32/alloc-id:fake:payload +18134 _string_31_xor_with/imm32/subx-name +18135 1/imm32/rm32-is-first-inout +18136 2/imm32/r32-is-second-inout +18137 0/imm32/no-imm32 +18138 0/imm32/no-imm8 +18139 0/imm32/no-disp32 +18140 0/imm32/output-is-write-only +18141 0x11/imm32/alloc-id:fake +18142 _Primitive-xor-mem-with-reg/imm32/next +18143 _Primitive-xor-mem-with-reg: # (payload primitive) +18144 0x11/imm32/alloc-id:fake:payload +18145 # var1/reg <- xor var2 => 33/xor var2/rm32 var1/r32 +18146 0x11/imm32/alloc-id:fake +18147 _string-xor/imm32/name +18148 0x11/imm32/alloc-id:fake +18149 Single-int-var-in-mem/imm32/inouts +18150 0x11/imm32/alloc-id:fake +18151 Single-int-var-in-some-register/imm32/outputs +18152 0x11/imm32/alloc-id:fake +18153 _string_33_xor/imm32/subx-name +18154 1/imm32/rm32-is-first-inout +18155 3/imm32/r32-is-first-output +18156 0/imm32/no-imm32 +18157 0/imm32/no-imm8 +18158 0/imm32/no-disp32 +18159 0/imm32/output-is-write-only +18160 0x11/imm32/alloc-id:fake +18161 _Primitive-xor-lit-with-reg/imm32/next +18162 _Primitive-xor-lit-with-reg: # (payload primitive) +18163 0x11/imm32/alloc-id:fake:payload +18164 # var1/reg <- xor lit => 81 6/subop/xor var1/rm32 lit/imm32 +18165 0x11/imm32/alloc-id:fake +18166 _string-xor/imm32/name 18167 0x11/imm32/alloc-id:fake -18168 _string-loop-if->=/imm32/name +18168 Single-lit-var/imm32/inouts 18169 0x11/imm32/alloc-id:fake -18170 Single-lit-var/imm32/inouts -18171 0/imm32/no-outputs -18172 0/imm32/no-outputs -18173 0x11/imm32/alloc-id:fake -18174 _string_0f_8d_jump_label/imm32/subx-name -18175 0/imm32/no-rm32 -18176 0/imm32/no-r32 -18177 0/imm32/no-imm32 -18178 0/imm32/no-imm8 -18179 1/imm32/disp32-is-first-inout -18180 0/imm32/no-output -18181 0x11/imm32/alloc-id:fake -18182 _Primitive-loop-if-<=-named/imm32/next -18183 _Primitive-loop-if-<=-named: # (payload primitive) -18184 0x11/imm32/alloc-id:fake:payload -18185 0x11/imm32/alloc-id:fake -18186 _string-loop-if-<=/imm32/name -18187 0x11/imm32/alloc-id:fake -18188 Single-lit-var/imm32/inouts +18170 Single-int-var-in-some-register/imm32/outputs +18171 0x11/imm32/alloc-id:fake +18172 _string_81_subop_xor/imm32/subx-name +18173 3/imm32/rm32-is-first-output +18174 0/imm32/no-r32 +18175 1/imm32/imm32-is-first-inout +18176 0/imm32/no-imm8 +18177 0/imm32/no-disp32 +18178 0/imm32/output-is-write-only +18179 0x11/imm32/alloc-id:fake +18180 _Primitive-xor-lit-with-mem/imm32/next +18181 _Primitive-xor-lit-with-mem: # (payload primitive) +18182 0x11/imm32/alloc-id:fake:payload +18183 # xor-with var1, lit => 81 6/subop/xor var1/rm32 lit/imm32 +18184 0x11/imm32/alloc-id:fake +18185 _string-xor-with/imm32/name +18186 0x11/imm32/alloc-id:fake +18187 Int-var-and-literal/imm32/inouts +18188 0/imm32/no-outputs 18189 0/imm32/no-outputs -18190 0/imm32/no-outputs -18191 0x11/imm32/alloc-id:fake -18192 _string_0f_8e_jump_label/imm32/subx-name -18193 0/imm32/no-rm32 -18194 0/imm32/no-r32 -18195 0/imm32/no-imm32 -18196 0/imm32/no-imm8 -18197 1/imm32/disp32-is-first-inout -18198 0/imm32/no-output -18199 0x11/imm32/alloc-id:fake -18200 _Primitive-loop-if->-named/imm32/next -18201 _Primitive-loop-if->-named: # (payload primitive) -18202 0x11/imm32/alloc-id:fake:payload +18190 0x11/imm32/alloc-id:fake +18191 _string_81_subop_xor/imm32/subx-name +18192 1/imm32/rm32-is-first-inout +18193 0/imm32/no-r32 +18194 2/imm32/imm32-is-second-inout +18195 0/imm32/no-imm8 +18196 0/imm32/no-disp32 +18197 0/imm32/output-is-write-only +18198 0x11/imm32/alloc-id:fake +18199 _Primitive-shift-reg-left-by-lit/imm32/next +18200 _Primitive-shift-reg-left-by-lit: # (payload primitive) +18201 0x11/imm32/alloc-id:fake:payload +18202 # var1/reg <- shift-left lit => c1/shift 4/subop/left var1/rm32 lit/imm32 18203 0x11/imm32/alloc-id:fake -18204 _string-loop-if->/imm32/name +18204 _string-shift-left/imm32/name 18205 0x11/imm32/alloc-id:fake -18206 Single-lit-var/imm32/inouts -18207 0/imm32/no-outputs -18208 0/imm32/no-outputs +18206 Single-lit-var/imm32/inouts +18207 0x11/imm32/alloc-id:fake +18208 Single-int-var-in-some-register/imm32/outputs 18209 0x11/imm32/alloc-id:fake -18210 _string_0f_8f_jump_label/imm32/subx-name -18211 0/imm32/no-rm32 +18210 _string_c1_subop_shift_left/imm32/subx-name +18211 3/imm32/rm32-is-first-output 18212 0/imm32/no-r32 18213 0/imm32/no-imm32 -18214 0/imm32/no-imm8 -18215 1/imm32/disp32-is-first-inout -18216 0/imm32/no-output +18214 1/imm32/imm8-is-first-inout +18215 0/imm32/no-disp32 +18216 0/imm32/output-is-write-only 18217 0x11/imm32/alloc-id:fake -18218 _Primitive-loop-named/imm32/next # we probably don't need an unconditional break -18219 _Primitive-loop-named: # (payload primitive) +18218 _Primitive-shift-reg-right-by-lit/imm32/next +18219 _Primitive-shift-reg-right-by-lit: # (payload primitive) 18220 0x11/imm32/alloc-id:fake:payload -18221 0x11/imm32/alloc-id:fake -18222 _string-loop/imm32/name -18223 0x11/imm32/alloc-id:fake -18224 Single-lit-var/imm32/inouts -18225 0/imm32/no-outputs -18226 0/imm32/no-outputs -18227 0x11/imm32/alloc-id:fake -18228 _string_e9_jump_label/imm32/subx-name -18229 0/imm32/no-rm32 -18230 0/imm32/no-r32 -18231 0/imm32/no-imm32 -18232 0/imm32/no-imm8 -18233 1/imm32/disp32-is-first-inout -18234 0/imm32/no-output -18235 0/imm32/next -18236 0/imm32/next -18237 -18238 # string literals for Mu instructions -18239 _string-add: # (payload array byte) -18240 0x11/imm32/alloc-id:fake:payload -18241 # "add" -18242 0x3/imm32/size -18243 0x61/a 0x64/d 0x64/d -18244 _string-address: # (payload array byte) -18245 0x11/imm32/alloc-id:fake:payload -18246 # "address" -18247 0x7/imm32/size -18248 0x61/a 0x64/d 0x64/d 0x72/r 0x65/e 0x73/s 0x73/s -18249 _string-add-to: # (payload array byte) -18250 0x11/imm32/alloc-id:fake:payload -18251 # "add-to" -18252 0x6/imm32/size -18253 0x61/a 0x64/d 0x64/d 0x2d/dash 0x74/t 0x6f/o -18254 _string-and: # (payload array byte) -18255 0x11/imm32/alloc-id:fake:payload -18256 # "and" -18257 0x3/imm32/size -18258 0x61/a 0x6e/n 0x64/d -18259 _string-and-with: # (payload array byte) -18260 0x11/imm32/alloc-id:fake:payload -18261 # "and-with" -18262 0x8/imm32/size -18263 0x61/a 0x6e/n 0x64/d 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h -18264 _string-break: # (payload array byte) -18265 0x11/imm32/alloc-id:fake:payload -18266 # "break" -18267 0x5/imm32/size -18268 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k -18269 _string-break-if-<: # (payload array byte) -18270 0x11/imm32/alloc-id:fake:payload -18271 # "break-if-<" -18272 0xa/imm32/size -18273 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/< -18274 _string-break-if-<=: # (payload array byte) -18275 0x11/imm32/alloc-id:fake:payload -18276 # "break-if-<=" -18277 0xb/imm32/size -18278 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/< 0x3d/= -18279 _string-break-if-=: # (payload array byte) -18280 0x11/imm32/alloc-id:fake:payload -18281 # "break-if-=" -18282 0xa/imm32/size -18283 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3d/= -18284 _string-break-if->: # (payload array byte) -18285 0x11/imm32/alloc-id:fake:payload -18286 # "break-if->" -18287 0xa/imm32/size -18288 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/> -18289 _string-break-if->=: # (payload array byte) -18290 0x11/imm32/alloc-id:fake:payload -18291 # "break-if->=" -18292 0xb/imm32/size -18293 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/> 0x3d/= -18294 _string-break-if-!=: # (payload array byte) -18295 0x11/imm32/alloc-id:fake:payload -18296 # "break-if-!=" -18297 0xb/imm32/size -18298 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x21/! 0x3d/= -18299 _string-break-if-addr<: # (payload array byte) -18300 0x11/imm32/alloc-id:fake:payload -18301 # "break-if-addr<" -18302 0xe/imm32/size -18303 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3c/< -18304 _string-break-if-addr<=: # (payload array byte) -18305 0x11/imm32/alloc-id:fake:payload -18306 # "break-if-addr<=" -18307 0xf/imm32/size -18308 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3c/< 0x3d/= -18309 _string-break-if-addr>: # (payload array byte) -18310 0x11/imm32/alloc-id:fake:payload -18311 # "break-if-addr>" -18312 0xe/imm32/size -18313 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3e/> -18314 _string-break-if-addr>=: # (payload array byte) -18315 0x11/imm32/alloc-id:fake:payload -18316 # "break-if-addr>=" -18317 0xf/imm32/size -18318 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3e/> 0x3d/= -18319 _string-compare: # (payload array byte) -18320 0x11/imm32/alloc-id:fake:payload -18321 # "compare" -18322 0x7/imm32/size -18323 0x63/c 0x6f/o 0x6d/m 0x70/p 0x61/a 0x72/r 0x65/e -18324 _string-copy: # (payload array byte) -18325 0x11/imm32/alloc-id:fake:payload -18326 # "copy" -18327 0x4/imm32/size -18328 0x63/c 0x6f/o 0x70/p 0x79/y -18329 _string-copy-to: # (payload array byte) -18330 0x11/imm32/alloc-id:fake:payload -18331 # "copy-to" -18332 0x7/imm32/size -18333 0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/dash 0x74/t 0x6f/o -18334 _string-copy-byte: +18221 # var1/reg <- shift-right lit => c1/shift 5/subop/right var1/rm32 lit/imm32 +18222 0x11/imm32/alloc-id:fake +18223 _string-shift-right/imm32/name +18224 0x11/imm32/alloc-id:fake +18225 Single-lit-var/imm32/inouts +18226 0x11/imm32/alloc-id:fake +18227 Single-int-var-in-some-register/imm32/outputs +18228 0x11/imm32/alloc-id:fake +18229 _string_c1_subop_shift_right_padding_zeroes/imm32/subx-name +18230 3/imm32/rm32-is-first-output +18231 0/imm32/no-r32 +18232 0/imm32/no-imm32 +18233 1/imm32/imm8-is-first-inout +18234 0/imm32/no-disp32 +18235 0/imm32/output-is-write-only +18236 0x11/imm32/alloc-id:fake +18237 _Primitive-shift-reg-right-signed-by-lit/imm32/next +18238 _Primitive-shift-reg-right-signed-by-lit: # (payload primitive) +18239 0x11/imm32/alloc-id:fake:payload +18240 # var1/reg <- shift-right-signed lit => c1/shift 7/subop/right-preserving-sign var1/rm32 lit/imm32 +18241 0x11/imm32/alloc-id:fake +18242 _string-shift-right-signed/imm32/name +18243 0x11/imm32/alloc-id:fake +18244 Single-lit-var/imm32/inouts +18245 0x11/imm32/alloc-id:fake +18246 Single-int-var-in-some-register/imm32/outputs +18247 0x11/imm32/alloc-id:fake +18248 _string_c1_subop_shift_right_preserving_sign/imm32/subx-name +18249 3/imm32/rm32-is-first-output +18250 0/imm32/no-r32 +18251 0/imm32/no-imm32 +18252 1/imm32/imm8-is-first-inout +18253 0/imm32/no-disp32 +18254 0/imm32/output-is-write-only +18255 0x11/imm32/alloc-id:fake +18256 _Primitive-shift-mem-left-by-lit/imm32/next +18257 _Primitive-shift-mem-left-by-lit: # (payload primitive) +18258 0x11/imm32/alloc-id:fake:payload +18259 # shift-left var1, lit => c1/shift 4/subop/left var1/rm32 lit/imm32 +18260 0x11/imm32/alloc-id:fake +18261 _string-shift-left/imm32/name +18262 0x11/imm32/alloc-id:fake +18263 Int-var-and-literal/imm32/inouts +18264 0/imm32/no-outputs +18265 0/imm32/no-outputs +18266 0x11/imm32/alloc-id:fake +18267 _string_c1_subop_shift_left/imm32/subx-name +18268 1/imm32/rm32-is-first-inout +18269 0/imm32/no-r32 +18270 0/imm32/no-imm32 +18271 2/imm32/imm8-is-second-inout +18272 0/imm32/no-disp32 +18273 0/imm32/output-is-write-only +18274 0x11/imm32/alloc-id:fake +18275 _Primitive-shift-mem-right-by-lit/imm32/next +18276 _Primitive-shift-mem-right-by-lit: # (payload primitive) +18277 0x11/imm32/alloc-id:fake:payload +18278 # shift-right var1, lit => c1/shift 5/subop/right var1/rm32 lit/imm32 +18279 0x11/imm32/alloc-id:fake +18280 _string-shift-right/imm32/name +18281 0x11/imm32/alloc-id:fake +18282 Int-var-and-literal/imm32/inouts +18283 0/imm32/no-outputs +18284 0/imm32/no-outputs +18285 0x11/imm32/alloc-id:fake +18286 _string_c1_subop_shift_right_padding_zeroes/imm32/subx-name +18287 1/imm32/rm32-is-first-inout +18288 0/imm32/no-r32 +18289 0/imm32/no-imm32 +18290 2/imm32/imm8-is-second-inout +18291 0/imm32/no-disp32 +18292 0/imm32/output-is-write-only +18293 0x11/imm32/alloc-id:fake +18294 _Primitive-shift-mem-right-signed-by-lit/imm32/next +18295 _Primitive-shift-mem-right-signed-by-lit: # (payload primitive) +18296 0x11/imm32/alloc-id:fake:payload +18297 # shift-right-signed var1, lit => c1/shift 7/subop/right-preserving-sign var1/rm32 lit/imm32 +18298 0x11/imm32/alloc-id:fake +18299 _string-shift-right-signed/imm32/name +18300 0x11/imm32/alloc-id:fake +18301 Int-var-and-literal/imm32/inouts +18302 0/imm32/no-outputs +18303 0/imm32/no-outputs +18304 0x11/imm32/alloc-id:fake +18305 _string_c1_subop_shift_right_preserving_sign/imm32/subx-name +18306 1/imm32/rm32-is-first-inout +18307 0/imm32/no-r32 +18308 0/imm32/no-imm32 +18309 2/imm32/imm8-is-second-inout +18310 0/imm32/no-disp32 +18311 0/imm32/output-is-write-only +18312 0x11/imm32/alloc-id:fake +18313 _Primitive-copy-to-eax/imm32/next +18314 # - copy +18315 _Primitive-copy-to-eax: # (payload primitive) +18316 0x11/imm32/alloc-id:fake:payload +18317 # var/eax <- copy lit => b8/copy-to-eax lit/imm32 +18318 0x11/imm32/alloc-id:fake +18319 _string-copy/imm32/name +18320 0x11/imm32/alloc-id:fake +18321 Single-lit-var/imm32/inouts +18322 0x11/imm32/alloc-id:fake +18323 Single-int-var-in-eax/imm32/outputs +18324 0x11/imm32/alloc-id:fake +18325 _string_b8_copy_to_eax/imm32/subx-name +18326 0/imm32/no-rm32 +18327 0/imm32/no-r32 +18328 1/imm32/imm32-is-first-inout +18329 0/imm32/no-imm8 +18330 0/imm32/no-disp32 +18331 1/imm32/output-is-write-only +18332 0x11/imm32/alloc-id:fake +18333 _Primitive-copy-to-ecx/imm32/next +18334 _Primitive-copy-to-ecx: # (payload primitive) 18335 0x11/imm32/alloc-id:fake:payload -18336 # "copy-byte" -18337 0x9/imm32/size -18338 0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/- 0x62/b 0x79/y 0x74/t 0x65/e -18339 _string-copy-byte-to: -18340 0x11/imm32/alloc-id:fake:payload -18341 # "copy-byte-to" -18342 0xc/imm32/size -18343 0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/- 0x62/b 0x79/y 0x74/t 0x65/e 0x2d/- 0x74/t 0x6f/o -18344 _string-decrement: # (payload array byte) -18345 0x11/imm32/alloc-id:fake:payload -18346 # "decrement" -18347 0x9/imm32/size -18348 0x64/d 0x65/e 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t -18349 _string-increment: # (payload array byte) -18350 0x11/imm32/alloc-id:fake:payload -18351 # "increment" -18352 0x9/imm32/size -18353 0x69/i 0x6e/n 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t -18354 _string-loop: # (payload array byte) -18355 0x11/imm32/alloc-id:fake:payload -18356 # "loop" -18357 0x4/imm32/size -18358 0x6c/l 0x6f/o 0x6f/o 0x70/p -18359 _string-loop-if-<: # (payload array byte) -18360 0x11/imm32/alloc-id:fake:payload -18361 # "loop-if-<" -18362 0x9/imm32/size -18363 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/< -18364 _string-loop-if-<=: # (payload array byte) -18365 0x11/imm32/alloc-id:fake:payload -18366 # "loop-if-<=" -18367 0xa/imm32/size -18368 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/< 0x3d/= -18369 _string-loop-if-=: # (payload array byte) -18370 0x11/imm32/alloc-id:fake:payload -18371 # "loop-if-=" -18372 0x9/imm32/size -18373 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3d/= -18374 _string-loop-if->: # (payload array byte) -18375 0x11/imm32/alloc-id:fake:payload -18376 # "loop-if->" -18377 0x9/imm32/size -18378 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/> -18379 _string-loop-if->=: # (payload array byte) -18380 0x11/imm32/alloc-id:fake:payload -18381 # "loop-if->=" -18382 0xa/imm32/size -18383 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/> 0x3d/= -18384 _string-loop-if-!=: # (payload array byte) -18385 0x11/imm32/alloc-id:fake:payload -18386 # "loop-if-!=" -18387 0xa/imm32/size -18388 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x21/! 0x3d/= -18389 _string-loop-if-addr<: # (payload array byte) -18390 0x11/imm32/alloc-id:fake:payload -18391 # "loop-if-addr<" -18392 0xd/imm32/size -18393 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3c/< -18394 _string-loop-if-addr<=: # (payload array byte) -18395 0x11/imm32/alloc-id:fake:payload -18396 # "loop-if-addr<=" -18397 0xe/imm32/size -18398 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3c/< 0x3d/= -18399 _string-loop-if-addr>: # (payload array byte) -18400 0x11/imm32/alloc-id:fake:payload -18401 # "loop-if-addr>" -18402 0xd/imm32/size -18403 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3e/> -18404 _string-loop-if-addr>=: # (payload array byte) -18405 0x11/imm32/alloc-id:fake:payload -18406 # "loop-if-addr>=" -18407 0xe/imm32/size -18408 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3e/> 0x3d/= -18409 _string-multiply: # (payload array byte) -18410 0x11/imm32/alloc-id:fake:payload -18411 # "multiply" -18412 0x8/imm32/size -18413 0x6d/m 0x75/u 0x6c/l 0x74/t 0x69/i 0x70/p 0x6c/l 0x79/y -18414 _string-or: # (payload array byte) -18415 0x11/imm32/alloc-id:fake:payload -18416 # "or" -18417 0x2/imm32/size -18418 0x6f/o 0x72/r -18419 _string-or-with: # (payload array byte) -18420 0x11/imm32/alloc-id:fake:payload -18421 # "or-with" -18422 0x7/imm32/size -18423 0x6f/o 0x72/r 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h -18424 _string-subtract: # (payload array byte) -18425 0x11/imm32/alloc-id:fake:payload -18426 # "subtract" -18427 0x8/imm32/size -18428 0x73/s 0x75/u 0x62/b 0x74/t 0x72/r 0x61/a 0x63/c 0x74/t -18429 _string-subtract-from: # (payload array byte) +18336 # var/ecx <- copy lit => b9/copy-to-ecx lit/imm32 +18337 0x11/imm32/alloc-id:fake +18338 _string-copy/imm32/name +18339 0x11/imm32/alloc-id:fake +18340 Single-lit-var/imm32/inouts +18341 0x11/imm32/alloc-id:fake +18342 Single-int-var-in-ecx/imm32/outputs +18343 0x11/imm32/alloc-id:fake +18344 _string_b9_copy_to_ecx/imm32/subx-name +18345 0/imm32/no-rm32 +18346 0/imm32/no-r32 +18347 1/imm32/imm32-is-first-inout +18348 0/imm32/no-imm8 +18349 0/imm32/no-disp32 +18350 1/imm32/output-is-write-only +18351 0x11/imm32/alloc-id:fake +18352 _Primitive-copy-to-edx/imm32/next +18353 _Primitive-copy-to-edx: # (payload primitive) +18354 0x11/imm32/alloc-id:fake:payload +18355 # var/edx <- copy lit => ba/copy-to-edx lit/imm32 +18356 0x11/imm32/alloc-id:fake +18357 _string-copy/imm32/name +18358 0x11/imm32/alloc-id:fake +18359 Single-lit-var/imm32/inouts +18360 0x11/imm32/alloc-id:fake +18361 Single-int-var-in-edx/imm32/outputs +18362 0x11/imm32/alloc-id:fake +18363 _string_ba_copy_to_edx/imm32/subx-name +18364 0/imm32/no-rm32 +18365 0/imm32/no-r32 +18366 1/imm32/imm32-is-first-inout +18367 0/imm32/no-imm8 +18368 0/imm32/no-disp32 +18369 1/imm32/output-is-write-only +18370 0x11/imm32/alloc-id:fake +18371 _Primitive-copy-to-ebx/imm32/next +18372 _Primitive-copy-to-ebx: # (payload primitive) +18373 0x11/imm32/alloc-id:fake:payload +18374 # var/ebx <- copy lit => bb/copy-to-ebx lit/imm32 +18375 0x11/imm32/alloc-id:fake +18376 _string-copy/imm32/name +18377 0x11/imm32/alloc-id:fake +18378 Single-lit-var/imm32/inouts +18379 0x11/imm32/alloc-id:fake +18380 Single-int-var-in-ebx/imm32/outputs +18381 0x11/imm32/alloc-id:fake +18382 _string_bb_copy_to_ebx/imm32/subx-name +18383 0/imm32/no-rm32 +18384 0/imm32/no-r32 +18385 1/imm32/imm32-is-first-inout +18386 0/imm32/no-imm8 +18387 0/imm32/no-disp32 +18388 1/imm32/output-is-write-only +18389 0x11/imm32/alloc-id:fake +18390 _Primitive-copy-to-esi/imm32/next +18391 _Primitive-copy-to-esi: # (payload primitive) +18392 0x11/imm32/alloc-id:fake:payload +18393 # var/esi <- copy lit => be/copy-to-esi lit/imm32 +18394 0x11/imm32/alloc-id:fake +18395 _string-copy/imm32/name +18396 0x11/imm32/alloc-id:fake +18397 Single-lit-var/imm32/inouts +18398 0x11/imm32/alloc-id:fake +18399 Single-int-var-in-esi/imm32/outputs +18400 0x11/imm32/alloc-id:fake +18401 _string_be_copy_to_esi/imm32/subx-name +18402 0/imm32/no-rm32 +18403 0/imm32/no-r32 +18404 1/imm32/imm32-is-first-inout +18405 0/imm32/no-imm8 +18406 0/imm32/no-disp32 +18407 1/imm32/output-is-write-only +18408 0x11/imm32/alloc-id:fake +18409 _Primitive-copy-to-edi/imm32/next +18410 _Primitive-copy-to-edi: # (payload primitive) +18411 0x11/imm32/alloc-id:fake:payload +18412 # var/edi <- copy lit => bf/copy-to-edi lit/imm32 +18413 0x11/imm32/alloc-id:fake +18414 _string-copy/imm32/name +18415 0x11/imm32/alloc-id:fake +18416 Single-lit-var/imm32/inouts +18417 0x11/imm32/alloc-id:fake +18418 Single-int-var-in-edi/imm32/outputs +18419 0x11/imm32/alloc-id:fake +18420 _string_bf_copy_to_edi/imm32/subx-name +18421 0/imm32/no-rm32 +18422 0/imm32/no-r32 +18423 1/imm32/imm32-is-first-inout +18424 0/imm32/no-imm8 +18425 0/imm32/no-disp32 +18426 1/imm32/output-is-write-only +18427 0x11/imm32/alloc-id:fake +18428 _Primitive-copy-reg-to-reg/imm32/next +18429 _Primitive-copy-reg-to-reg: # (payload primitive) 18430 0x11/imm32/alloc-id:fake:payload -18431 # "subtract-from" -18432 0xd/imm32/size -18433 0x73/s 0x75/u 0x62/b 0x74/t 0x72/r 0x61/a 0x63/c 0x74/t 0x2d/dash 0x66/f 0x72/r 0x6f/o 0x6d/m -18434 _string-xor: # (payload array byte) -18435 0x11/imm32/alloc-id:fake:payload -18436 # "xor" -18437 0x3/imm32/size -18438 0x78/x 0x6f/o 0x72/r -18439 _string-xor-with: # (payload array byte) -18440 0x11/imm32/alloc-id:fake:payload -18441 # "xor-with" -18442 0x8/imm32/size -18443 0x78/x 0x6f/o 0x72/r 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h -18444 _string-shift-left: # (payload array byte) -18445 0x11/imm32/alloc-id:fake:payload -18446 # "shift-left" -18447 0xa/imm32/size -18448 0x73/s 0x68/h 0x69/i 0x66/f 0x74/t 0x2d/dash 0x6c/l 0x65/e 0x66/f 0x74/t -18449 _string-shift-right: # (payload array byte) -18450 0x11/imm32/alloc-id:fake:payload -18451 # "shift-right" -18452 0xb/imm32/size -18453 0x73/s 0x68/h 0x69/i 0x66/f 0x74/t 0x2d/dash 0x72/r 0x69/i 0x67/g 0x68/h 0x74/t -18454 _string-shift-right-signed: # (payload array byte) -18455 0x11/imm32/alloc-id:fake:payload -18456 # "shift-right-signed" -18457 0x12/imm32/size -18458 0x73/s 0x68/h 0x69/i 0x66/f 0x74/t 0x2d/dash 0x72/r 0x69/i 0x67/g 0x68/h 0x74/t 0x2d/dash 0x73/s 0x69/i 0x67/g 0x6e/n 0x65/e 0x64/d -18459 -18460 # string literals for SubX instructions -18461 _string_01_add_to: # (payload array byte) -18462 0x11/imm32/alloc-id:fake:payload -18463 # "01/add-to" -18464 0x9/imm32/size -18465 0x30/0 0x31/1 0x2f/slash 0x61/a 0x64/d 0x64/d 0x2d/dash 0x74/t 0x6f/o -18466 _string_03_add: # (payload array byte) -18467 0x11/imm32/alloc-id:fake:payload -18468 # "03/add" -18469 0x6/imm32/size -18470 0x30/0 0x33/3 0x2f/slash 0x61/a 0x64/d 0x64/d -18471 _string_05_add_to_eax: # (payload array byte) -18472 0x11/imm32/alloc-id:fake:payload -18473 # "05/add-to-eax" -18474 0xd/imm32/size -18475 0x30/0 0x35/5 0x2f/slash 0x61/a 0x64/d 0x64/d 0x2d/dash 0x74/t 0x6f/o 0x2d/dash 0x65/e 0x61/a 0x78/x -18476 _string_09_or_with: # (payload array byte) -18477 0x11/imm32/alloc-id:fake:payload -18478 # "09/or-with" -18479 0xa/imm32/size -18480 0x30/0 0x39/9 0x2f/slash 0x6f/o 0x72/r 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h -18481 _string_0b_or: # (payload array byte) -18482 0x11/imm32/alloc-id:fake:payload -18483 # "0b/or" -18484 0x5/imm32/size -18485 0x30/0 0x62/b 0x2f/slash 0x6f/o 0x72/r -18486 _string_0d_or_with_eax: # (payload array byte) +18431 # var1/reg <- copy var2/reg => 89/<- var1/rm32 var2/r32 +18432 0x11/imm32/alloc-id:fake +18433 _string-copy/imm32/name +18434 0x11/imm32/alloc-id:fake +18435 Single-int-var-in-some-register/imm32/inouts +18436 0x11/imm32/alloc-id:fake +18437 Single-int-var-in-some-register/imm32/outputs +18438 0x11/imm32/alloc-id:fake +18439 _string_89_<-/imm32/subx-name +18440 3/imm32/rm32-is-first-output +18441 1/imm32/r32-is-first-inout +18442 0/imm32/no-imm32 +18443 0/imm32/no-imm8 +18444 0/imm32/no-disp32 +18445 1/imm32/output-is-write-only +18446 0x11/imm32/alloc-id:fake +18447 _Primitive-copy-reg-to-mem/imm32/next +18448 _Primitive-copy-reg-to-mem: # (payload primitive) +18449 0x11/imm32/alloc-id:fake:payload +18450 # copy-to var1 var2/reg => 89/<- var1 var2/r32 +18451 0x11/imm32/alloc-id:fake +18452 _string-copy-to/imm32/name +18453 0x11/imm32/alloc-id:fake +18454 Two-args-int-stack-int-reg/imm32/inouts +18455 0/imm32/no-outputs +18456 0/imm32/no-outputs +18457 0x11/imm32/alloc-id:fake +18458 _string_89_<-/imm32/subx-name +18459 1/imm32/rm32-is-first-inout +18460 2/imm32/r32-is-second-inout +18461 0/imm32/no-imm32 +18462 0/imm32/no-imm8 +18463 0/imm32/no-disp32 +18464 1/imm32/output-is-write-only +18465 0x11/imm32/alloc-id:fake +18466 _Primitive-copy-mem-to-reg/imm32/next +18467 _Primitive-copy-mem-to-reg: # (payload primitive) +18468 0x11/imm32/alloc-id:fake:payload +18469 # var1/reg <- copy var2 => 8b/-> var2/rm32 var1/r32 +18470 0x11/imm32/alloc-id:fake +18471 _string-copy/imm32/name +18472 0x11/imm32/alloc-id:fake +18473 Single-int-var-in-mem/imm32/inouts +18474 0x11/imm32/alloc-id:fake +18475 Single-int-var-in-some-register/imm32/outputs +18476 0x11/imm32/alloc-id:fake +18477 _string_8b_->/imm32/subx-name +18478 1/imm32/rm32-is-first-inout +18479 3/imm32/r32-is-first-output +18480 0/imm32/no-imm32 +18481 0/imm32/no-imm8 +18482 0/imm32/no-disp32 +18483 1/imm32/output-is-write-only +18484 0x11/imm32/alloc-id:fake +18485 _Primitive-copy-lit-to-reg/imm32/next +18486 _Primitive-copy-lit-to-reg: # (payload primitive) 18487 0x11/imm32/alloc-id:fake:payload -18488 # "0d/or-with-eax" -18489 0xe/imm32/size -18490 0x30/0 0x64/d 0x2f/slash 0x6f/o 0x72/r 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h 0x2d/dash 0x65/e 0x61/a 0x78/x -18491 _string_0f_82_jump_label: # (payload array byte) -18492 0x11/imm32/alloc-id:fake:payload -18493 # "0f 82/jump-if-addr<" -18494 0x13/imm32/size -18495 0x30/0 0x66/f 0x20/space 0x38/8 0x32/2 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3c/< -18496 _string_0f_82_jump_break: # (payload array byte) -18497 0x11/imm32/alloc-id:fake:payload -18498 # "0f 82/jump-if-addr< break/disp32" -18499 0x20/imm32/size -18500 0x30/0 0x66/f 0x20/space 0x38/8 0x32/2 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3c/< 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 -18501 _string_0f_82_jump_loop: # (payload array byte) -18502 0x11/imm32/alloc-id:fake:payload -18503 # "0f 82/jump-if-addr< loop/disp32" -18504 0x1f/imm32/size -18505 0x30/0 0x66/f 0x20/space 0x38/8 0x32/2 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3c/< 0x20/space 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 -18506 _string_0f_83_jump_label: # (payload array byte) -18507 0x11/imm32/alloc-id:fake:payload -18508 # "0f 83/jump-if-addr>=" -18509 0x14/imm32/size -18510 0x30/0 0x66/f 0x20/space 0x38/8 0x33/3 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3e/> 0x3d/= -18511 _string_0f_83_jump_break: # (payload array byte) -18512 0x11/imm32/alloc-id:fake:payload -18513 # "0f 83/jump-if-addr>= break/disp32" -18514 0x21/imm32/size -18515 0x30/0 0x66/f 0x20/space 0x38/8 0x33/3 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3e/> 0x3d/= 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 -18516 _string_0f_83_jump_loop: # (payload array byte) -18517 0x11/imm32/alloc-id:fake:payload -18518 # "0f 83/jump-if-addr>= loop/disp32" -18519 0x20/imm32/size -18520 0x30/0 0x66/f 0x20/space 0x38/8 0x33/3 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3e/> 0x3d/= 0x20/space 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 -18521 _string_0f_84_jump_label: # (payload array byte) -18522 0x11/imm32/alloc-id:fake:payload -18523 # "0f 84/jump-if-=" -18524 0xf/imm32/size -18525 0x30/0 0x66/f 0x20/space 0x38/8 0x34/4 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3d/= -18526 _string_0f_84_jump_break: # (payload array byte) -18527 0x11/imm32/alloc-id:fake:payload -18528 # "0f 84/jump-if-= break/disp32" -18529 0x1c/imm32/size -18530 0x30/0 0x66/f 0x20/space 0x38/8 0x34/4 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3d/= 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 -18531 _string_0f_84_jump_loop: # (payload array byte) -18532 0x11/imm32/alloc-id:fake:payload -18533 # "0f 84/jump-if-= loop/disp32" -18534 0x1b/imm32/size -18535 0x30/0 0x66/f 0x20/space 0x38/8 0x34/4 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3d/= 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 -18536 _string_0f_85_jump_label: # (payload array byte) -18537 0x11/imm32/alloc-id:fake:payload -18538 # "0f 85/jump-if-!=" -18539 0x10/imm32/size -18540 0x30/0 0x66/f 0x20/space 0x38/8 0x35/5 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x21/! 0x3d/= -18541 _string_0f_85_jump_break: # (payload array byte) -18542 0x11/imm32/alloc-id:fake:payload -18543 # "0f 85/jump-if-!= break/disp32" -18544 0x1d/imm32/size -18545 0x30/0 0x66/f 0x20/space 0x38/8 0x35/5 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x21/! 0x3d/= 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 -18546 _string_0f_85_jump_loop: # (payload array byte) -18547 0x11/imm32/alloc-id:fake:payload -18548 # "0f 85/jump-if-!= loop/disp32" -18549 0x1c/imm32/size -18550 0x30/0 0x66/f 0x20/space 0x38/8 0x35/5 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x21/! 0x3d/= 0x20/space 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 -18551 _string_0f_86_jump_label: # (payload array byte) -18552 0x11/imm32/alloc-id:fake:payload -18553 # "0f 86/jump-if-addr<=" -18554 0x14/imm32/size -18555 0x30/0 0x66/f 0x20/space 0x38/8 0x36/6 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3c/< 0x3d/= -18556 _string_0f_86_jump_break: # (payload array byte) -18557 0x11/imm32/alloc-id:fake:payload -18558 # "0f 86/jump-if-addr<= break/disp32" -18559 0x21/imm32/size -18560 0x30/0 0x66/f 0x20/space 0x38/8 0x36/6 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3c/< 0x3d/= 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 -18561 _string_0f_86_jump_loop: # (payload array byte) -18562 0x11/imm32/alloc-id:fake:payload -18563 # "0f 86/jump-if-addr<= loop/disp32" -18564 0x20/imm32/size -18565 0x30/0 0x66/f 0x20/space 0x38/8 0x36/6 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3c/< 0x3d/= 0x20/space 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 -18566 _string_0f_87_jump_label: # (payload array byte) -18567 0x11/imm32/alloc-id:fake:payload -18568 # "0f 87/jump-if-addr>" -18569 0x13/imm32/size -18570 0x30/0 0x66/f 0x20/space 0x38/8 0x37/7 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3e/> -18571 _string_0f_87_jump_break: # (payload array byte) -18572 0x11/imm32/alloc-id:fake:payload -18573 # "0f 87/jump-if-addr> break/disp32" -18574 0x20/imm32/size -18575 0x30/0 0x66/f 0x20/space 0x38/8 0x37/7 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3e/> 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 -18576 _string_0f_87_jump_loop: # (payload array byte) -18577 0x11/imm32/alloc-id:fake:payload -18578 # "0f 87/jump-if-addr> loop/disp32" -18579 0x1f/imm32/size -18580 0x30/0 0x66/f 0x20/space 0x38/8 0x37/7 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3e/> 0x20/space 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 -18581 _string_0f_8c_jump_label: # (payload array byte) -18582 0x11/imm32/alloc-id:fake:payload -18583 # "0f 8c/jump-if-<" -18584 0xf/imm32/size -18585 0x30/0 0x66/f 0x20/space 0x38/8 0x63/c 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/< -18586 _string_0f_8c_jump_break: # (payload array byte) -18587 0x11/imm32/alloc-id:fake:payload -18588 # "0f 8c/jump-if-< break/disp32" -18589 0x1c/imm32/size -18590 0x30/0 0x66/f 0x20/space 0x38/8 0x63/c 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/< 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 -18591 _string_0f_8c_jump_loop: # (payload array byte) -18592 0x11/imm32/alloc-id:fake:payload -18593 # "0f 8c/jump-if-< loop/disp32" -18594 0x1b/imm32/size -18595 0x30/0 0x66/f 0x20/space 0x38/8 0x63/c 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/< 0x20/space 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 -18596 _string_0f_8d_jump_label: # (payload array byte) -18597 0x11/imm32/alloc-id:fake:payload -18598 # "0f 8d/jump-if->=" -18599 0x10/imm32/size -18600 0x30/0 0x66/f 0x20/space 0x38/8 0x64/d 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/> 0x3d/= -18601 _string_0f_8d_jump_break: # (payload array byte) -18602 0x11/imm32/alloc-id:fake:payload -18603 # "0f 8d/jump-if->= break/disp32" -18604 0x1d/imm32/size -18605 0x30/0 0x66/f 0x20/space 0x38/8 0x64/d 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/> 0x3d/= 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 -18606 _string_0f_8d_jump_loop: # (payload array byte) -18607 0x11/imm32/alloc-id:fake:payload -18608 # "0f 8d/jump-if->= loop/disp32" -18609 0x1c/imm32/size -18610 0x30/0 0x66/f 0x20/space 0x38/8 0x64/d 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/> 0x3d/= 0x20/space 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 -18611 _string_0f_8e_jump_label: # (payload array byte) -18612 0x11/imm32/alloc-id:fake:payload -18613 # "0f 8e/jump-if-<=" -18614 0x10/imm32/size -18615 0x30/0 0x66/f 0x20/space 0x38/8 0x65/e 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/< 0x3d/= -18616 _string_0f_8e_jump_break: # (payload array byte) -18617 0x11/imm32/alloc-id:fake:payload -18618 # "0f 8e/jump-if-<= break/disp32" -18619 0x1d/imm32/size -18620 0x30/0 0x66/f 0x20/space 0x38/8 0x65/e 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/< 0x3d/= 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 -18621 _string_0f_8e_jump_loop: # (payload array byte) -18622 0x11/imm32/alloc-id:fake:payload -18623 # "0f 8e/jump-if-<= loop/disp32" -18624 0x1c/imm32/size -18625 0x30/0 0x66/f 0x20/space 0x38/8 0x65/e 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/< 0x3d/= 0x20/space 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 -18626 _string_0f_8f_jump_label: # (payload array byte) -18627 0x11/imm32/alloc-id:fake:payload -18628 # "0f 8f/jump-if->" -18629 0xf/imm32/size -18630 0x30/0 0x66/f 0x20/space 0x38/8 0x66/f 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/> -18631 _string_0f_8f_jump_break: # (payload array byte) -18632 0x11/imm32/alloc-id:fake:payload -18633 # "0f 8f/jump-if-> break/disp32" -18634 0x1c/imm32/size -18635 0x30/0 0x66/f 0x20/space 0x38/8 0x66/f 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/> 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 -18636 _string_0f_8f_jump_loop: # (payload array byte) -18637 0x11/imm32/alloc-id:fake:payload -18638 # "0f 8f/jump-if-> loop/disp32" -18639 0x1b/imm32/size -18640 0x30/0 0x66/f 0x20/space 0x38/8 0x66/f 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/> 0x20/space 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 -18641 _string_0f_af_multiply: # (payload array byte) +18488 # var1/reg <- copy lit => c7 0/subop/copy var1/rm32 lit/imm32 +18489 0x11/imm32/alloc-id:fake +18490 _string-copy/imm32/name +18491 0x11/imm32/alloc-id:fake +18492 Single-lit-var/imm32/inouts +18493 0x11/imm32/alloc-id:fake +18494 Single-int-var-in-some-register/imm32/outputs +18495 0x11/imm32/alloc-id:fake +18496 _string_c7_subop_copy/imm32/subx-name +18497 3/imm32/rm32-is-first-output +18498 0/imm32/no-r32 +18499 1/imm32/imm32-is-first-inout +18500 0/imm32/no-imm8 +18501 0/imm32/no-disp32 +18502 1/imm32/output-is-write-only +18503 0x11/imm32/alloc-id:fake +18504 _Primitive-copy-lit-to-mem/imm32/next +18505 _Primitive-copy-lit-to-mem: # (payload primitive) +18506 0x11/imm32/alloc-id:fake:payload +18507 # copy-to var1, lit => c7 0/subop/copy var1/rm32 lit/imm32 +18508 0x11/imm32/alloc-id:fake +18509 _string-copy-to/imm32/name +18510 0x11/imm32/alloc-id:fake +18511 Int-var-and-literal/imm32/inouts +18512 0/imm32/no-outputs +18513 0/imm32/no-outputs +18514 0x11/imm32/alloc-id:fake +18515 _string_c7_subop_copy/imm32/subx-name +18516 1/imm32/rm32-is-first-inout +18517 0/imm32/no-r32 +18518 2/imm32/imm32-is-second-inout +18519 0/imm32/no-imm8 +18520 0/imm32/no-disp32 +18521 1/imm32/output-is-write-only +18522 0x11/imm32/alloc-id:fake +18523 _Primitive-copy-byte-from-reg/imm32/next +18524 # - copy byte +18525 _Primitive-copy-byte-from-reg: +18526 0x11/imm32/alloc-id:fake:payload +18527 # var/reg <- copy-byte var2/reg2 => 8a/byte-> %var2 var/r32 +18528 0x11/imm32/alloc-id:fake +18529 _string-copy-byte/imm32/name +18530 0x11/imm32/alloc-id:fake +18531 Single-byte-var-in-some-register/imm32/inouts +18532 0x11/imm32/alloc-id:fake +18533 Single-byte-var-in-some-register/imm32/outputs +18534 0x11/imm32/alloc-id:fake +18535 _string_8a_copy_byte/imm32/subx-name +18536 1/imm32/rm32-is-first-inout +18537 3/imm32/r32-is-first-output +18538 0/imm32/no-imm32 +18539 0/imm32/no-imm8 +18540 0/imm32/no-disp32 +18541 1/imm32/output-is-write-only +18542 0x11/imm32/alloc-id:fake +18543 _Primitive-copy-byte-from-mem/imm32/next +18544 _Primitive-copy-byte-from-mem: +18545 0x11/imm32/alloc-id:fake:payload +18546 # var/reg <- copy-byte *var2/reg2 => 8a/byte-> *var2 var/r32 +18547 0x11/imm32/alloc-id:fake +18548 _string-copy-byte/imm32/name +18549 0x11/imm32/alloc-id:fake +18550 Single-byte-var-in-mem/imm32/inouts +18551 0x11/imm32/alloc-id:fake +18552 Single-byte-var-in-some-register/imm32/outputs +18553 0x11/imm32/alloc-id:fake +18554 _string_8a_copy_byte/imm32/subx-name +18555 1/imm32/rm32-is-first-inout +18556 3/imm32/r32-is-first-output +18557 0/imm32/no-imm32 +18558 0/imm32/no-imm8 +18559 0/imm32/no-disp32 +18560 1/imm32/output-is-write-only +18561 0x11/imm32/alloc-id:fake +18562 _Primitive-copy-byte-to-mem/imm32/next +18563 _Primitive-copy-byte-to-mem: +18564 0x11/imm32/alloc-id:fake:payload +18565 # copy-byte-to *var1/reg1, var2/reg2 => 88/byte<- *reg1 reg2/r32 +18566 0x11/imm32/alloc-id:fake +18567 _string-copy-byte-to/imm32/name +18568 0x11/imm32/alloc-id:fake +18569 Two-args-byte-stack-byte-reg/imm32/inouts +18570 0/imm32/no-outputs +18571 0/imm32/no-outputs +18572 0x11/imm32/alloc-id:fake +18573 _string_88_copy_byte/imm32/subx-name +18574 1/imm32/rm32-is-first-inout +18575 2/imm32/r32-is-second-inout +18576 0/imm32/no-imm32 +18577 0/imm32/no-imm8 +18578 0/imm32/no-disp32 +18579 0/imm32/output-is-write-only +18580 0x11/imm32/alloc-id:fake +18581 _Primitive-address/imm32/next +18582 # - address +18583 _Primitive-address: # (payload primitive) +18584 0x11/imm32/alloc-id:fake:payload +18585 # var1/reg <- address var2 => 8d/copy-address var2/rm32 var1/r32 +18586 0x11/imm32/alloc-id:fake +18587 _string-address/imm32/name +18588 0x11/imm32/alloc-id:fake +18589 Single-int-var-in-mem/imm32/inouts +18590 0x11/imm32/alloc-id:fake +18591 Single-addr-var-in-some-register/imm32/outputs +18592 0x11/imm32/alloc-id:fake +18593 _string_8d_copy_address/imm32/subx-name +18594 1/imm32/rm32-is-first-inout +18595 3/imm32/r32-is-first-output +18596 0/imm32/no-imm32 +18597 0/imm32/no-imm8 +18598 0/imm32/no-disp32 +18599 1/imm32/output-is-write-only +18600 0x11/imm32/alloc-id:fake +18601 _Primitive-compare-reg-with-reg/imm32/next +18602 # - compare +18603 _Primitive-compare-reg-with-reg: # (payload primitive) +18604 0x11/imm32/alloc-id:fake:payload +18605 # compare var1/reg1 var2/reg2 => 39/compare var1/rm32 var2/r32 +18606 0x11/imm32/alloc-id:fake +18607 _string-compare/imm32/name +18608 0x11/imm32/alloc-id:fake +18609 Two-int-args-in-regs/imm32/inouts +18610 0/imm32/no-outputs +18611 0/imm32/no-outputs +18612 0x11/imm32/alloc-id:fake +18613 _string_39_compare->/imm32/subx-name +18614 1/imm32/rm32-is-first-inout +18615 2/imm32/r32-is-second-inout +18616 0/imm32/no-imm32 +18617 0/imm32/no-imm8 +18618 0/imm32/no-disp32 +18619 0/imm32/output-is-write-only +18620 0x11/imm32/alloc-id:fake +18621 _Primitive-compare-mem-with-reg/imm32/next +18622 _Primitive-compare-mem-with-reg: # (payload primitive) +18623 0x11/imm32/alloc-id:fake:payload +18624 # compare var1 var2/reg => 39/compare var1/rm32 var2/r32 +18625 0x11/imm32/alloc-id:fake +18626 _string-compare/imm32/name +18627 0x11/imm32/alloc-id:fake +18628 Two-args-int-stack-int-reg/imm32/inouts +18629 0/imm32/no-outputs +18630 0/imm32/no-outputs +18631 0x11/imm32/alloc-id:fake +18632 _string_39_compare->/imm32/subx-name +18633 1/imm32/rm32-is-first-inout +18634 2/imm32/r32-is-second-inout +18635 0/imm32/no-imm32 +18636 0/imm32/no-imm8 +18637 0/imm32/no-disp32 +18638 0/imm32/output-is-write-only +18639 0x11/imm32/alloc-id:fake +18640 _Primitive-compare-reg-with-mem/imm32/next +18641 _Primitive-compare-reg-with-mem: # (payload primitive) 18642 0x11/imm32/alloc-id:fake:payload -18643 # "0f af/multiply" -18644 0xe/imm32/size -18645 0x30/0 0x66/f 0x20/space 0x61/a 0x66/f 0x2f/slash 0x6d/m 0x75/u 0x6c/l 0x74/t 0x69/i 0x70/p 0x6c/l 0x79/y -18646 _string_21_and_with: # (payload array byte) -18647 0x11/imm32/alloc-id:fake:payload -18648 # "21/and-with" -18649 0xb/imm32/size -18650 0x32/2 0x31/1 0x2f/slash 0x61/a 0x6e/n 0x64/d 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h -18651 _string_23_and: # (payload array byte) -18652 0x11/imm32/alloc-id:fake:payload -18653 # "23/and" -18654 0x6/imm32/size -18655 0x32/2 0x33/3 0x2f/slash 0x61/a 0x6e/n 0x64/d -18656 _string_25_and_with_eax: # (payload array byte) -18657 0x11/imm32/alloc-id:fake:payload -18658 # "25/and-with-eax" -18659 0xf/imm32/size -18660 0x32/2 0x35/5 0x2f/slash 0x61/a 0x6e/n 0x64/d 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h 0x2d/dash 0x65/e 0x61/a 0x78/x -18661 _string_29_subtract_from: # (payload array byte) -18662 0x11/imm32/alloc-id:fake:payload -18663 # "29/subtract-from" -18664 0x10/imm32/size -18665 0x32/2 0x39/9 0x2f/slash 0x73/s 0x75/u 0x62/b 0x74/t 0x72/r 0x61/a 0x63/c 0x74/t 0x2d/dash 0x66/f 0x72/r 0x6f/o 0x6d/m -18666 _string_2b_subtract: # (payload array byte) -18667 0x11/imm32/alloc-id:fake:payload -18668 # "2b/subtract" -18669 0xb/imm32/size -18670 0x32/2 0x62/b 0x2f/slash 0x73/s 0x75/u 0x62/b 0x74/t 0x72/r 0x61/a 0x63/c 0x74/t -18671 _string_2d_subtract_from_eax: # (payload array byte) -18672 0x11/imm32/alloc-id:fake:payload -18673 # "2d/subtract-from-eax" -18674 0x14/imm32/size -18675 0x32/2 0x64/d 0x2f/slash 0x73/s 0x75/u 0x62/b 0x74/t 0x72/r 0x61/a 0x63/c 0x74/t 0x2d/dash 0x66/f 0x72/r 0x6f/o 0x6d/m 0x2d/dash 0x65/e 0x61/a 0x78/x -18676 _string_31_xor_with: # (payload array byte) -18677 0x11/imm32/alloc-id:fake:payload -18678 # "31/xor-with" -18679 0xb/imm32/size -18680 0x33/3 0x31/1 0x2f/slash 0x78/x 0x6f/o 0x72/r 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h -18681 _string_33_xor: # (payload array byte) -18682 0x11/imm32/alloc-id:fake:payload -18683 # "33/xor" -18684 0x6/imm32/size -18685 0x33/3 0x33/3 0x2f/slash 0x78/x 0x6f/o 0x72/r -18686 _string_35_xor_with_eax: # (payload array byte) -18687 0x11/imm32/alloc-id:fake:payload -18688 # "35/xor-with-eax" -18689 0xf/imm32/size -18690 0x33/3 0x35/5 0x2f/slash 0x78/x 0x6f/o 0x72/r 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h 0x2d/dash 0x65/e 0x61/a 0x78/x -18691 _string_39_compare->: # (payload array byte) -18692 0x11/imm32/alloc-id:fake:payload -18693 # "39/compare->" -18694 0xc/imm32/size -18695 0x33/3 0x39/9 0x2f/slash 0x63/c 0x6f/o 0x6d/m 0x70/p 0x61/a 0x72/r 0x65/e 0x2d/dash 0x3e/> -18696 _string_3b_compare<-: # (payload array byte) -18697 0x11/imm32/alloc-id:fake:payload -18698 # "3b/compare<-" -18699 0xc/imm32/size -18700 0x33/3 0x62/b 0x2f/slash 0x63/c 0x6f/o 0x6d/m 0x70/p 0x61/a 0x72/r 0x65/e 0x3c/< 0x2d/dash -18701 _string_3d_compare_eax_with: # (payload array byte) -18702 0x11/imm32/alloc-id:fake:payload -18703 # "3d/compare-eax-with" -18704 0x13/imm32/size -18705 0x33/3 0x64/d 0x2f/slash 0x63/c 0x6f/o 0x6d/m 0x70/p 0x61/a 0x72/r 0x65/e 0x2d/dash 0x65/e 0x61/a 0x78/x 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h -18706 _string_40_increment_eax: # (payload array byte) -18707 0x11/imm32/alloc-id:fake:payload -18708 # "40/increment-eax" -18709 0x10/imm32/size -18710 0x34/4 0x30/0 0x2f/slash 0x69/i 0x6e/n 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t 0x2d/dash 0x65/e 0x61/a 0x78/x -18711 _string_41_increment_ecx: # (payload array byte) -18712 0x11/imm32/alloc-id:fake:payload -18713 # "41/increment-ecx" -18714 0x10/imm32/size -18715 0x34/4 0x31/1 0x2f/slash 0x69/i 0x6e/n 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t 0x2d/dash 0x65/e 0x63/c 0x78/x -18716 _string_42_increment_edx: # (payload array byte) -18717 0x11/imm32/alloc-id:fake:payload -18718 # "42/increment-edx" -18719 0x10/imm32/size -18720 0x34/4 0x32/2 0x2f/slash 0x69/i 0x6e/n 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t 0x2d/dash 0x65/e 0x64/d 0x78/x -18721 _string_43_increment_ebx: # (payload array byte) -18722 0x11/imm32/alloc-id:fake:payload -18723 # "43/increment-ebx" -18724 0x10/imm32/size -18725 0x34/4 0x33/3 0x2f/slash 0x69/i 0x6e/n 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t 0x2d/dash 0x65/e 0x62/b 0x78/x -18726 _string_46_increment_esi: # (payload array byte) -18727 0x11/imm32/alloc-id:fake:payload -18728 # "46/increment-esi" -18729 0x10/imm32/size -18730 0x34/4 0x36/6 0x2f/slash 0x69/i 0x6e/n 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t 0x2d/dash 0x65/e 0x73/s 0x69/i -18731 _string_47_increment_edi: # (payload array byte) -18732 0x11/imm32/alloc-id:fake:payload -18733 # "47/increment-edi" -18734 0x10/imm32/size -18735 0x34/4 0x37/7 0x2f/slash 0x69/i 0x6e/n 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t 0x2d/dash 0x65/e 0x64/d 0x69/i -18736 _string_48_decrement_eax: # (payload array byte) -18737 0x11/imm32/alloc-id:fake:payload -18738 # "48/decrement-eax" -18739 0x10/imm32/size -18740 0x34/4 0x38/8 0x2f/slash 0x64/d 0x65/e 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t 0x2d/dash 0x65/e 0x61/a 0x78/x -18741 _string_49_decrement_ecx: # (payload array byte) -18742 0x11/imm32/alloc-id:fake:payload -18743 # "49/decrement-ecx" -18744 0x10/imm32/size -18745 0x34/4 0x39/9 0x2f/slash 0x64/d 0x65/e 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t 0x2d/dash 0x65/e 0x63/c 0x78/x -18746 _string_4a_decrement_edx: # (payload array byte) -18747 0x11/imm32/alloc-id:fake:payload -18748 # "4a/decrement-edx" -18749 0x10/imm32/size -18750 0x34/4 0x61/a 0x2f/slash 0x64/d 0x65/e 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t 0x2d/dash 0x65/e 0x64/d 0x78/x -18751 _string_4b_decrement_ebx: # (payload array byte) -18752 0x11/imm32/alloc-id:fake:payload -18753 # "4b/decrement-ebx" -18754 0x10/imm32/size -18755 0x34/4 0x62/b 0x2f/slash 0x64/d 0x65/e 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t 0x2d/dash 0x65/e 0x62/b 0x78/x -18756 _string_4e_decrement_esi: # (payload array byte) -18757 0x11/imm32/alloc-id:fake:payload -18758 # "4e/decrement-esi" -18759 0x10/imm32/size -18760 0x34/4 0x65/e 0x2f/slash 0x64/d 0x65/e 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t 0x2d/dash 0x65/e 0x73/s 0x69/i -18761 _string_4f_decrement_edi: # (payload array byte) -18762 0x11/imm32/alloc-id:fake:payload -18763 # "4f/decrement-edi" -18764 0x10/imm32/size -18765 0x34/4 0x66/f 0x2f/slash 0x64/d 0x65/e 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t 0x2d/dash 0x65/e 0x64/d 0x69/i -18766 _string_81_subop_add: # (payload array byte) -18767 0x11/imm32/alloc-id:fake:payload -18768 # "81 0/subop/add" -18769 0xe/imm32/size -18770 0x38/8 0x31/1 0x20/space 0x30/0 0x2f/slash 0x73/s 0x75/u 0x62/b 0x6f/o 0x70/p 0x2f/slash 0x61/a 0x64/d 0x64/d -18771 _string_81_subop_or: # (payload array byte) -18772 0x11/imm32/alloc-id:fake:payload -18773 # "81 1/subop/or" -18774 0xd/imm32/size -18775 0x38/8 0x31/1 0x20/space 0x31/1 0x2f/slash 0x73/s 0x75/u 0x62/b 0x6f/o 0x70/p 0x2f/slash 0x6f/o 0x72/r -18776 _string_81_subop_and: # (payload array byte) -18777 0x11/imm32/alloc-id:fake:payload -18778 # "81 4/subop/and" -18779 0xe/imm32/size -18780 0x38/8 0x31/1 0x20/space 0x34/4 0x2f/slash 0x73/s 0x75/u 0x62/b 0x6f/o 0x70/p 0x2f/slash 0x61/a 0x6e/n 0x64/d -18781 _string_81_subop_subtract: # (payload array byte) -18782 0x11/imm32/alloc-id:fake:payload -18783 # "81 5/subop/subtract" -18784 0x13/imm32/size -18785 0x38/8 0x31/1 0x20/space 0x35/5 0x2f/slash 0x73/s 0x75/u 0x62/b 0x6f/o 0x70/p 0x2f/slash 0x73/s 0x75/u 0x62/b 0x74/t 0x72/r 0x61/a 0x63/c 0x74/t -18786 _string_81_subop_xor: # (payload array byte) -18787 0x11/imm32/alloc-id:fake:payload -18788 # "81 6/subop/xor" -18789 0xe/imm32/size -18790 0x38/8 0x31/1 0x20/space 0x36/6 0x2f/slash 0x73/s 0x75/u 0x62/b 0x6f/o 0x70/p 0x2f/slash 0x78/x 0x6f/o 0x72/r -18791 _string_81_subop_compare: # (payload array byte) -18792 0x11/imm32/alloc-id:fake:payload -18793 # "81 7/subop/compare" -18794 0x12/imm32/size -18795 0x38/8 0x31/1 0x20/space 0x37/7 0x2f/slash 0x73/s 0x75/u 0x62/b 0x6f/o 0x70/p 0x2f/slash 0x63/c 0x6f/o 0x6d/m 0x70/p 0x61/a 0x72/r 0x65/e -18796 _string_89_<-: # (payload array byte) -18797 0x11/imm32/alloc-id:fake:payload -18798 # "89/<-" -18799 0x5/imm32/size -18800 0x38/8 0x39/9 0x2f/slash 0x3c/< 0x2d/dash -18801 _string_8b_->: # (payload array byte) -18802 0x11/imm32/alloc-id:fake:payload -18803 # "8b/->" -18804 0x5/imm32/size -18805 0x38/8 0x62/b 0x2f/slash 0x2d/dash 0x3e/> -18806 _string_8a_copy_byte: -18807 0x11/imm32/alloc-id:fake:payload -18808 # "8a/byte->" -18809 0x9/imm32/size -18810 0x38/8 0x61/a 0x2f// 0x62/b 0x79/y 0x74/t 0x65/e 0x2d/- 0x3e/> -18811 _string_88_copy_byte: +18643 # compare var1/reg var2 => 3b/compare<- var2/rm32 var1/r32 +18644 0x11/imm32/alloc-id:fake +18645 _string-compare/imm32/name +18646 0x11/imm32/alloc-id:fake +18647 Two-args-int-reg-int-stack/imm32/inouts +18648 0/imm32/no-outputs +18649 0/imm32/no-outputs +18650 0x11/imm32/alloc-id:fake +18651 _string_3b_compare<-/imm32/subx-name +18652 2/imm32/rm32-is-second-inout +18653 1/imm32/r32-is-first-inout +18654 0/imm32/no-imm32 +18655 0/imm32/no-imm8 +18656 0/imm32/no-disp32 +18657 0/imm32/output-is-write-only +18658 0x11/imm32/alloc-id:fake +18659 _Primitive-compare-eax-with-literal/imm32/next +18660 _Primitive-compare-eax-with-literal: # (payload primitive) +18661 0x11/imm32/alloc-id:fake:payload +18662 # compare var1/eax n => 3d/compare-eax-with n/imm32 +18663 0x11/imm32/alloc-id:fake +18664 _string-compare/imm32/name +18665 0x11/imm32/alloc-id:fake +18666 Two-args-int-eax-int-literal/imm32/inouts +18667 0/imm32/no-outputs +18668 0/imm32/no-outputs +18669 0x11/imm32/alloc-id:fake +18670 _string_3d_compare_eax_with/imm32/subx-name +18671 0/imm32/no-rm32 +18672 0/imm32/no-r32 +18673 2/imm32/imm32-is-second-inout +18674 0/imm32/no-imm8 +18675 0/imm32/no-disp32 +18676 0/imm32/output-is-write-only +18677 0x11/imm32/alloc-id:fake +18678 _Primitive-compare-reg-with-literal/imm32/next +18679 _Primitive-compare-reg-with-literal: # (payload primitive) +18680 0x11/imm32/alloc-id:fake:payload +18681 # compare var1/reg n => 81 7/subop/compare %reg n/imm32 +18682 0x11/imm32/alloc-id:fake +18683 _string-compare/imm32/name +18684 0x11/imm32/alloc-id:fake +18685 Int-var-in-register-and-literal/imm32/inouts +18686 0/imm32/no-outputs +18687 0/imm32/no-outputs +18688 0x11/imm32/alloc-id:fake +18689 _string_81_subop_compare/imm32/subx-name +18690 1/imm32/rm32-is-first-inout +18691 0/imm32/no-r32 +18692 2/imm32/imm32-is-second-inout +18693 0/imm32/no-imm8 +18694 0/imm32/no-disp32 +18695 0/imm32/output-is-write-only +18696 0x11/imm32/alloc-id:fake +18697 _Primitive-compare-mem-with-literal/imm32/next +18698 _Primitive-compare-mem-with-literal: # (payload primitive) +18699 0x11/imm32/alloc-id:fake:payload +18700 # compare var1 n => 81 7/subop/compare *(ebp+___) n/imm32 +18701 0x11/imm32/alloc-id:fake +18702 _string-compare/imm32/name +18703 0x11/imm32/alloc-id:fake +18704 Int-var-and-literal/imm32/inouts +18705 0/imm32/no-outputs +18706 0/imm32/no-outputs +18707 0x11/imm32/alloc-id:fake +18708 _string_81_subop_compare/imm32/subx-name +18709 1/imm32/rm32-is-first-inout +18710 0/imm32/no-r32 +18711 2/imm32/imm32-is-second-inout +18712 0/imm32/no-imm8 +18713 0/imm32/no-disp32 +18714 0/imm32/output-is-write-only +18715 0x11/imm32/alloc-id:fake +18716 _Primitive-multiply-reg-by-reg/imm32/next +18717 # - multiply +18718 _Primitive-multiply-reg-by-reg: # (payload primitive) +18719 0x11/imm32/alloc-id:fake:payload +18720 # var1/reg <- multiply var2 => 0f af/multiply var2/rm32 var1/r32 +18721 0x11/imm32/alloc-id:fake +18722 _string-multiply/imm32/name +18723 0x11/imm32/alloc-id:fake +18724 Single-int-var-in-some-register/imm32/inouts +18725 0x11/imm32/alloc-id:fake +18726 Single-int-var-in-some-register/imm32/outputs +18727 0x11/imm32/alloc-id:fake +18728 _string_0f_af_multiply/imm32/subx-name +18729 1/imm32/rm32-is-first-inout +18730 3/imm32/r32-is-first-output +18731 0/imm32/no-imm32 +18732 0/imm32/no-imm8 +18733 0/imm32/no-disp32 +18734 0/imm32/output-is-write-only +18735 0x11/imm32/alloc-id:fake +18736 _Primitive-multiply-reg-by-mem/imm32/next +18737 _Primitive-multiply-reg-by-mem: # (payload primitive) +18738 0x11/imm32/alloc-id:fake:payload +18739 # var1/reg <- multiply var2 => 0f af/multiply var2/rm32 var1/r32 +18740 0x11/imm32/alloc-id:fake +18741 _string-multiply/imm32/name +18742 0x11/imm32/alloc-id:fake +18743 Single-int-var-in-mem/imm32/inouts +18744 0x11/imm32/alloc-id:fake +18745 Single-int-var-in-some-register/imm32/outputs +18746 0x11/imm32/alloc-id:fake +18747 _string_0f_af_multiply/imm32/subx-name +18748 1/imm32/rm32-is-first-inout +18749 3/imm32/r32-is-first-output +18750 0/imm32/no-imm32 +18751 0/imm32/no-imm8 +18752 0/imm32/no-disp32 +18753 0/imm32/output-is-write-only +18754 0x11/imm32/alloc-id:fake +18755 _Primitive-break-if-addr</imm32/next +18756 # - branches +18757 _Primitive-break-if-addr<: # (payload primitive) +18758 0x11/imm32/alloc-id:fake:payload +18759 0x11/imm32/alloc-id:fake +18760 _string-break-if-addr</imm32/name +18761 0/imm32/no-inouts +18762 0/imm32/no-inouts +18763 0/imm32/no-outputs +18764 0/imm32/no-outputs +18765 0x11/imm32/alloc-id:fake +18766 _string_0f_82_jump_break/imm32/subx-name +18767 0/imm32/no-rm32 +18768 0/imm32/no-r32 +18769 0/imm32/no-imm32 +18770 0/imm32/no-imm8 +18771 0/imm32/no-disp32 +18772 0/imm32/no-output +18773 0x11/imm32/alloc-id:fake +18774 _Primitive-break-if-addr>=/imm32/next +18775 _Primitive-break-if-addr>=: # (payload primitive) +18776 0x11/imm32/alloc-id:fake:payload +18777 0x11/imm32/alloc-id:fake +18778 _string-break-if-addr>=/imm32/name +18779 0/imm32/no-inouts +18780 0/imm32/no-inouts +18781 0/imm32/no-outputs +18782 0/imm32/no-outputs +18783 0x11/imm32/alloc-id:fake +18784 _string_0f_83_jump_break/imm32/subx-name +18785 0/imm32/no-rm32 +18786 0/imm32/no-r32 +18787 0/imm32/no-imm32 +18788 0/imm32/no-imm8 +18789 0/imm32/no-disp32 +18790 0/imm32/no-output +18791 0x11/imm32/alloc-id:fake +18792 _Primitive-break-if-=/imm32/next +18793 _Primitive-break-if-=: # (payload primitive) +18794 0x11/imm32/alloc-id:fake:payload +18795 0x11/imm32/alloc-id:fake +18796 _string-break-if-=/imm32/name +18797 0/imm32/no-inouts +18798 0/imm32/no-inouts +18799 0/imm32/no-outputs +18800 0/imm32/no-outputs +18801 0x11/imm32/alloc-id:fake +18802 _string_0f_84_jump_break/imm32/subx-name +18803 0/imm32/no-rm32 +18804 0/imm32/no-r32 +18805 0/imm32/no-imm32 +18806 0/imm32/no-imm8 +18807 0/imm32/no-disp32 +18808 0/imm32/no-output +18809 0x11/imm32/alloc-id:fake +18810 _Primitive-break-if-!=/imm32/next +18811 _Primitive-break-if-!=: # (payload primitive) 18812 0x11/imm32/alloc-id:fake:payload -18813 # "88/byte<-" -18814 0x9/imm32/size -18815 0x38/8 0x38/8 0x2f// 0x62/b 0x79/y 0x74/t 0x65/e 0x3c/< 0x2d/- -18816 _string_8d_copy_address: # (payload array byte) -18817 0x11/imm32/alloc-id:fake:payload -18818 # "8d/copy-address" -18819 0xf/imm32/size -18820 0x38/8 0x64/d 0x2f/slash 0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x65/e 0x73/s 0x73/s -18821 _string_b8_copy_to_eax: # (payload array byte) -18822 0x11/imm32/alloc-id:fake:payload -18823 # "b8/copy-to-eax" -18824 0xe/imm32/size -18825 0x62/b 0x38/8 0x2f/slash 0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/dash 0x74/t 0x6f/o 0x2d/dash 0x65/e 0x61/a 0x78/x -18826 _string_b9_copy_to_ecx: # (payload array byte) -18827 0x11/imm32/alloc-id:fake:payload -18828 # "b9/copy-to-ecx" -18829 0xe/imm32/size -18830 0x62/b 0x39/9 0x2f/slash 0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/dash 0x74/t 0x6f/o 0x2d/dash 0x65/e 0x63/c 0x78/x -18831 _string_ba_copy_to_edx: # (payload array byte) -18832 0x11/imm32/alloc-id:fake:payload -18833 # "ba/copy-to-edx" -18834 0xe/imm32/size -18835 0x62/b 0x61/a 0x2f/slash 0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/dash 0x74/t 0x6f/o 0x2d/dash 0x65/e 0x64/d 0x78/x -18836 _string_bb_copy_to_ebx: # (payload array byte) -18837 0x11/imm32/alloc-id:fake:payload -18838 # "bb/copy-to-ebx" -18839 0xe/imm32/size -18840 0x62/b 0x62/b 0x2f/slash 0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/dash 0x74/t 0x6f/o 0x2d/dash 0x65/e 0x62/b 0x78/x -18841 _string_be_copy_to_esi: # (payload array byte) -18842 0x11/imm32/alloc-id:fake:payload -18843 # "be/copy-to-esi" -18844 0xe/imm32/size -18845 0x62/b 0x65/e 0x2f/slash 0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/dash 0x74/t 0x6f/o 0x2d/dash 0x65/e 0x73/s 0x69/i -18846 _string_bf_copy_to_edi: # (payload array byte) -18847 0x11/imm32/alloc-id:fake:payload -18848 # "bf/copy-to-edi" -18849 0xe/imm32/size -18850 0x62/b 0x66/f 0x2f/slash 0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/dash 0x74/t 0x6f/o 0x2d/dash 0x65/e 0x64/d 0x69/i -18851 _string_c7_subop_copy: # (payload array byte) -18852 0x11/imm32/alloc-id:fake:payload -18853 # "c7 0/subop/copy" -18854 0xf/imm32/size -18855 0x63/c 0x37/7 0x20/space 0x30/0 0x2f/slash 0x73/s 0x75/u 0x62/b 0x6f/o 0x70/p 0x2f/slash 0x63/c 0x6f/o 0x70/p 0x79/y -18856 _string_e9_jump_label: # (payload array byte) -18857 0x11/imm32/alloc-id:fake:payload -18858 # "e9/jump" -18859 0x7/imm32/size -18860 0x65/e 0x39/9 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p -18861 _string_e9_jump_break: # (payload array byte) -18862 0x11/imm32/alloc-id:fake:payload -18863 # "e9/jump break/disp32" -18864 0x14/imm32/size -18865 0x65/e 0x39/9 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 -18866 _string_e9_jump_loop: # (payload array byte) -18867 0x11/imm32/alloc-id:fake:payload -18868 # "e9/jump loop/disp32" -18869 0x13/imm32/size -18870 0x65/e 0x39/9 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x20/space 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 -18871 _string_ff_subop_increment: # (payload array byte) -18872 0x11/imm32/alloc-id:fake:payload -18873 # "ff 0/subop/increment" -18874 0x14/imm32/size -18875 0x66/f 0x66/f 0x20/space 0x30/0 0x2f/slash 0x73/s 0x75/u 0x62/b 0x6f/o 0x70/p 0x2f/slash 0x69/i 0x6e/n 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t -18876 _string_ff_subop_decrement: # (payload array byte) -18877 0x11/imm32/alloc-id:fake:payload -18878 # "ff 1/subop/decrement" -18879 0x14/imm32/size -18880 0x66/f 0x66/f 0x20/space 0x31/1 0x2f/slash 0x73/s 0x75/u 0x62/b 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x65/e 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t -18881 _string_c1_subop_shift_left: # (payload array byte) -18882 0x11/imm32/alloc-id:fake:payload -18883 # "c1/shift 4/subop/left" -18884 0x15/imm32/size -18885 0x63/c 0x31/1 0x2f/slash 0x73/s 0x68/h 0x69/i 0x66/f 0x74/t 0x20/space 0x34/4 0x2f/slash 0x73/s 0x75/u 0x62/b 0x6f/o 0x70/p 0x2f/slash 0x6c/l 0x65/e 0x66/f 0x74/t -18886 _string_c1_subop_shift_right_padding_zeroes: # (payload array byte) -18887 0x11/imm32/alloc-id:fake:payload -18888 # "c1/shift 5/subop/right-padding-zeroes" -18889 0x25/imm32/size -18890 0x63/c 0x31/1 0x2f/slash 0x73/s 0x68/h 0x69/i 0x66/f 0x74/t 0x20/space 0x35/5 0x2f/slash 0x73/s 0x75/u 0x62/b 0x6f/o 0x70/p 0x2f/slash 0x72/r 0x69/i 0x67/g 0x68/h 0x74/t 0x2d/dash 0x70/p 0x61/a 0x64/d 0x64/d 0x69/i 0x6e/n 0x67/g 0x2d/dash 0x7a/z 0x65/e 0x72/r 0x6f/o 0x65/e 0x73/s -18891 _string_c1_subop_shift_right_preserving_sign: # (payload array byte) -18892 0x11/imm32/alloc-id:fake:payload -18893 # "c1/shift 7/subop/right-preserving-sign" -18894 0x26/imm32/size -18895 0x63/c 0x31/1 0x2f/slash 0x73/s 0x68/h 0x69/i 0x66/f 0x74/t 0x20/space 0x37/7 0x2f/slash 0x73/s 0x75/u 0x62/b 0x6f/o 0x70/p 0x2f/slash 0x72/r 0x69/i 0x67/g 0x68/h 0x74/t 0x2d/dash 0x70/p 0x72/r 0x65/e 0x73/s 0x65/e 0x72/r 0x76/v 0x69/i 0x6e/n 0x67/g 0x2d/dash 0x73/s 0x69/i 0x67/g 0x6e/n -18896 -18897 Single-int-var-in-mem: # (payload list var) -18898 0x11/imm32/alloc-id:fake:payload +18813 0x11/imm32/alloc-id:fake +18814 _string-break-if-!=/imm32/name +18815 0/imm32/no-inouts +18816 0/imm32/no-inouts +18817 0/imm32/no-outputs +18818 0/imm32/no-outputs +18819 0x11/imm32/alloc-id:fake +18820 _string_0f_85_jump_break/imm32/subx-name +18821 0/imm32/no-rm32 +18822 0/imm32/no-r32 +18823 0/imm32/no-imm32 +18824 0/imm32/no-imm8 +18825 0/imm32/no-disp32 +18826 0/imm32/no-output +18827 0x11/imm32/alloc-id:fake +18828 _Primitive-break-if-addr<=/imm32/next +18829 _Primitive-break-if-addr<=: # (payload primitive) +18830 0x11/imm32/alloc-id:fake:payload +18831 0x11/imm32/alloc-id:fake +18832 _string-break-if-addr<=/imm32/name +18833 0/imm32/no-inouts +18834 0/imm32/no-inouts +18835 0/imm32/no-outputs +18836 0/imm32/no-outputs +18837 0x11/imm32/alloc-id:fake +18838 _string_0f_86_jump_break/imm32/subx-name +18839 0/imm32/no-rm32 +18840 0/imm32/no-r32 +18841 0/imm32/no-imm32 +18842 0/imm32/no-imm8 +18843 0/imm32/no-disp32 +18844 0/imm32/no-output +18845 0x11/imm32/alloc-id:fake +18846 _Primitive-break-if-addr>/imm32/next +18847 _Primitive-break-if-addr>: # (payload primitive) +18848 0x11/imm32/alloc-id:fake:payload +18849 0x11/imm32/alloc-id:fake +18850 _string-break-if-addr>/imm32/name +18851 0/imm32/no-inouts +18852 0/imm32/no-inouts +18853 0/imm32/no-outputs +18854 0/imm32/no-outputs +18855 0x11/imm32/alloc-id:fake +18856 _string_0f_87_jump_break/imm32/subx-name +18857 0/imm32/no-rm32 +18858 0/imm32/no-r32 +18859 0/imm32/no-imm32 +18860 0/imm32/no-imm8 +18861 0/imm32/no-disp32 +18862 0/imm32/no-output +18863 0x11/imm32/alloc-id:fake +18864 _Primitive-break-if-</imm32/next +18865 _Primitive-break-if-<: # (payload primitive) +18866 0x11/imm32/alloc-id:fake:payload +18867 0x11/imm32/alloc-id:fake +18868 _string-break-if-</imm32/name +18869 0/imm32/no-inouts +18870 0/imm32/no-inouts +18871 0/imm32/no-outputs +18872 0/imm32/no-outputs +18873 0x11/imm32/alloc-id:fake +18874 _string_0f_8c_jump_break/imm32/subx-name +18875 0/imm32/no-rm32 +18876 0/imm32/no-r32 +18877 0/imm32/no-imm32 +18878 0/imm32/no-imm8 +18879 0/imm32/no-disp32 +18880 0/imm32/no-output +18881 0x11/imm32/alloc-id:fake +18882 _Primitive-break-if->=/imm32/next +18883 _Primitive-break-if->=: # (payload primitive) +18884 0x11/imm32/alloc-id:fake:payload +18885 0x11/imm32/alloc-id:fake +18886 _string-break-if->=/imm32/name +18887 0/imm32/no-inouts +18888 0/imm32/no-inouts +18889 0/imm32/no-outputs +18890 0/imm32/no-outputs +18891 0x11/imm32/alloc-id:fake +18892 _string_0f_8d_jump_break/imm32/subx-name +18893 0/imm32/no-rm32 +18894 0/imm32/no-r32 +18895 0/imm32/no-imm32 +18896 0/imm32/no-imm8 +18897 0/imm32/no-disp32 +18898 0/imm32/no-output 18899 0x11/imm32/alloc-id:fake -18900 Int-var-in-mem/imm32 -18901 0/imm32/next -18902 0/imm32/next -18903 -18904 Int-var-in-mem: # (payload var) -18905 0x11/imm32/alloc-id:fake:payload -18906 0/imm32/name -18907 0/imm32/name -18908 0x11/imm32/alloc-id:fake -18909 Type-int/imm32 -18910 1/imm32/some-block-depth -18911 1/imm32/some-stack-offset -18912 0/imm32/no-register -18913 0/imm32/no-register -18914 -18915 # Not really legal, but closest we can currently represent a dereference of an (addr byte) -18916 Single-byte-var-in-mem: # (payload list var) -18917 0x11/imm32/alloc-id:fake:payload -18918 0x11/imm32/alloc-id:fake -18919 Byte-var-in-mem/imm32 -18920 0/imm32/next -18921 0/imm32/next -18922 -18923 # Not really legal, but closest we can currently represent a dereference of an (addr byte) -18924 Byte-var-in-mem: # (payload var) -18925 0x11/imm32/alloc-id:fake:payload -18926 0/imm32/name -18927 0/imm32/name -18928 0x11/imm32/alloc-id:fake -18929 Type-byte/imm32 -18930 1/imm32/some-block-depth -18931 1/imm32/some-stack-offset -18932 0/imm32/no-register -18933 0/imm32/no-register -18934 -18935 Two-args-int-stack-int-reg: # (payload list var) -18936 0x11/imm32/alloc-id:fake:payload -18937 0x11/imm32/alloc-id:fake -18938 Int-var-in-mem/imm32 +18900 _Primitive-break-if-<=/imm32/next +18901 _Primitive-break-if-<=: # (payload primitive) +18902 0x11/imm32/alloc-id:fake:payload +18903 0x11/imm32/alloc-id:fake +18904 _string-break-if-<=/imm32/name +18905 0/imm32/no-inouts +18906 0/imm32/no-inouts +18907 0/imm32/no-outputs +18908 0/imm32/no-outputs +18909 0x11/imm32/alloc-id:fake +18910 _string_0f_8e_jump_break/imm32/subx-name +18911 0/imm32/no-rm32 +18912 0/imm32/no-r32 +18913 0/imm32/no-imm32 +18914 0/imm32/no-imm8 +18915 0/imm32/no-disp32 +18916 0/imm32/no-output +18917 0x11/imm32/alloc-id:fake +18918 _Primitive-break-if->/imm32/next +18919 _Primitive-break-if->: # (payload primitive) +18920 0x11/imm32/alloc-id:fake:payload +18921 0x11/imm32/alloc-id:fake +18922 _string-break-if->/imm32/name +18923 0/imm32/no-inouts +18924 0/imm32/no-inouts +18925 0/imm32/no-outputs +18926 0/imm32/no-outputs +18927 0x11/imm32/alloc-id:fake +18928 _string_0f_8f_jump_break/imm32/subx-name +18929 0/imm32/no-rm32 +18930 0/imm32/no-r32 +18931 0/imm32/no-imm32 +18932 0/imm32/no-imm8 +18933 0/imm32/no-disp32 +18934 0/imm32/no-output +18935 0x11/imm32/alloc-id:fake +18936 _Primitive-break/imm32/next +18937 _Primitive-break: # (payload primitive) +18938 0x11/imm32/alloc-id:fake:payload 18939 0x11/imm32/alloc-id:fake -18940 Single-int-var-in-some-register/imm32/next -18941 -18942 Two-int-args-in-regs: # (payload list var) -18943 0x11/imm32/alloc-id:fake:payload -18944 0x11/imm32/alloc-id:fake -18945 Int-var-in-some-register/imm32 -18946 0x11/imm32/alloc-id:fake -18947 Single-int-var-in-some-register/imm32/next -18948 -18949 # Not really legal, but closest we can currently represent a dereference of an (addr byte) -18950 Two-args-byte-stack-byte-reg: # (payload list var) -18951 0x11/imm32/alloc-id:fake:payload -18952 0x11/imm32/alloc-id:fake -18953 Byte-var-in-mem/imm32 -18954 0x11/imm32/alloc-id:fake -18955 Single-byte-var-in-some-register/imm32/next -18956 -18957 Two-args-int-reg-int-stack: # (payload list var) -18958 0x11/imm32/alloc-id:fake:payload -18959 0x11/imm32/alloc-id:fake -18960 Int-var-in-some-register/imm32 -18961 0x11/imm32/alloc-id:fake -18962 Single-int-var-in-mem/imm32/next -18963 -18964 Two-args-int-eax-int-literal: # (payload list var) -18965 0x11/imm32/alloc-id:fake:payload -18966 0x11/imm32/alloc-id:fake -18967 Int-var-in-eax/imm32 -18968 0x11/imm32/alloc-id:fake -18969 Single-lit-var/imm32/next -18970 -18971 Int-var-and-literal: # (payload list var) -18972 0x11/imm32/alloc-id:fake:payload -18973 0x11/imm32/alloc-id:fake -18974 Int-var-in-mem/imm32 +18940 _string-break/imm32/name +18941 0/imm32/no-inouts +18942 0/imm32/no-inouts +18943 0/imm32/no-outputs +18944 0/imm32/no-outputs +18945 0x11/imm32/alloc-id:fake +18946 _string_e9_jump_break/imm32/subx-name +18947 0/imm32/no-rm32 +18948 0/imm32/no-r32 +18949 0/imm32/no-imm32 +18950 0/imm32/no-imm8 +18951 0/imm32/no-disp32 +18952 0/imm32/no-output +18953 0x11/imm32/alloc-id:fake +18954 _Primitive-loop-if-addr</imm32/next +18955 _Primitive-loop-if-addr<: # (payload primitive) +18956 0x11/imm32/alloc-id:fake:payload +18957 0x11/imm32/alloc-id:fake +18958 _string-loop-if-addr</imm32/name +18959 0/imm32/no-inouts +18960 0/imm32/no-inouts +18961 0/imm32/no-outputs +18962 0/imm32/no-outputs +18963 0x11/imm32/alloc-id:fake +18964 _string_0f_82_jump_loop/imm32/subx-name +18965 0/imm32/no-rm32 +18966 0/imm32/no-r32 +18967 0/imm32/no-imm32 +18968 0/imm32/no-imm8 +18969 0/imm32/no-disp32 +18970 0/imm32/no-output +18971 0x11/imm32/alloc-id:fake +18972 _Primitive-loop-if-addr>=/imm32/next +18973 _Primitive-loop-if-addr>=: # (payload primitive) +18974 0x11/imm32/alloc-id:fake:payload 18975 0x11/imm32/alloc-id:fake -18976 Single-lit-var/imm32/next -18977 -18978 Int-var-in-register-and-literal: # (payload list var) -18979 0x11/imm32/alloc-id:fake:payload -18980 0x11/imm32/alloc-id:fake -18981 Int-var-in-some-register/imm32 -18982 0x11/imm32/alloc-id:fake -18983 Single-lit-var/imm32/next -18984 -18985 Single-int-var-in-some-register: # (payload list var) -18986 0x11/imm32/alloc-id:fake:payload -18987 0x11/imm32/alloc-id:fake -18988 Int-var-in-some-register/imm32 -18989 0/imm32/next -18990 0/imm32/next -18991 -18992 Single-addr-var-in-some-register: # (payload list var) -18993 0x11/imm32/alloc-id:fake:payload -18994 0x11/imm32/alloc-id:fake -18995 Addr-var-in-some-register/imm32 -18996 0/imm32/next -18997 0/imm32/next -18998 -18999 Single-byte-var-in-some-register: # (payload list var) -19000 0x11/imm32/alloc-id:fake:payload -19001 0x11/imm32/alloc-id:fake -19002 Byte-var-in-some-register/imm32 -19003 0/imm32/next -19004 0/imm32/next -19005 -19006 Int-var-in-some-register: # (payload var) -19007 0x11/imm32/alloc-id:fake:payload -19008 0/imm32/name -19009 0/imm32/name -19010 0x11/imm32/alloc-id:fake -19011 Type-int/imm32 -19012 1/imm32/some-block-depth -19013 0/imm32/no-stack-offset -19014 0x11/imm32/alloc-id:fake -19015 Any-register/imm32 -19016 -19017 Any-register: # (payload array byte) -19018 0x11/imm32/alloc-id:fake:payload -19019 1/imm32/size -19020 # data -19021 2a/asterisk -19022 -19023 Addr-var-in-some-register: # (payload var) -19024 0x11/imm32/alloc-id:fake:payload -19025 0/imm32/name -19026 0/imm32/name -19027 0x11/imm32/alloc-id:fake -19028 Type-addr/imm32 -19029 1/imm32/some-block-depth -19030 0/imm32/no-stack-offset -19031 0x11/imm32/alloc-id:fake -19032 Any-register/imm32 -19033 -19034 Byte-var-in-some-register: # (payload var) -19035 0x11/imm32/alloc-id:fake:payload -19036 0/imm32/name -19037 0/imm32/name -19038 0x11/imm32/alloc-id:fake -19039 Type-byte/imm32 -19040 1/imm32/some-block-depth -19041 0/imm32/no-stack-offset -19042 0x11/imm32/alloc-id:fake -19043 Any-register/imm32 -19044 -19045 Single-int-var-in-eax: # (payload list var) +18976 _string-loop-if-addr>=/imm32/name +18977 0/imm32/no-inouts +18978 0/imm32/no-inouts +18979 0/imm32/no-outputs +18980 0/imm32/no-outputs +18981 0x11/imm32/alloc-id:fake +18982 _string_0f_83_jump_loop/imm32/subx-name +18983 0/imm32/no-rm32 +18984 0/imm32/no-r32 +18985 0/imm32/no-imm32 +18986 0/imm32/no-imm8 +18987 0/imm32/no-disp32 +18988 0/imm32/no-output +18989 0x11/imm32/alloc-id:fake +18990 _Primitive-loop-if-=/imm32/next +18991 _Primitive-loop-if-=: # (payload primitive) +18992 0x11/imm32/alloc-id:fake:payload +18993 0x11/imm32/alloc-id:fake +18994 _string-loop-if-=/imm32/name +18995 0/imm32/no-inouts +18996 0/imm32/no-inouts +18997 0/imm32/no-outputs +18998 0/imm32/no-outputs +18999 0x11/imm32/alloc-id:fake +19000 _string_0f_84_jump_loop/imm32/subx-name +19001 0/imm32/no-rm32 +19002 0/imm32/no-r32 +19003 0/imm32/no-imm32 +19004 0/imm32/no-imm8 +19005 0/imm32/no-disp32 +19006 0/imm32/no-output +19007 0x11/imm32/alloc-id:fake +19008 _Primitive-loop-if-!=/imm32/next +19009 _Primitive-loop-if-!=: # (payload primitive) +19010 0x11/imm32/alloc-id:fake:payload +19011 0x11/imm32/alloc-id:fake +19012 _string-loop-if-!=/imm32/name +19013 0/imm32/no-inouts +19014 0/imm32/no-inouts +19015 0/imm32/no-outputs +19016 0/imm32/no-outputs +19017 0x11/imm32/alloc-id:fake +19018 _string_0f_85_jump_loop/imm32/subx-name +19019 0/imm32/no-rm32 +19020 0/imm32/no-r32 +19021 0/imm32/no-imm32 +19022 0/imm32/no-imm8 +19023 0/imm32/no-disp32 +19024 0/imm32/no-output +19025 0x11/imm32/alloc-id:fake +19026 _Primitive-loop-if-addr<=/imm32/next +19027 _Primitive-loop-if-addr<=: # (payload primitive) +19028 0x11/imm32/alloc-id:fake:payload +19029 0x11/imm32/alloc-id:fake +19030 _string-loop-if-addr<=/imm32/name +19031 0/imm32/no-inouts +19032 0/imm32/no-inouts +19033 0/imm32/no-outputs +19034 0/imm32/no-outputs +19035 0x11/imm32/alloc-id:fake +19036 _string_0f_86_jump_loop/imm32/subx-name +19037 0/imm32/no-rm32 +19038 0/imm32/no-r32 +19039 0/imm32/no-imm32 +19040 0/imm32/no-imm8 +19041 0/imm32/no-disp32 +19042 0/imm32/no-output +19043 0x11/imm32/alloc-id:fake +19044 _Primitive-loop-if-addr>/imm32/next +19045 _Primitive-loop-if-addr>: # (payload primitive) 19046 0x11/imm32/alloc-id:fake:payload 19047 0x11/imm32/alloc-id:fake -19048 Int-var-in-eax/imm32 -19049 0/imm32/next -19050 0/imm32/next -19051 -19052 Int-var-in-eax: -19053 0x11/imm32/alloc-id:fake:payload -19054 0/imm32/name -19055 0/imm32/name -19056 0x11/imm32/alloc-id:fake -19057 Type-int/imm32 -19058 1/imm32/some-block-depth -19059 0/imm32/no-stack-offset -19060 0x11/imm32/alloc-id:fake -19061 $Register-eax/imm32 -19062 -19063 Single-int-var-in-ecx: # (payload list var) +19048 _string-loop-if-addr>/imm32/name +19049 0/imm32/no-inouts +19050 0/imm32/no-inouts +19051 0/imm32/no-outputs +19052 0/imm32/no-outputs +19053 0x11/imm32/alloc-id:fake +19054 _string_0f_87_jump_loop/imm32/subx-name +19055 0/imm32/no-rm32 +19056 0/imm32/no-r32 +19057 0/imm32/no-imm32 +19058 0/imm32/no-imm8 +19059 0/imm32/no-disp32 +19060 0/imm32/no-output +19061 0x11/imm32/alloc-id:fake +19062 _Primitive-loop-if-</imm32/next +19063 _Primitive-loop-if-<: # (payload primitive) 19064 0x11/imm32/alloc-id:fake:payload 19065 0x11/imm32/alloc-id:fake -19066 Int-var-in-ecx/imm32 -19067 0/imm32/next -19068 0/imm32/next -19069 -19070 Int-var-in-ecx: -19071 0x11/imm32/alloc-id:fake:payload -19072 0/imm32/name -19073 0/imm32/name -19074 0x11/imm32/alloc-id:fake -19075 Type-int/imm32 -19076 1/imm32/some-block-depth -19077 0/imm32/no-stack-offset -19078 0x11/imm32/alloc-id:fake -19079 $Register-ecx/imm32/register -19080 -19081 Single-int-var-in-edx: # (payload list var) +19066 _string-loop-if-</imm32/name +19067 0/imm32/no-inouts +19068 0/imm32/no-inouts +19069 0/imm32/no-outputs +19070 0/imm32/no-outputs +19071 0x11/imm32/alloc-id:fake +19072 _string_0f_8c_jump_loop/imm32/subx-name +19073 0/imm32/no-rm32 +19074 0/imm32/no-r32 +19075 0/imm32/no-imm32 +19076 0/imm32/no-imm8 +19077 0/imm32/no-disp32 +19078 0/imm32/no-output +19079 0x11/imm32/alloc-id:fake +19080 _Primitive-loop-if->=/imm32/next +19081 _Primitive-loop-if->=: # (payload primitive) 19082 0x11/imm32/alloc-id:fake:payload 19083 0x11/imm32/alloc-id:fake -19084 Int-var-in-edx/imm32 -19085 0/imm32/next -19086 0/imm32/next -19087 -19088 Int-var-in-edx: # (payload list var) -19089 0x11/imm32/alloc-id:fake:payload -19090 0/imm32/name -19091 0/imm32/name -19092 0x11/imm32/alloc-id:fake -19093 Type-int/imm32 -19094 1/imm32/some-block-depth -19095 0/imm32/no-stack-offset -19096 0x11/imm32/alloc-id:fake -19097 $Register-edx/imm32/register -19098 -19099 Single-int-var-in-ebx: # (payload list var) +19084 _string-loop-if->=/imm32/name +19085 0/imm32/no-inouts +19086 0/imm32/no-inouts +19087 0/imm32/no-outputs +19088 0/imm32/no-outputs +19089 0x11/imm32/alloc-id:fake +19090 _string_0f_8d_jump_loop/imm32/subx-name +19091 0/imm32/no-rm32 +19092 0/imm32/no-r32 +19093 0/imm32/no-imm32 +19094 0/imm32/no-imm8 +19095 0/imm32/no-disp32 +19096 0/imm32/no-output +19097 0x11/imm32/alloc-id:fake +19098 _Primitive-loop-if-<=/imm32/next +19099 _Primitive-loop-if-<=: # (payload primitive) 19100 0x11/imm32/alloc-id:fake:payload 19101 0x11/imm32/alloc-id:fake -19102 Int-var-in-ebx/imm32 -19103 0/imm32/next -19104 0/imm32/next -19105 -19106 Int-var-in-ebx: # (payload list var) -19107 0x11/imm32/alloc-id:fake:payload -19108 0/imm32/name -19109 0/imm32/name -19110 0x11/imm32/alloc-id:fake -19111 Type-int/imm32 -19112 1/imm32/some-block-depth -19113 0/imm32/no-stack-offset -19114 0x11/imm32/alloc-id:fake -19115 $Register-ebx/imm32/register -19116 -19117 Single-int-var-in-esi: # (payload list var) +19102 _string-loop-if-<=/imm32/name +19103 0/imm32/no-inouts +19104 0/imm32/no-inouts +19105 0/imm32/no-outputs +19106 0/imm32/no-outputs +19107 0x11/imm32/alloc-id:fake +19108 _string_0f_8e_jump_loop/imm32/subx-name +19109 0/imm32/no-rm32 +19110 0/imm32/no-r32 +19111 0/imm32/no-imm32 +19112 0/imm32/no-imm8 +19113 0/imm32/no-disp32 +19114 0/imm32/no-output +19115 0x11/imm32/alloc-id:fake +19116 _Primitive-loop-if->/imm32/next +19117 _Primitive-loop-if->: # (payload primitive) 19118 0x11/imm32/alloc-id:fake:payload 19119 0x11/imm32/alloc-id:fake -19120 Int-var-in-esi/imm32 -19121 0/imm32/next -19122 0/imm32/next -19123 -19124 Int-var-in-esi: # (payload list var) -19125 0x11/imm32/alloc-id:fake:payload -19126 0/imm32/name -19127 0/imm32/name -19128 0x11/imm32/alloc-id:fake -19129 Type-int/imm32 -19130 1/imm32/some-block-depth -19131 0/imm32/no-stack-offset -19132 0x11/imm32/alloc-id:fake -19133 $Register-esi/imm32/register -19134 -19135 Single-int-var-in-edi: # (payload list var) +19120 _string-loop-if->/imm32/name +19121 0/imm32/no-inouts +19122 0/imm32/no-inouts +19123 0/imm32/no-outputs +19124 0/imm32/no-outputs +19125 0x11/imm32/alloc-id:fake +19126 _string_0f_8f_jump_loop/imm32/subx-name +19127 0/imm32/no-rm32 +19128 0/imm32/no-r32 +19129 0/imm32/no-imm32 +19130 0/imm32/no-imm8 +19131 0/imm32/no-disp32 +19132 0/imm32/no-output +19133 0x11/imm32/alloc-id:fake +19134 _Primitive-loop/imm32/next # we probably don't need an unconditional break +19135 _Primitive-loop: # (payload primitive) 19136 0x11/imm32/alloc-id:fake:payload 19137 0x11/imm32/alloc-id:fake -19138 Int-var-in-edi/imm32 -19139 0/imm32/next -19140 0/imm32/next -19141 -19142 Int-var-in-edi: # (payload list var) -19143 0x11/imm32/alloc-id:fake:payload -19144 0/imm32/name -19145 0/imm32/name -19146 0x11/imm32/alloc-id:fake -19147 Type-int/imm32 -19148 1/imm32/some-block-depth -19149 0/imm32/no-stack-offset -19150 0x11/imm32/alloc-id:fake -19151 $Register-edi/imm32/register -19152 -19153 Single-lit-var: # (payload list var) -19154 0x11/imm32/alloc-id:fake:payload -19155 0x11/imm32/alloc-id:fake -19156 Lit-var/imm32 -19157 0/imm32/next -19158 0/imm32/next -19159 -19160 Lit-var: # (payload var) -19161 0x11/imm32/alloc-id:fake:payload -19162 0/imm32/name -19163 0/imm32/name -19164 0x11/imm32/alloc-id:fake -19165 Type-literal/imm32 -19166 1/imm32/some-block-depth -19167 0/imm32/no-stack-offset -19168 0/imm32/no-register -19169 0/imm32/no-register -19170 -19171 Type-int: # (payload type-tree) -19172 0x11/imm32/alloc-id:fake:payload -19173 1/imm32/is-atom -19174 1/imm32/value:int -19175 0/imm32/left:unused -19176 0/imm32/right:null -19177 0/imm32/right:null -19178 -19179 Type-literal: # (payload type-tree) -19180 0x11/imm32/alloc-id:fake:payload -19181 1/imm32/is-atom -19182 0/imm32/value:literal -19183 0/imm32/left:unused -19184 0/imm32/right:null -19185 0/imm32/right:null -19186 -19187 Type-addr: # (payload type-tree) -19188 0x11/imm32/alloc-id:fake:payload -19189 1/imm32/is-atom -19190 2/imm32/value:addr -19191 0/imm32/left:unused -19192 0/imm32/right:null -19193 0/imm32/right:null -19194 -19195 Type-byte: # (payload type-tree) -19196 0x11/imm32/alloc-id:fake:payload -19197 1/imm32/is-atom -19198 8/imm32/value:byte -19199 0/imm32/left:unused -19200 0/imm32/right:null -19201 0/imm32/right:null -19202 -19203 == code -19204 emit-subx-primitive: # out: (addr buffered-file), stmt: (addr stmt), primitive: (addr primitive), err: (addr buffered-file), ed: (addr exit-descriptor) -19205 # . prologue -19206 55/push-ebp -19207 89/<- %ebp 4/r32/esp -19208 # . save registers -19209 50/push-eax -19210 51/push-ecx -19211 # ecx = primitive -19212 8b/-> *(ebp+0x10) 1/r32/ecx -19213 # emit primitive name -19214 (emit-indent *(ebp+8) *Curr-block-depth) -19215 (lookup *(ecx+0x18) *(ecx+0x1c)) # Primitive-subx-name Primitive-subx-name => eax -19216 (write-buffered *(ebp+8) %eax) -19217 # emit rm32 if necessary -19218 (emit-subx-rm32 *(ebp+8) *(ecx+0x20) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18)) # Primitive-subx-rm32 -19219 # emit r32 if necessary -19220 (emit-subx-r32 *(ebp+8) *(ecx+0x24) *(ebp+0xc)) # Primitive-subx-r32 -19221 # emit imm32 if necessary -19222 (emit-subx-imm32 *(ebp+8) *(ecx+0x28) *(ebp+0xc)) # Primitive-subx-imm32 -19223 # emit imm8 if necessary -19224 (emit-subx-imm8 *(ebp+8) *(ecx+0x2c) *(ebp+0xc)) # Primitive-subx-imm8 -19225 # emit disp32 if necessary -19226 (emit-subx-disp32 *(ebp+8) *(ecx+0x30) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18)) # Primitive-subx-disp32 -19227 (write-buffered *(ebp+8) Newline) -19228 $emit-subx-primitive:end: -19229 # . restore registers -19230 59/pop-to-ecx -19231 58/pop-to-eax -19232 # . epilogue -19233 89/<- %esp 5/r32/ebp -19234 5d/pop-to-ebp -19235 c3/return -19236 -19237 emit-subx-rm32: # out: (addr buffered-file), l: arg-location, stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) -19238 # . prologue -19239 55/push-ebp -19240 89/<- %ebp 4/r32/esp -19241 # . save registers -19242 50/push-eax -19243 # if (l == 0) return -19244 81 7/subop/compare *(ebp+0xc) 0/imm32 -19245 74/jump-if-= $emit-subx-rm32:end/disp8 -19246 # var v/eax: (addr stmt-var) -19247 (get-stmt-operand-from-arg-location *(ebp+0x10) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18)) # => eax -19248 (emit-subx-var-as-rm32 *(ebp+8) %eax) -19249 $emit-subx-rm32:end: -19250 # . restore registers -19251 58/pop-to-eax -19252 # . epilogue -19253 89/<- %esp 5/r32/ebp -19254 5d/pop-to-ebp -19255 c3/return -19256 -19257 get-stmt-operand-from-arg-location: # stmt: (addr stmt), l: arg-location, err: (addr buffered-file), ed: (addr exit-descriptor) -> var/eax: (addr stmt-var) -19258 # . prologue -19259 55/push-ebp -19260 89/<- %ebp 4/r32/esp -19261 # . save registers -19262 51/push-ecx -19263 # eax = l -19264 8b/-> *(ebp+0xc) 0/r32/eax -19265 # ecx = stmt -19266 8b/-> *(ebp+8) 1/r32/ecx -19267 # if (l == 1) return stmt->inouts -19268 { -19269 3d/compare-eax-and 1/imm32 -19270 75/jump-if-!= break/disp8 -19271 $get-stmt-operand-from-arg-location:1: -19272 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax -19273 eb/jump $get-stmt-operand-from-arg-location:end/disp8 -19274 } -19275 # if (l == 2) return stmt->inouts->next -19276 { -19277 3d/compare-eax-and 2/imm32 -19278 75/jump-if-!= break/disp8 -19279 $get-stmt-operand-from-arg-location:2: -19280 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax -19281 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax -19282 eb/jump $get-stmt-operand-from-arg-location:end/disp8 -19283 } -19284 # if (l == 3) return stmt->outputs -19285 { -19286 3d/compare-eax-and 3/imm32 -19287 75/jump-if-!= break/disp8 -19288 $get-stmt-operand-from-arg-location:3: -19289 (lookup *(ecx+0x14) *(ecx+0x18)) # Stmt1-outputs Stmt1-outputs => eax -19290 eb/jump $get-stmt-operand-from-arg-location:end/disp8 -19291 } -19292 # abort -19293 e9/jump $get-stmt-operand-from-arg-location:abort/disp32 -19294 $get-stmt-operand-from-arg-location:end: -19295 # . restore registers -19296 59/pop-to-ecx -19297 # . epilogue -19298 89/<- %esp 5/r32/ebp -19299 5d/pop-to-ebp -19300 c3/return -19301 -19302 $get-stmt-operand-from-arg-location:abort: -19303 # error("invalid arg-location " eax) -19304 (write-buffered *(ebp+0x10) "invalid arg-location ") -19305 (write-int32-hex-buffered *(ebp+0x10) %eax) -19306 (write-buffered *(ebp+0x10) Newline) -19307 (flush *(ebp+0x10)) -19308 (stop *(ebp+0x14) 1) -19309 # never gets here -19310 -19311 emit-subx-r32: # out: (addr buffered-file), l: arg-location, stmt: (addr stmt) -19312 # . prologue -19313 55/push-ebp -19314 89/<- %ebp 4/r32/esp -19315 # . save registers -19316 50/push-eax -19317 51/push-ecx -19318 # if (l == 0) return -19319 81 7/subop/compare *(ebp+0xc) 0/imm32 -19320 0f 84/jump-if-= $emit-subx-r32:end/disp32 -19321 # var v/eax: (addr stmt-var) -19322 (get-stmt-operand-from-arg-location *(ebp+0x10) *(ebp+0xc)) # => eax -19323 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -19324 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax -19325 (maybe-get Mu-registers %eax 0xc) # => eax: (addr register-index) -19326 (write-buffered *(ebp+8) Space) -19327 (write-int32-hex-buffered *(ebp+8) *eax) -19328 (write-buffered *(ebp+8) "/r32") -19329 $emit-subx-r32:end: -19330 # . restore registers -19331 59/pop-to-ecx -19332 58/pop-to-eax -19333 # . epilogue -19334 89/<- %esp 5/r32/ebp -19335 5d/pop-to-ebp -19336 c3/return -19337 -19338 emit-subx-imm32: # out: (addr buffered-file), l: arg-location, stmt: (addr stmt) -19339 # . prologue -19340 55/push-ebp -19341 89/<- %ebp 4/r32/esp -19342 # . save registers -19343 50/push-eax -19344 51/push-ecx -19345 # if (l == 0) return -19346 81 7/subop/compare *(ebp+0xc) 0/imm32 -19347 0f 84/jump-if-= $emit-subx-imm32:end/disp32 -19348 # var v/eax: (handle var) -19349 (get-stmt-operand-from-arg-location *(ebp+0x10) *(ebp+0xc)) # => eax -19350 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -19351 (lookup *eax *(eax+4)) # Var-name Var-name => eax -19352 (write-buffered *(ebp+8) Space) -19353 (write-buffered *(ebp+8) %eax) -19354 (write-buffered *(ebp+8) "/imm32") -19355 $emit-subx-imm32:end: -19356 # . restore registers -19357 59/pop-to-ecx -19358 58/pop-to-eax -19359 # . epilogue -19360 89/<- %esp 5/r32/ebp -19361 5d/pop-to-ebp -19362 c3/return -19363 -19364 emit-subx-imm8: # out: (addr buffered-file), l: arg-location, stmt: (addr stmt) -19365 # . prologue -19366 55/push-ebp -19367 89/<- %ebp 4/r32/esp -19368 # . save registers -19369 50/push-eax -19370 51/push-ecx -19371 # if (l == 0) return -19372 81 7/subop/compare *(ebp+0xc) 0/imm32 -19373 0f 84/jump-if-= $emit-subx-imm32:end/disp32 -19374 # var v/eax: (handle var) -19375 (get-stmt-operand-from-arg-location *(ebp+0x10) *(ebp+0xc)) # => eax -19376 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -19377 (lookup *eax *(eax+4)) # Var-name Var-name => eax -19378 (write-buffered *(ebp+8) Space) -19379 (write-buffered *(ebp+8) %eax) -19380 (write-buffered *(ebp+8) "/imm8") -19381 $emit-subx-imm8:end: -19382 # . restore registers -19383 59/pop-to-ecx -19384 58/pop-to-eax -19385 # . epilogue -19386 89/<- %esp 5/r32/ebp -19387 5d/pop-to-ebp -19388 c3/return -19389 -19390 emit-subx-disp32: # out: (addr buffered-file), l: arg-location, stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) -19391 # . prologue -19392 55/push-ebp -19393 89/<- %ebp 4/r32/esp -19394 # . save registers -19395 50/push-eax -19396 51/push-ecx -19397 # if (location == 0) return -19398 81 7/subop/compare *(ebp+0xc) 0/imm32 -19399 0f 84/jump-if-= $emit-subx-disp32:end/disp32 -19400 # var v/eax: (addr stmt-var) -19401 (get-stmt-operand-from-arg-location *(ebp+0x10) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18)) # => eax -19402 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -19403 (lookup *eax *(eax+4)) # Var-name Var-name => eax -19404 (write-buffered *(ebp+8) Space) -19405 (write-buffered *(ebp+8) %eax) -19406 # hack: if instruction operation starts with "break", emit ":break" -19407 # var name/ecx: (addr array byte) = lookup(stmt->operation) -19408 8b/-> *(ebp+0x10) 0/r32/eax -19409 (lookup *(eax+4) *(eax+8)) # Stmt1-operation Stmt1-operation => eax -19410 89/<- %ecx 0/r32/eax -19411 { -19412 (string-starts-with? %ecx "break") # => eax -19413 3d/compare-eax-and 0/imm32/false -19414 74/jump-if-= break/disp8 -19415 (write-buffered *(ebp+8) ":break") -19416 } -19417 # hack: if instruction operation starts with "loop", emit ":loop" -19418 { -19419 (string-starts-with? %ecx "loop") # => eax -19420 3d/compare-eax-and 0/imm32/false -19421 74/jump-if-= break/disp8 -19422 (write-buffered *(ebp+8) ":loop") -19423 } -19424 (write-buffered *(ebp+8) "/disp32") -19425 $emit-subx-disp32:end: -19426 # . restore registers -19427 59/pop-to-ecx -19428 58/pop-to-eax -19429 # . epilogue -19430 89/<- %esp 5/r32/ebp -19431 5d/pop-to-ebp -19432 c3/return -19433 -19434 emit-call: # out: (addr buffered-file), stmt: (addr stmt) -19435 # . prologue -19436 55/push-ebp -19437 89/<- %ebp 4/r32/esp -19438 # . save registers -19439 50/push-eax -19440 51/push-ecx -19441 # -19442 (emit-indent *(ebp+8) *Curr-block-depth) -19443 (write-buffered *(ebp+8) "(") -19444 # ecx = stmt -19445 8b/-> *(ebp+0xc) 1/r32/ecx -19446 # - emit function name -19447 (lookup *(ecx+4) *(ecx+8)) # Stmt1-operation Stmt1-operation => eax -19448 (write-buffered *(ebp+8) %eax) -19449 # - emit arguments -19450 # var curr/eax: (addr stmt-var) = lookup(stmt->inouts) -19451 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax -19452 { -19453 # if (curr == null) break -19454 3d/compare-eax-and 0/imm32 -19455 74/jump-if-= break/disp8 -19456 # -19457 (emit-subx-call-operand *(ebp+8) %eax) -19458 # curr = lookup(curr->next) -19459 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax -19460 eb/jump loop/disp8 -19461 } -19462 # -19463 (write-buffered *(ebp+8) ")\n") -19464 $emit-call:end: -19465 # . restore registers -19466 59/pop-to-ecx -19467 58/pop-to-eax -19468 # . epilogue -19469 89/<- %esp 5/r32/ebp -19470 5d/pop-to-ebp -19471 c3/return -19472 -19473 emit-subx-call-operand: # out: (addr buffered-file), s: (addr stmt-var) -19474 # shares code with emit-subx-var-as-rm32 -19475 # . prologue -19476 55/push-ebp -19477 89/<- %ebp 4/r32/esp -19478 # . save registers -19479 50/push-eax -19480 51/push-ecx -19481 56/push-esi -19482 # ecx = s -19483 8b/-> *(ebp+0xc) 1/r32/ecx -19484 # var operand/esi: (addr var) = lookup(s->value) -19485 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax -19486 89/<- %esi 0/r32/eax -19487 # if (operand->register && !s->is-deref?) emit "%__" -19488 { -19489 $emit-subx-call-operand:check-for-register-direct: -19490 81 7/subop/compare *(esi+0x18) 0/imm32 # Var-register -19491 74/jump-if-= break/disp8 -19492 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref -19493 75/jump-if-!= break/disp8 -19494 $emit-subx-call-operand:register-direct: -19495 (write-buffered *(ebp+8) " %") -19496 (lookup *(esi+0x18) *(esi+0x1c)) # Var-register Var-register => eax -19497 (write-buffered *(ebp+8) %eax) -19498 e9/jump $emit-subx-call-operand:end/disp32 -19499 } -19500 # else if (operand->register && s->is-deref?) emit "*__" -19501 { -19502 $emit-subx-call-operand:check-for-register-indirect: -19503 81 7/subop/compare *(esi+0x18) 0/imm32 # Var-register -19504 74/jump-if-= break/disp8 -19505 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref -19506 74/jump-if-= break/disp8 -19507 $emit-subx-call-operand:register-indirect: -19508 (emit-subx-call-operand-register-indirect *(ebp+8) %esi) -19509 e9/jump $emit-subx-call-operand:end/disp32 -19510 } -19511 # else if (operand->stack-offset) emit "*(ebp+__)" -19512 { -19513 81 7/subop/compare *(esi+0x14) 0/imm32 # Var-offset -19514 74/jump-if-= break/disp8 -19515 $emit-subx-call-operand:stack: -19516 (emit-subx-call-operand-stack *(ebp+8) %esi) -19517 e9/jump $emit-subx-call-operand:end/disp32 -19518 } -19519 # else if (operand->type == literal) emit "__" -19520 { -19521 (lookup *(esi+8) *(esi+0xc)) # Var-type Var-type => eax -19522 81 7/subop/compare *(eax+4) 0/imm32 # Type-tree-left -19523 75/jump-if-!= break/disp8 -19524 $emit-subx-call-operand:literal: -19525 (write-buffered *(ebp+8) Space) -19526 (lookup *esi *(esi+4)) # Var-name Var-name => eax -19527 (write-buffered *(ebp+8) %eax) -19528 } -19529 $emit-subx-call-operand:end: -19530 # . restore registers -19531 5e/pop-to-esi -19532 59/pop-to-ecx -19533 58/pop-to-eax -19534 # . epilogue -19535 89/<- %esp 5/r32/ebp -19536 5d/pop-to-ebp -19537 c3/return -19538 -19539 emit-subx-call-operand-register-indirect: # out: (addr buffered-file), v: (addr var) -19540 # . prologue -19541 55/push-ebp -19542 89/<- %ebp 4/r32/esp -19543 # . save registers -19544 50/push-eax -19545 51/push-ecx -19546 56/push-esi -19547 # esi = v -19548 8b/-> *(ebp+0xc) 6/r32/esi -19549 # var size/ecx: int = size-of-deref(v) -19550 (size-of-deref %esi) # => eax -19551 89/<- %ecx 0/r32/eax -19552 # var reg-name/esi: (addr array byte) = lookup(v->register) -19553 (lookup *(esi+0x18) *(esi+0x1c)) # Var-register Var-register => eax -19554 89/<- %esi 0/r32/eax -19555 # TODO: assert size is a multiple of 4 -19556 # var i/eax: int = 0 -19557 b8/copy-to-eax 0/imm32 -19558 { -19559 $emit-subx-call-operand-register-indirect:loop: -19560 # if (i >= size) break -19561 39/compare %eax 1/r32/ecx -19562 7d/jump-if->= break/disp8 -19563 # emit " *(" v->register "+" i ")" -19564 (write-buffered *(ebp+8) " *(") -19565 (write-buffered *(ebp+8) %esi) -19566 (write-buffered *(ebp+8) "+") -19567 (write-int32-hex-buffered *(ebp+8) %eax) -19568 (write-buffered *(ebp+8) ")") -19569 # i += 4 -19570 05/add-to-eax 4/imm32 -19571 # -19572 eb/jump loop/disp8 -19573 } -19574 $emit-subx-call-operand-register-indirect:end: -19575 # . restore registers -19576 5e/pop-to-esi -19577 59/pop-to-ecx -19578 58/pop-to-eax -19579 # . epilogue -19580 89/<- %esp 5/r32/ebp -19581 5d/pop-to-ebp -19582 c3/return -19583 -19584 emit-subx-call-operand-stack: # out: (addr buffered-file), v: (addr var) -19585 # . prologue -19586 55/push-ebp -19587 89/<- %ebp 4/r32/esp -19588 # . save registers -19589 50/push-eax -19590 51/push-ecx -19591 56/push-esi -19592 # esi = v -19593 8b/-> *(ebp+0xc) 6/r32/esi -19594 # var curr/ecx: int = v->offset -19595 8b/-> *(esi+0x14) 1/r32/ecx # Var-offset -19596 # var max/eax: int = v->offset + size-of(v) -19597 (size-of %esi) # => eax -19598 # TODO: assert size is a multiple of 4 -19599 01/add-to %eax 1/r32/ecx -19600 { -19601 $emit-subx-call-operand-stack:loop: -19602 # if (curr >= max) break -19603 39/compare %ecx 0/r32/eax -19604 7d/jump-if->= break/disp8 -19605 # emit " *(ebp+" curr ")" -19606 (write-buffered *(ebp+8) " *(ebp+") -19607 (write-int32-hex-buffered *(ebp+8) %ecx) -19608 (write-buffered *(ebp+8) ")") -19609 # i += 4 -19610 81 0/subop/add %ecx 4/imm32 -19611 # -19612 eb/jump loop/disp8 -19613 } -19614 $emit-subx-call-operand-stack:end: -19615 # . restore registers -19616 5e/pop-to-esi -19617 59/pop-to-ecx -19618 58/pop-to-eax -19619 # . epilogue -19620 89/<- %esp 5/r32/ebp -19621 5d/pop-to-ebp -19622 c3/return -19623 -19624 emit-subx-var-as-rm32: # out: (addr buffered-file), s: (addr stmt-var) -19625 # . prologue -19626 55/push-ebp -19627 89/<- %ebp 4/r32/esp -19628 # . save registers -19629 50/push-eax -19630 51/push-ecx -19631 56/push-esi -19632 # ecx = s -19633 8b/-> *(ebp+0xc) 1/r32/ecx -19634 # var operand/esi: (addr var) = lookup(s->value) -19635 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax -19636 89/<- %esi 0/r32/eax -19637 # if (operand->register && s->is-deref?) emit "*__" -19638 { -19639 $emit-subx-var-as-rm32:check-for-register-indirect: -19640 81 7/subop/compare *(esi+0x18) 0/imm32 # Var-register -19641 74/jump-if-= break/disp8 -19642 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref -19643 74/jump-if-= break/disp8 -19644 $emit-subx-var-as-rm32:register-indirect: -19645 (write-buffered *(ebp+8) " *") -19646 (lookup *(esi+0x18) *(esi+0x1c)) # Var-register Var-register => eax -19647 (write-buffered *(ebp+8) %eax) -19648 e9/jump $emit-subx-var-as-rm32:end/disp32 -19649 } -19650 # if (operand->register && !s->is-deref?) emit "%__" -19651 { -19652 $emit-subx-var-as-rm32:check-for-register-direct: -19653 81 7/subop/compare *(esi+0x18) 0/imm32 # Var-register -19654 74/jump-if-= break/disp8 -19655 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref -19656 75/jump-if-!= break/disp8 -19657 $emit-subx-var-as-rm32:register-direct: -19658 (write-buffered *(ebp+8) " %") -19659 (lookup *(esi+0x18) *(esi+0x1c)) # Var-register Var-register => eax -19660 (write-buffered *(ebp+8) %eax) -19661 e9/jump $emit-subx-var-as-rm32:end/disp32 -19662 } -19663 # else if (operand->stack-offset) emit "*(ebp+__)" -19664 { -19665 81 7/subop/compare *(esi+0x14) 0/imm32 # Var-offset -19666 74/jump-if-= break/disp8 -19667 $emit-subx-var-as-rm32:stack: -19668 (write-buffered *(ebp+8) Space) -19669 (write-buffered *(ebp+8) "*(ebp+") -19670 (write-int32-hex-buffered *(ebp+8) *(esi+0x14)) # Var-offset -19671 (write-buffered *(ebp+8) ")") -19672 } -19673 $emit-subx-var-as-rm32:end: -19674 # . restore registers -19675 5e/pop-to-esi -19676 59/pop-to-ecx -19677 58/pop-to-eax -19678 # . epilogue -19679 89/<- %esp 5/r32/ebp -19680 5d/pop-to-ebp -19681 c3/return -19682 -19683 find-matching-primitive: # primitives: (addr primitive), stmt: (addr stmt) -> result/eax: (addr primitive) -19684 # . prologue -19685 55/push-ebp -19686 89/<- %ebp 4/r32/esp -19687 # . save registers -19688 51/push-ecx -19689 # var curr/ecx: (addr primitive) = primitives -19690 8b/-> *(ebp+8) 1/r32/ecx -19691 { -19692 $find-matching-primitive:loop: -19693 # if (curr == null) break -19694 81 7/subop/compare %ecx 0/imm32 -19695 74/jump-if-= break/disp8 -19696 # if match(curr, stmt) return curr -19697 { -19698 (mu-stmt-matches-primitive? *(ebp+0xc) %ecx) # => eax -19699 3d/compare-eax-and 0/imm32/false -19700 74/jump-if-= break/disp8 -19701 89/<- %eax 1/r32/ecx -19702 eb/jump $find-matching-primitive:end/disp8 -19703 } -19704 $find-matching-primitive:next-primitive: -19705 # curr = curr->next -19706 (lookup *(ecx+0x38) *(ecx+0x3c)) # Primitive-next Primitive-next => eax -19707 89/<- %ecx 0/r32/eax -19708 # -19709 e9/jump loop/disp32 -19710 } -19711 # return null -19712 b8/copy-to-eax 0/imm32 -19713 $find-matching-primitive:end: -19714 # . restore registers -19715 59/pop-to-ecx -19716 # . epilogue -19717 89/<- %esp 5/r32/ebp -19718 5d/pop-to-ebp -19719 c3/return -19720 -19721 mu-stmt-matches-primitive?: # stmt: (addr stmt), primitive: (addr primitive) -> result/eax: boolean -19722 # A mu stmt matches a primitive if the name matches, all the inout vars -19723 # match, and all the output vars match. -19724 # Vars match if types match and registers match. -19725 # In addition, a stmt output matches a primitive's output if types match -19726 # and the primitive has a wildcard register. -19727 # . prologue -19728 55/push-ebp -19729 89/<- %ebp 4/r32/esp -19730 # . save registers -19731 51/push-ecx -19732 52/push-edx -19733 53/push-ebx -19734 56/push-esi -19735 57/push-edi -19736 # ecx = stmt -19737 8b/-> *(ebp+8) 1/r32/ecx -19738 # edx = primitive -19739 8b/-> *(ebp+0xc) 2/r32/edx -19740 { -19741 $mu-stmt-matches-primitive?:check-name: -19742 # if (primitive->name != stmt->operation) return false -19743 # . var esi: (addr array byte) = lookup(stmt->operation) -19744 (lookup *(ecx+4) *(ecx+8)) # Stmt1-operation Stmt1-operation => eax -19745 89/<- %esi 0/r32/eax -19746 # . var edi: (addr array byte) = lookup(primitive->name) -19747 (lookup *edx *(edx+4)) # Primitive-name Primitive-name => eax -19748 89/<- %edi 0/r32/eax -19749 (string-equal? %esi %edi) # => eax -19750 3d/compare-eax-and 0/imm32/false -19751 75/jump-if-!= break/disp8 -19752 b8/copy-to-eax 0/imm32 -19753 e9/jump $mu-stmt-matches-primitive?:end/disp32 -19754 } -19755 # var curr/esi: (addr stmt-var) = lookup(stmt->inouts) -19756 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax -19757 89/<- %esi 0/r32/eax -19758 # var curr2/edi: (addr list var) = lookup(primitive->inouts) -19759 (lookup *(edx+8) *(edx+0xc)) # Primitive-inouts Primitive-inouts => eax -19760 89/<- %edi 0/r32/eax -19761 { -19762 $mu-stmt-matches-primitive?:inouts-loop: -19763 # if (curr == 0 && curr2 == 0) move on to check outputs -19764 { -19765 $mu-stmt-matches-primitive?:check-both-inouts-null: -19766 81 7/subop/compare %esi 0/imm32 -19767 75/jump-if-!= break/disp8 -19768 $mu-stmt-matches-primitive?:stmt-inout-null: -19769 81 7/subop/compare %edi 0/imm32 -19770 0f 84/jump-if-= $mu-stmt-matches-primitive?:check-outputs/disp32 -19771 $mu-stmt-matches-primitive?:stmt-inout-null-and-prim-inout-not-null: -19772 # return false -19773 b8/copy-to-eax 0/imm32/false -19774 e9/jump $mu-stmt-matches-primitive?:end/disp32 -19775 } -19776 # if (curr2 == 0) return false -19777 { -19778 $mu-stmt-matches-primitive?:check-prim-inout-null: -19779 81 7/subop/compare %edi 0/imm32 -19780 75/jump-if-!= break/disp8 -19781 $mu-stmt-matches-primitive?:prim-inout-null: -19782 b8/copy-to-eax 0/imm32/false -19783 e9/jump $mu-stmt-matches-primitive?:end/disp32 -19784 } -19785 # if (curr != curr2) return false -19786 { -19787 $mu-stmt-matches-primitive?:check-inouts-match: -19788 (lookup *edi *(edi+4)) # List-value List-value => eax -19789 (operand-matches-primitive? %esi %eax) # => eax -19790 3d/compare-eax-and 0/imm32/false -19791 75/jump-if-!= break/disp8 -19792 $mu-stmt-matches-primitive?:inouts-match: -19793 b8/copy-to-eax 0/imm32/false -19794 e9/jump $mu-stmt-matches-primitive?:end/disp32 -19795 } -19796 $mu-stmt-matches-primitive?:next-inout: -19797 # curr = lookup(curr->next) -19798 (lookup *(esi+8) *(esi+0xc)) # Stmt-var-next Stmt-var-next => eax -19799 89/<- %esi 0/r32/eax -19800 # curr2 = lookup(curr2->next) -19801 (lookup *(edi+8) *(edi+0xc)) # List-next List-next => eax -19802 89/<- %edi 0/r32/eax -19803 # -19804 e9/jump loop/disp32 -19805 } -19806 $mu-stmt-matches-primitive?:check-outputs: -19807 # var curr/esi: (addr stmt-var) = lookup(stmt->outputs) -19808 (lookup *(ecx+0x14) *(ecx+0x18)) # Stmt1-outputs Stmt1-outputs => eax -19809 89/<- %esi 0/r32/eax -19810 # var curr2/edi: (addr list var) = lookup(primitive->outputs) -19811 (lookup *(edx+0x10) *(edx+0x14)) # Primitive-outputs Primitive-outputs => eax -19812 89/<- %edi 0/r32/eax -19813 { -19814 $mu-stmt-matches-primitive?:outputs-loop: -19815 # if (curr == 0) return (curr2 == 0) -19816 { -19817 $mu-stmt-matches-primitive?:check-both-outputs-null: -19818 81 7/subop/compare %esi 0/imm32 -19819 75/jump-if-!= break/disp8 -19820 { -19821 $mu-stmt-matches-primitive?:stmt-output-null: -19822 81 7/subop/compare %edi 0/imm32 -19823 75/jump-if-!= break/disp8 -19824 $mu-stmt-matches-primitive?:both-outputs-null: -19825 # return true -19826 b8/copy-to-eax 1/imm32 -19827 e9/jump $mu-stmt-matches-primitive?:end/disp32 -19828 } -19829 $mu-stmt-matches-primitive?:stmt-output-null-and-prim-output-not-null: -19830 # return false -19831 b8/copy-to-eax 0/imm32 -19832 e9/jump $mu-stmt-matches-primitive?:end/disp32 -19833 } -19834 # if (curr2 == 0) return false -19835 { -19836 $mu-stmt-matches-primitive?:check-prim-output-null: -19837 81 7/subop/compare %edi 0/imm32 -19838 75/jump-if-!= break/disp8 -19839 $mu-stmt-matches-primitive?:prim-output-is-null: -19840 b8/copy-to-eax 0/imm32 -19841 e9/jump $mu-stmt-matches-primitive?:end/disp32 -19842 } -19843 # if (curr != curr2) return false -19844 { -19845 $mu-stmt-matches-primitive?:check-outputs-match: -19846 (lookup *edi *(edi+4)) # List-value List-value => eax -19847 (operand-matches-primitive? %esi %eax) # => eax -19848 3d/compare-eax-and 0/imm32/false -19849 75/jump-if-!= break/disp8 -19850 $mu-stmt-matches-primitive?:outputs-match: -19851 b8/copy-to-eax 0/imm32 -19852 e9/jump $mu-stmt-matches-primitive?:end/disp32 -19853 } -19854 $mu-stmt-matches-primitive?:next-output: -19855 # curr = lookup(curr->next) -19856 (lookup *(esi+8) *(esi+0xc)) # Stmt-var-next Stmt-var-next => eax -19857 89/<- %esi 0/r32/eax -19858 # curr2 = lookup(curr2->next) -19859 (lookup *(edi+8) *(edi+0xc)) # List-next List-next => eax -19860 89/<- %edi 0/r32/eax -19861 # -19862 e9/jump loop/disp32 -19863 } -19864 $mu-stmt-matches-primitive?:return-true: -19865 b8/copy-to-eax 1/imm32 -19866 $mu-stmt-matches-primitive?:end: -19867 # . restore registers -19868 5f/pop-to-edi -19869 5e/pop-to-esi -19870 5b/pop-to-ebx -19871 5a/pop-to-edx -19872 59/pop-to-ecx -19873 # . epilogue -19874 89/<- %esp 5/r32/ebp -19875 5d/pop-to-ebp -19876 c3/return -19877 -19878 operand-matches-primitive?: # s: (addr stmt-var), prim-var: (addr var) -> result/eax: boolean -19879 # . prologue -19880 55/push-ebp -19881 89/<- %ebp 4/r32/esp -19882 # . save registers -19883 51/push-ecx -19884 52/push-edx -19885 53/push-ebx -19886 56/push-esi -19887 57/push-edi -19888 # ecx = s -19889 8b/-> *(ebp+8) 1/r32/ecx -19890 # var var/esi: (addr var) = lookup(s->value) -19891 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax -19892 89/<- %esi 0/r32/eax -19893 # edi = prim-var -19894 8b/-> *(ebp+0xc) 7/r32/edi -19895 $operand-matches-primitive?:check-type: -19896 # if !category-match?(var->type, prim-var->type) return false -19897 # . var vtype/ebx: (addr type-tree) = lookup(var->type) -19898 (lookup *(esi+8) *(esi+0xc)) # Var-type Var-type => eax -19899 89/<- %ebx 0/r32/eax -19900 # . var ptype/eax: (addr type-tree) = lookup(prim-var->type) -19901 (lookup *(edi+8) *(edi+0xc)) # Var-type Var-type => eax -19902 (subx-type-category-match? %ebx %eax) # => eax -19903 3d/compare-eax-and 0/imm32/false -19904 0f 84/jump-if-= $operand-matches-primitive?:return-false/disp32 -19905 { -19906 $operand-matches-primitive?:check-register: -19907 # if prim-var is in memory and var is in register but dereference, match -19908 { -19909 81 7/subop/compare *(edi+0x18) 0/imm32 # Var-register -19910 0f 85/jump-if-!= break/disp32 -19911 81 7/subop/compare *(esi+0x18) 0/imm32 # Var-register -19912 74/jump-if-= break/disp8 -19913 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref -19914 74/jump-if-= break/disp8 -19915 $operand-matches-primitive?:var-deref-match: -19916 e9/jump $operand-matches-primitive?:return-true/disp32 -19917 } -19918 # if prim-var is in register and var is in register but dereference, no match -19919 { -19920 81 7/subop/compare *(edi+0x18) 0/imm32 # Var-register -19921 0f 84/jump-if-= break/disp32 -19922 81 7/subop/compare *(esi+0x18) 0/imm32 # Var-register -19923 0f 84/jump-if-= break/disp32 -19924 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref -19925 74/jump-if-= break/disp8 -19926 $operand-matches-primitive?:var-deref-no-match: -19927 e9/jump $operand-matches-primitive?:return-false/disp32 -19928 } -19929 # return false if var->register doesn't match prim-var->register -19930 { -19931 # if register addresses are equal, it's a match -19932 # var vreg/ebx: (addr array byte) = lookup(var->register) -19933 (lookup *(esi+0x18) *(esi+0x1c)) # Var-register Var-register => eax -19934 89/<- %ebx 0/r32/eax -19935 # var preg/ecx: (addr array byte) = lookup(prim-var->register) -19936 (lookup *(edi+0x18) *(edi+0x1c)) # Var-register Var-register => eax -19937 89/<- %ecx 0/r32/eax -19938 # if (vreg == preg) break -19939 39/compare %ecx 3/r32/ebx -19940 74/jump-if-= break/disp8 -19941 $operand-matches-primitive?:var-register-no-match: -19942 # if either address is 0, return false -19943 81 7/subop/compare %ebx 0/imm32 -19944 74/jump-if-= $operand-matches-primitive?:return-false/disp8 -19945 81 7/subop/compare %ecx 0/imm32 -19946 74/jump-if-= $operand-matches-primitive?:return-false/disp8 -19947 # if prim-var->register is wildcard, it's a match -19948 (string-equal? %ecx "*") # Any-register => eax -19949 3d/compare-eax-and 0/imm32/false -19950 75/jump-if-!= break/disp8 -19951 $operand-matches-primitive?:wildcard-no-match: -19952 # if string contents aren't equal, return false -19953 (string-equal? %ecx %ebx) # => eax -19954 3d/compare-eax-and 0/imm32/false -19955 74/jump-if-= $operand-matches-primitive?:return-false/disp8 -19956 } -19957 } -19958 $operand-matches-primitive?:return-true: -19959 b8/copy-to-eax 1/imm32/true -19960 eb/jump $operand-matches-primitive?:end/disp8 -19961 $operand-matches-primitive?:return-false: -19962 b8/copy-to-eax 0/imm32/false -19963 $operand-matches-primitive?:end: -19964 # . restore registers -19965 5f/pop-to-edi -19966 5e/pop-to-esi -19967 5b/pop-to-ebx -19968 5a/pop-to-edx -19969 59/pop-to-ecx -19970 # . epilogue -19971 89/<- %esp 5/r32/ebp -19972 5d/pop-to-ebp -19973 c3/return -19974 -19975 find-matching-function: # functions: (addr function), stmt: (addr stmt) -> result/eax: (addr function) -19976 # . prologue -19977 55/push-ebp -19978 89/<- %ebp 4/r32/esp -19979 # . save registers -19980 51/push-ecx -19981 # var curr/ecx: (handle function) = functions -19982 8b/-> *(ebp+8) 1/r32/ecx -19983 { -19984 # if (curr == null) break -19985 81 7/subop/compare %ecx 0/imm32 -19986 74/jump-if-= break/disp8 -19987 #? (write-buffered Stderr "iter\n") -19988 #? (flush Stderr) -19989 # if match(stmt, curr) return curr -19990 { -19991 (mu-stmt-matches-function? *(ebp+0xc) %ecx) # => eax -19992 3d/compare-eax-and 0/imm32/false -19993 74/jump-if-= break/disp8 -19994 89/<- %eax 1/r32/ecx -19995 eb/jump $find-matching-function:end/disp8 -19996 } -19997 # curr = curr->next -19998 (lookup *(ecx+0x20) *(ecx+0x24)) # Function-next Function-next => eax -19999 89/<- %ecx 0/r32/eax -20000 # -20001 eb/jump loop/disp8 -20002 } -20003 # return null -20004 b8/copy-to-eax 0/imm32 -20005 $find-matching-function:end: -20006 # . restore registers -20007 59/pop-to-ecx -20008 # . epilogue -20009 89/<- %esp 5/r32/ebp -20010 5d/pop-to-ebp -20011 c3/return -20012 -20013 # Just compare names; user-defined functions don't support overloading yet. -20014 mu-stmt-matches-function?: # stmt: (addr stmt1), function: (addr function) -> result/eax: boolean -20015 # . prologue -20016 55/push-ebp -20017 89/<- %ebp 4/r32/esp -20018 # . save registers -20019 51/push-ecx -20020 # return function->name == stmt->operation -20021 # ecx = lookup(stmt->operation) -20022 8b/-> *(ebp+8) 0/r32/eax -20023 (lookup *(eax+4) *(eax+8)) # Stmt1-operation Stmt1-operation => eax -20024 89/<- %ecx 0/r32/eax -20025 # eax = lookup(function->name) -20026 8b/-> *(ebp+0xc) 0/r32/eax -20027 (lookup *eax *(eax+4)) # Function-name Function-name => eax -20028 (string-equal? %eax %ecx) # => eax -20029 $mu-stmt-matches-function?:end: -20030 # . restore registers -20031 59/pop-to-ecx -20032 # . epilogue -20033 89/<- %esp 5/r32/ebp -20034 5d/pop-to-ebp -20035 c3/return -20036 -20037 # Type-checking happens elsewhere. This method is for selecting between -20038 # primitives. -20039 subx-type-category-match?: # a: (addr type-tree), b: (addr type-tree) -> result/eax: boolean -20040 # . prologue -20041 55/push-ebp -20042 89/<- %ebp 4/r32/esp -20043 # . save registers -20044 51/push-ecx -20045 # var alit/ecx: boolean = is-literal-type?(a) -20046 (is-simple-mu-type? *(ebp+8) 0) # => eax -20047 89/<- %ecx 0/r32/eax -20048 # var blit/eax: boolean = is-literal-type?(b) -20049 (is-simple-mu-type? *(ebp+0xc) 0) # => eax -20050 # return alit == blit -20051 39/compare %eax 1/r32/ecx -20052 0f 94/set-byte-if-= %al -20053 81 4/subop/and %eax 0xff/imm32 -20054 $subx-type-category-match?:end: -20055 # . restore registers -20056 59/pop-to-ecx -20057 # . epilogue -20058 89/<- %esp 5/r32/ebp -20059 5d/pop-to-ebp -20060 c3/return -20061 -20062 is-simple-mu-type?: # a: (addr type-tree), n: type-id -> result/eax: boolean -20063 # . prologue -20064 55/push-ebp -20065 89/<- %ebp 4/r32/esp -20066 # . save registers -20067 51/push-ecx -20068 # ecx = n -20069 8b/-> *(ebp+0xc) 1/r32/ecx -20070 # return (a->value == n) -20071 8b/-> *(ebp+8) 0/r32/eax -20072 39/compare *(eax+4) 1/r32/ecx # Type-tree-value -20073 0f 94/set-byte-if-= %al -20074 81 4/subop/and %eax 0xff/imm32 -20075 $is-simple-mu-type?:end: -20076 # . restore registers -20077 59/pop-to-ecx -20078 # . epilogue -20079 89/<- %esp 5/r32/ebp -20080 5d/pop-to-ebp -20081 c3/return -20082 -20083 is-mu-addr-type?: # a: (addr type-tree) -> result/eax: boolean -20084 # . prologue -20085 55/push-ebp -20086 89/<- %ebp 4/r32/esp -20087 # eax = a -20088 8b/-> *(ebp+8) 0/r32/eax -20089 # if (!a->is-atom?) a = a->left -20090 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom -20091 { -20092 75/jump-if-!= break/disp8 -20093 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax -20094 } -20095 # return (a->value == addr) -20096 81 7/subop/compare *(eax+4) 2/imm32/addr # Type-tree-value -20097 0f 94/set-byte-if-= %al -20098 81 4/subop/and %eax 0xff/imm32 -20099 $is-mu-addr-type?:end: -20100 # . epilogue -20101 89/<- %esp 5/r32/ebp -20102 5d/pop-to-ebp -20103 c3/return -20104 -20105 is-mu-array-type?: # a: (addr type-tree) -> result/eax: boolean -20106 # . prologue -20107 55/push-ebp -20108 89/<- %ebp 4/r32/esp -20109 # eax = a -20110 8b/-> *(ebp+8) 0/r32/eax -20111 # if (!a->is-atom?) a = a->left -20112 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom -20113 { -20114 75/jump-if-!= break/disp8 -20115 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax -20116 } -20117 # return (a->value == array) -20118 81 7/subop/compare *(eax+4) 3/imm32/array # Type-tree-value -20119 0f 94/set-byte-if-= %al -20120 81 4/subop/and %eax 0xff/imm32 -20121 $is-mu-array-type?:end: -20122 # . epilogue -20123 89/<- %esp 5/r32/ebp -20124 5d/pop-to-ebp -20125 c3/return -20126 -20127 is-mu-stream-type?: # a: (addr type-tree) -> result/eax: boolean -20128 # . prologue -20129 55/push-ebp -20130 89/<- %ebp 4/r32/esp -20131 # eax = a -20132 8b/-> *(ebp+8) 0/r32/eax -20133 # if (!a->is-atom?) a = a->left -20134 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom -20135 { -20136 75/jump-if-!= break/disp8 -20137 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax -20138 } -20139 # return (a->value == stream) -20140 81 7/subop/compare *(eax+4) 0xb/imm32/stream # Type-tree-value -20141 0f 94/set-byte-if-= %al -20142 81 4/subop/and %eax 0xff/imm32 -20143 $is-mu-stream-type?:end: -20144 # . epilogue -20145 89/<- %esp 5/r32/ebp -20146 5d/pop-to-ebp -20147 c3/return -20148 -20149 test-emit-subx-stmt-primitive: -20150 # Primitive operation on a variable on the stack. -20151 # increment foo -20152 # => -20153 # ff 0/subop/increment *(ebp-8) -20154 # -20155 # There's a variable on the var stack as follows: -20156 # name: 'foo' -20157 # type: int -20158 # stack-offset: -8 -20159 # -20160 # There's a primitive with this info: -20161 # name: 'increment' -20162 # inouts: int/mem -20163 # value: 'ff 0/subop/increment' -20164 # -20165 # . prologue -20166 55/push-ebp -20167 89/<- %ebp 4/r32/esp -20168 # setup -20169 (clear-stream _test-output-stream) -20170 (clear-stream $_test-output-buffered-file->buffer) -20171 # simulate allocated payloads starting with an initial fake alloc-id (0x11) -20172 $test-emit-subx-stmt-primitive:initialize-type: -20173 # var type/ecx: (payload type-tree) = int -20174 68/push 0/imm32/right:null -20175 68/push 0/imm32/right:null -20176 68/push 0/imm32/left:unused -20177 68/push 1/imm32/value:int -20178 68/push 1/imm32/is-atom?:true -20179 68/push 0x11/imm32/alloc-id:fake:payload -20180 89/<- %ecx 4/r32/esp -20181 $test-emit-subx-stmt-primitive:initialize-var: -20182 # var var-foo/ecx: (payload var) = var(type) -20183 68/push 0/imm32/no-register -20184 68/push 0/imm32/no-register -20185 68/push -8/imm32/stack-offset -20186 68/push 1/imm32/block-depth -20187 51/push-ecx/type -20188 68/push 0x11/imm32/alloc-id:fake -20189 68/push 0/imm32/name -20190 68/push 0/imm32/name -20191 68/push 0x11/imm32/alloc-id:fake:payload -20192 89/<- %ecx 4/r32/esp -20193 $test-emit-subx-stmt-primitive:initialize-var-name: -20194 # var-foo->name = "foo" -20195 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -20196 (copy-array Heap "foo" %eax) -20197 $test-emit-subx-stmt-primitive:initialize-stmt-var: -20198 # var operand/ebx: (payload stmt-var) = stmt-var(var-foo) -20199 68/push 0/imm32/is-deref:false -20200 68/push 0/imm32/next -20201 68/push 0/imm32/next -20202 51/push-ecx/var-foo -20203 68/push 0x11/imm32/alloc-id:fake -20204 68/push 0x11/imm32/alloc-id:fake:payload -20205 89/<- %ebx 4/r32/esp -20206 $test-emit-subx-stmt-primitive:initialize-stmt: -20207 # var stmt/esi: (addr statement) -20208 68/push 0/imm32/no-outputs -20209 68/push 0/imm32/no-outputs -20210 53/push-ebx/inouts -20211 68/push 0x11/imm32/alloc-id:fake -20212 68/push 0/imm32/operation -20213 68/push 0/imm32/operation -20214 68/push 1/imm32/tag -20215 89/<- %esi 4/r32/esp -20216 $test-emit-subx-stmt-primitive:initialize-stmt-operation: -20217 # stmt->operation = "increment" -20218 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -20219 (copy-array Heap "increment" %eax) -20220 $test-emit-subx-stmt-primitive:initialize-primitive: -20221 # var primitives/ebx: (addr primitive) -20222 68/push 0/imm32/next -20223 68/push 0/imm32/next -20224 68/push 0/imm32/output-is-write-only -20225 68/push 0/imm32/no-disp32 -20226 68/push 0/imm32/no-imm8 -20227 68/push 0/imm32/no-imm32 -20228 68/push 0/imm32/no-r32 -20229 68/push 1/imm32/rm32-is-first-inout -20230 68/push 0/imm32/subx-name -20231 68/push 0/imm32/subx-name -20232 68/push 0/imm32/no-outputs -20233 68/push 0/imm32/no-outputs -20234 53/push-ebx/inouts # hack: reuse stmt-var from call stmt as (list var) in function declaration -20235 68/push 0x11/imm32/alloc-id:fake -20236 68/push 0/imm32/name -20237 68/push 0/imm32/name -20238 89/<- %ebx 4/r32/esp -20239 $test-emit-subx-stmt-primitive:initialize-primitive-name: -20240 # primitives->name = "increment" -20241 (copy-array Heap "increment" %ebx) # Primitive-name -20242 $test-emit-subx-stmt-primitive:initialize-primitive-subx-name: -20243 # primitives->subx-name = "ff 0/subop/increment" -20244 8d/copy-address *(ebx+0x18) 0/r32/eax # Primitive-subx-name -20245 (copy-array Heap "ff 0/subop/increment" %eax) -20246 # convert -20247 c7 0/subop/copy *Curr-block-depth 0/imm32 -20248 (emit-subx-stmt _test-output-buffered-file %esi %ebx Stderr 0) -20249 (flush _test-output-buffered-file) -20250 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -20256 # check output -20257 (check-next-stream-line-equal _test-output-stream "ff 0/subop/increment *(ebp+0xfffffff8)" "F - test-emit-subx-stmt-primitive") -20258 # . epilogue -20259 89/<- %esp 5/r32/ebp -20260 5d/pop-to-ebp -20261 c3/return -20262 -20263 test-emit-subx-stmt-primitive-register: -20264 # Primitive operation on a variable in a register. -20265 # foo <- increment -20266 # => -20267 # ff 0/subop/increment %eax # sub-optimal, but should suffice -20268 # -20269 # There's a variable on the var stack as follows: -20270 # name: 'foo' -20271 # type: int -20272 # register: 'eax' -20273 # -20274 # There's a primitive with this info: -20275 # name: 'increment' -20276 # out: int/reg -20277 # value: 'ff 0/subop/increment' -20278 # -20279 # . prologue -20280 55/push-ebp -20281 89/<- %ebp 4/r32/esp -20282 # setup -20283 (clear-stream _test-output-stream) -20284 (clear-stream $_test-output-buffered-file->buffer) -20285 $test-emit-subx-stmt-primitive-register:initialize-type: -20286 # var type/ecx: (payload type-tree) = int -20287 68/push 0/imm32/right:null -20288 68/push 0/imm32/right:null -20289 68/push 0/imm32/left:unused -20290 68/push 1/imm32/value:int -20291 68/push 1/imm32/is-atom?:true -20292 68/push 0x11/imm32/alloc-id:fake:payload -20293 89/<- %ecx 4/r32/esp -20294 $test-emit-subx-stmt-primitive-register:initialize-var: -20295 # var var-foo/ecx: (payload var) -20296 68/push 0/imm32/register -20297 68/push 0/imm32/register -20298 68/push 0/imm32/no-stack-offset -20299 68/push 1/imm32/block-depth -20300 51/push-ecx -20301 68/push 0x11/imm32/alloc-id:fake -20302 68/push 0/imm32/name -20303 68/push 0/imm32/name -20304 68/push 0x11/imm32/alloc-id:fake:payload -20305 89/<- %ecx 4/r32/esp -20306 $test-emit-subx-stmt-primitive-register:initialize-var-name: -20307 # var-foo->name = "foo" -20308 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -20309 (copy-array Heap "foo" %eax) -20310 $test-emit-subx-stmt-primitive-register:initialize-var-register: -20311 # var-foo->register = "eax" -20312 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 -20313 (copy-array Heap "eax" %eax) -20314 $test-emit-subx-stmt-primitive-register:initialize-stmt-var: -20315 # var operand/ebx: (payload stmt-var) -20316 68/push 0/imm32/is-deref:false -20317 68/push 0/imm32/next -20318 68/push 0/imm32/next -20319 51/push-ecx/var-foo -20320 68/push 0x11/imm32/alloc-id:fake -20321 68/push 0x11/imm32/alloc-id:fake:payload -20322 89/<- %ebx 4/r32/esp -20323 $test-emit-subx-stmt-primitive-register:initialize-stmt: -20324 # var stmt/esi: (addr statement) -20325 53/push-ebx/outputs -20326 68/push 0x11/imm32/alloc-id:fake -20327 68/push 0/imm32/no-inouts -20328 68/push 0/imm32/no-inouts -20329 68/push 0/imm32/operation -20330 68/push 0/imm32/operation -20331 68/push 1/imm32 -20332 89/<- %esi 4/r32/esp -20333 $test-emit-subx-stmt-primitive-register:initialize-stmt-operation: -20334 # stmt->operation = "increment" -20335 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -20336 (copy-array Heap "increment" %eax) -20337 $test-emit-subx-stmt-primitive-register:initialize-formal-var: -20338 # var formal-var/ebx: (payload var) -20339 68/push 0/imm32/register -20340 68/push 0/imm32/register -20341 68/push 0/imm32/no-stack-offset -20342 68/push 1/imm32/block-depth -20343 ff 6/subop/push *(ecx+0x10) # Var-type + payload alloc id + handle alloc id -20344 68/push 0x11/imm32/alloc-id:fake -20345 68/push 0/imm32/name -20346 68/push 0/imm32/name -20347 68/push 0x11/imm32/alloc-id:fake:payload -20348 89/<- %ebx 4/r32/esp -20349 $test-emit-subx-stmt-primitive-register:initialize-formal-var-name: -20350 # formal-var->name = "dummy" -20351 8d/copy-address *(ebx+4) 0/r32/eax # Var-name + 4 -20352 (copy-array Heap "dummy" %eax) -20353 $test-emit-subx-stmt-primitive-register:initialize-formal-register: -20354 # formal-var->register = "*" -20355 8d/copy-address *(ebx+0x1c) 0/r32/eax # Var-register + 4 -20356 (copy-array Heap "*" %eax) # Any-register -20357 $test-emit-subx-stmt-primitive-register:initialize-var-list: -20358 # var formal-outputs/ebx: (payload list var) -20359 68/push 0/imm32/next -20360 68/push 0/imm32/next -20361 53/push-ebx/formal-var -20362 68/push 0x11/imm32/alloc-id:fake -20363 68/push 0x11/imm32/alloc-id:fake:payload -20364 89/<- %ebx 4/r32/esp -20365 $test-emit-subx-stmt-primitive-register:initialize-primitive: -20366 # var primitives/ebx: (addr primitive) -20367 68/push 0/imm32/next -20368 68/push 0/imm32/next -20369 68/push 0/imm32/output-is-write-only -20370 68/push 0/imm32/no-disp32 -20371 68/push 0/imm32/no-imm8 -20372 68/push 0/imm32/no-imm32 -20373 68/push 0/imm32/no-r32 -20374 68/push 3/imm32/rm32-is-first-output -20375 68/push 0/imm32/subx-name -20376 68/push 0/imm32/subx-name -20377 53/push-ebx/outputs -20378 68/push 0x11/imm32/alloc-id:fake -20379 68/push 0/imm32/no-inouts -20380 68/push 0/imm32/no-inouts -20381 68/push 0/imm32/name -20382 68/push 0/imm32/name -20383 89/<- %ebx 4/r32/esp -20384 $test-emit-subx-stmt-primitive-register:initialize-primitive-name: -20385 # primitives->name = "increment" -20386 (copy-array Heap "increment" %ebx) # Primitive-name -20387 $test-emit-subx-stmt-primitive-register:initialize-primitive-subx-name: -20388 # primitives->subx-name = "ff 0/subop/increment" -20389 8d/copy-address *(ebx+0x18) 0/r32/eax # Primitive-subx-name -20390 (copy-array Heap "ff 0/subop/increment" %eax) -20391 # convert -20392 c7 0/subop/copy *Curr-block-depth 0/imm32 -20393 (emit-subx-stmt _test-output-buffered-file %esi %ebx Stderr 0) -20394 (flush _test-output-buffered-file) -20395 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -20401 # check output -20402 (check-next-stream-line-equal _test-output-stream "ff 0/subop/increment %eax" "F - test-emit-subx-stmt-primitive-register") -20403 # . epilogue -20404 89/<- %esp 5/r32/ebp -20405 5d/pop-to-ebp -20406 c3/return -20407 -20408 test-emit-subx-stmt-select-primitive: -20409 # Select the right primitive between overloads. -20410 # foo <- increment -20411 # => -20412 # ff 0/subop/increment %eax # sub-optimal, but should suffice -20413 # -20414 # There's a variable on the var stack as follows: -20415 # name: 'foo' -20416 # type: int -20417 # register: 'eax' -20418 # -20419 # There's two primitives, as follows: -20420 # - name: 'increment' -20421 # out: int/reg -20422 # value: 'ff 0/subop/increment' -20423 # - name: 'increment' -20424 # inout: int/mem -20425 # value: 'ff 0/subop/increment' -20426 # -20427 # . prologue -20428 55/push-ebp -20429 89/<- %ebp 4/r32/esp -20430 # setup -20431 (clear-stream _test-output-stream) -20432 (clear-stream $_test-output-buffered-file->buffer) -20433 $test-emit-subx-stmt-select-primitive:initialize-type: -20434 # var type/ecx: (payload type-tree) = int -20435 68/push 0/imm32/right:null -20436 68/push 0/imm32/right:null -20437 68/push 0/imm32/left:unused -20438 68/push 1/imm32/value:int -20439 68/push 1/imm32/is-atom?:true -20440 68/push 0x11/imm32/alloc-id:fake:payload -20441 89/<- %ecx 4/r32/esp -20442 $test-emit-subx-stmt-select-primitive:initialize-var: -20443 # var var-foo/ecx: (payload var) -20444 68/push 0/imm32/register -20445 68/push 0/imm32/register -20446 68/push 0/imm32/no-stack-offset -20447 68/push 1/imm32/block-depth -20448 51/push-ecx -20449 68/push 0x11/imm32/alloc-id:fake -20450 68/push 0/imm32/name -20451 68/push 0/imm32/name -20452 68/push 0x11/imm32/alloc-id:fake:payload -20453 89/<- %ecx 4/r32/esp -20454 $test-emit-subx-stmt-select-primitive:initialize-var-name: -20455 # var-foo->name = "foo" -20456 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -20457 (copy-array Heap "foo" %eax) -20458 $test-emit-subx-stmt-select-primitive:initialize-var-register: -20459 # var-foo->register = "eax" -20460 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 -20461 (copy-array Heap "eax" %eax) -20462 $test-emit-subx-stmt-select-primitive:initialize-stmt-var: -20463 # var operand/ebx: (payload stmt-var) -20464 68/push 0/imm32/is-deref:false -20465 68/push 0/imm32/next -20466 68/push 0/imm32/next -20467 51/push-ecx/var-foo -20468 68/push 0x11/imm32/alloc-id:fake -20469 68/push 0x11/imm32/alloc-id:fake:payload -20470 89/<- %ebx 4/r32/esp -20471 $test-emit-subx-stmt-select-primitive:initialize-stmt: -20472 # var stmt/esi: (addr statement) -20473 53/push-ebx/outputs -20474 68/push 0x11/imm32/alloc-id:fake -20475 68/push 0/imm32/no-inouts -20476 68/push 0/imm32/no-inouts -20477 68/push 0/imm32/operation -20478 68/push 0/imm32/operation -20479 68/push 1/imm32 -20480 89/<- %esi 4/r32/esp -20481 $test-emit-subx-stmt-select-primitive:initialize-stmt-operation: -20482 # stmt->operation = "increment" -20483 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -20484 (copy-array Heap "increment" %eax) -20485 $test-emit-subx-stmt-select-primitive:initialize-formal-var: -20486 # var formal-var/ebx: (payload var) -20487 68/push 0/imm32/register -20488 68/push 0/imm32/register -20489 68/push 0/imm32/no-stack-offset -20490 68/push 1/imm32/block-depth -20491 ff 6/subop/push *(ecx+0x10) # Var-type + payload alloc id + handle alloc id -20492 68/push 0x11/imm32/alloc-id:fake -20493 68/push 0/imm32/name -20494 68/push 0/imm32/name -20495 68/push 0x11/imm32/alloc-id:fake:payload -20496 89/<- %ebx 4/r32/esp -20497 $test-emit-subx-stmt-select-primitive:initialize-formal-var-name: -20498 # formal-var->name = "dummy" -20499 8d/copy-address *(ebx+4) 0/r32/eax # Var-name + 4 -20500 (copy-array Heap "dummy" %eax) -20501 $test-emit-subx-stmt-select-primitive:initialize-formal-register: -20502 # formal-var->register = "*" -20503 8d/copy-address *(ebx+0x1c) 0/r32/eax # Var-register + 4 -20504 (copy-array Heap "*" %eax) # Any-register -20505 $test-emit-subx-stmt-select-primitive:initialize-var-list: -20506 # var formal-outputs/ebx: (payload list var) -20507 68/push 0/imm32/next -20508 68/push 0/imm32/next -20509 53/push-ebx/formal-var -20510 68/push 0x11/imm32/alloc-id:fake -20511 68/push 0x11/imm32/alloc-id:fake:payload -20512 89/<- %ebx 4/r32/esp -20513 $test-emit-subx-stmt-select-primitive:initialize-primitive2: -20514 # var primitive2/edi: (payload primitive) -20515 68/push 0/imm32/next -20516 68/push 0/imm32/next -20517 68/push 0/imm32/output-is-write-only -20518 68/push 0/imm32/no-disp32 -20519 68/push 0/imm32/no-imm8 -20520 68/push 0/imm32/no-imm32 -20521 68/push 0/imm32/no-r32 -20522 68/push 3/imm32/rm32-is-first-output -20523 68/push 0/imm32/subx-name -20524 68/push 0/imm32/subx-name -20525 53/push-ebx/outputs -20526 68/push 0x11/imm32/alloc-id:fake -20527 68/push 0/imm32/no-inouts -20528 68/push 0/imm32/no-inouts -20529 68/push 0/imm32/name -20530 68/push 0/imm32/name -20531 68/push 0x11/imm32/alloc-id:fake:payload -20532 89/<- %edi 4/r32/esp -20533 $test-emit-subx-stmt-select-primitive:initialize-primitive2-name: -20534 # primitives->name = "increment" -20535 8d/copy-address *(edi+4) 0/r32/eax # Primitive-name + 4 -20536 (copy-array Heap "increment" %eax) -20537 $test-emit-subx-stmt-select-primitive:initialize-primitive2-subx-name: -20538 # primitives->subx-name = "ff 0/subop/increment" -20539 8d/copy-address *(edi+0x1c) 0/r32/eax # Primitive-subx-name + 4 -20540 (copy-array Heap "ff 0/subop/increment" %eax) -20541 $test-emit-subx-stmt-select-primitive:initialize-primitive: -20542 # var primitives/ebx: (addr primitive) -20543 57/push-edi -20544 68/push 0x11/imm32/alloc-id:fake -20545 68/push 0/imm32/output-is-write-only -20546 68/push 0/imm32/no-disp32 -20547 68/push 0/imm32/no-imm8 -20548 68/push 0/imm32/no-imm32 -20549 68/push 0/imm32/no-r32 -20550 68/push 1/imm32/rm32-is-first-inout -20551 68/push 0/imm32/subx-name -20552 68/push 0/imm32/subx-name -20553 68/push 0/imm32/no-outputs -20554 68/push 0/imm32/no-outputs -20555 53/push-ebx/inouts # hack: reuse stmt-var from call stmt as (list var) in function declaration -20556 68/push 0x11/imm32/alloc-id:fake -20557 68/push 0/imm32/name -20558 68/push 0/imm32/name -20559 89/<- %ebx 4/r32/esp -20560 $test-emit-subx-stmt-select-primitive:initialize-primitive-name: -20561 # primitives->name = "increment" -20562 (copy-array Heap "increment" %ebx) # Primitive-name -20563 $test-emit-subx-stmt-select-primitive:initialize-primitive-subx-name: -20564 # primitives->subx-name = "ff 0/subop/increment" -20565 8d/copy-address *(ebx+0x18) 0/r32/eax # Primitive-subx-name -20566 (copy-array Heap "ff 0/subop/increment" %eax) -20567 # convert -20568 c7 0/subop/copy *Curr-block-depth 0/imm32 -20569 (emit-subx-stmt _test-output-buffered-file %esi %ebx Stderr 0) -20570 (flush _test-output-buffered-file) -20571 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -20577 # check output -20578 (check-next-stream-line-equal _test-output-stream "ff 0/subop/increment %eax" "F - test-emit-subx-stmt-select-primitive") -20579 # . epilogue -20580 89/<- %esp 5/r32/ebp -20581 5d/pop-to-ebp -20582 c3/return -20583 -20584 test-emit-subx-stmt-select-primitive-2: -20585 # Select the right primitive between overloads. -20586 # increment foo -20587 # => -20588 # ff 0/subop/increment %eax # sub-optimal, but should suffice -20589 # -20590 # There's a variable on the var stack as follows: -20591 # name: 'foo' -20592 # type: int -20593 # register: 'eax' -20594 # -20595 # There's two primitives, as follows: -20596 # - name: 'increment' -20597 # out: int/reg -20598 # value: 'ff 0/subop/increment' -20599 # - name: 'increment' -20600 # inout: int/mem -20601 # value: 'ff 0/subop/increment' -20602 # -20603 # . prologue -20604 55/push-ebp -20605 89/<- %ebp 4/r32/esp -20606 # setup -20607 (clear-stream _test-output-stream) -20608 (clear-stream $_test-output-buffered-file->buffer) -20609 $test-emit-subx-stmt-select-primitive-2:initialize-type: -20610 # var type/ecx: (payload type-tree) = int -20611 68/push 0/imm32/right:null -20612 68/push 0/imm32/right:null -20613 68/push 0/imm32/left:unused -20614 68/push 1/imm32/value:int -20615 68/push 1/imm32/is-atom?:true -20616 68/push 0x11/imm32/alloc-id:fake:payload -20617 89/<- %ecx 4/r32/esp -20618 $test-emit-subx-stmt-select-primitive-2:initialize-var: -20619 # var var-foo/ecx: (payload var) -20620 68/push 0/imm32/register -20621 68/push 0/imm32/register -20622 68/push 0/imm32/no-stack-offset -20623 68/push 1/imm32/block-depth -20624 51/push-ecx -20625 68/push 0x11/imm32/alloc-id:fake -20626 68/push 0/imm32/name -20627 68/push 0/imm32/name -20628 68/push 0x11/imm32/alloc-id:fake:payload -20629 89/<- %ecx 4/r32/esp -20630 $test-emit-subx-stmt-select-primitive-2:initialize-var-name: -20631 # var-foo->name = "foo" -20632 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -20633 (copy-array Heap "foo" %eax) -20634 $test-emit-subx-stmt-select-primitive-2:initialize-var-register: -20635 # var-foo->register = "eax" -20636 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 -20637 (copy-array Heap "eax" %eax) -20638 $test-emit-subx-stmt-select-primitive-2:initialize-stmt-var: -20639 # var operand/ebx: (payload stmt-var) -20640 68/push 0/imm32/is-deref:false -20641 68/push 0/imm32/next -20642 68/push 0/imm32/next -20643 51/push-ecx/var-foo -20644 68/push 0x11/imm32/alloc-id:fake -20645 68/push 0x11/imm32/alloc-id:fake:payload -20646 89/<- %ebx 4/r32/esp -20647 $test-emit-subx-stmt-select-primitive-2:initialize-stmt: -20648 # var stmt/esi: (addr statement) -20649 68/push 0/imm32/no-outputs -20650 68/push 0/imm32/no-outputs -20651 53/push-ebx/inouts -20652 68/push 0x11/imm32/alloc-id:fake -20653 68/push 0/imm32/operation -20654 68/push 0/imm32/operation -20655 68/push 1/imm32 -20656 89/<- %esi 4/r32/esp -20657 $test-emit-subx-stmt-select-primitive-2:initialize-stmt-operation: -20658 # stmt->operation = "increment" -20659 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -20660 (copy-array Heap "increment" %eax) -20661 $test-emit-subx-stmt-select-primitive-2:initialize-formal-var: -20662 # var formal-var/ebx: (payload var) -20663 68/push 0/imm32/register -20664 68/push 0/imm32/register -20665 68/push 0/imm32/no-stack-offset -20666 68/push 1/imm32/block-depth -20667 ff 6/subop/push *(ecx+0x10) # Var-type + payload alloc id + handle alloc id -20668 68/push 0x11/imm32/alloc-id:fake -20669 68/push 0/imm32/name -20670 68/push 0/imm32/name -20671 68/push 0x11/imm32/alloc-id:fake:payload -20672 89/<- %ebx 4/r32/esp -20673 $test-emit-subx-stmt-select-primitive-2:initialize-formal-var-name: -20674 # formal-var->name = "dummy" -20675 8d/copy-address *(ebx+4) 0/r32/eax # Var-name + 4 -20676 (copy-array Heap "dummy" %eax) -20677 $test-emit-subx-stmt-select-primitive-2:initialize-formal-register: -20678 # formal-var->register = "*" -20679 8d/copy-address *(ebx+0x1c) 0/r32/eax # Var-register + 4 -20680 (copy-array Heap "*" %eax) # Any-register -20681 $test-emit-subx-stmt-select-primitive-2:initialize-var-list: -20682 # var formal-outputs/ebx: (payload list stmt-var) -20683 68/push 0/imm32/next -20684 68/push 0/imm32/next -20685 53/push-ebx/formal-var -20686 68/push 0x11/imm32/alloc-id:fake -20687 68/push 0x11/imm32/alloc-id:fake:payload -20688 89/<- %ebx 4/r32/esp -20689 $test-emit-subx-stmt-select-primitive-2:initialize-primitive2: -20690 # var primitive2/edi: (payload primitive) -20691 68/push 0/imm32/next -20692 68/push 0/imm32/next -20693 68/push 0/imm32/output-is-write-only -20694 68/push 0/imm32/no-disp32 -20695 68/push 0/imm32/no-imm8 -20696 68/push 0/imm32/no-imm32 -20697 68/push 0/imm32/no-r32 -20698 68/push 3/imm32/rm32-is-first-output -20699 68/push 0/imm32/subx-name -20700 68/push 0/imm32/subx-name -20701 53/push-ebx/outputs -20702 68/push 0x11/imm32/alloc-id:fake -20703 68/push 0/imm32/no-inouts -20704 68/push 0/imm32/no-inouts -20705 68/push 0/imm32/name -20706 68/push 0/imm32/name -20707 68/push 0x11/imm32/alloc-id:fake:payload -20708 89/<- %edi 4/r32/esp -20709 $test-emit-subx-stmt-select-primitive-2:initialize-primitive2-name: -20710 # primitives->name = "increment" -20711 8d/copy-address *(edi+4) 0/r32/eax # Primitive-name + 4 -20712 (copy-array Heap "increment" %eax) -20713 $test-emit-subx-stmt-select-primitive-2:initialize-primitive2-subx-name: -20714 # primitives->subx-name = "ff 0/subop/increment" -20715 8d/copy-address *(edi+0x1c) 0/r32/eax # Primitive-subx-name + 4 -20716 (copy-array Heap "ff 0/subop/increment" %eax) -20717 $test-emit-subx-stmt-select-primitive-2:initialize-primitive: -20718 # var primitives/ebx: (addr primitive) -20719 57/push-edi -20720 68/push 0x11/imm32/alloc-id:fake -20721 68/push 0/imm32/output-is-write-only -20722 68/push 0/imm32/no-disp32 -20723 68/push 0/imm32/no-imm8 -20724 68/push 0/imm32/no-imm32 -20725 68/push 0/imm32/no-r32 -20726 68/push 1/imm32/rm32-is-first-inout -20727 68/push 0/imm32/subx-name -20728 68/push 0/imm32/subx-name -20729 68/push 0/imm32/no-outputs -20730 68/push 0/imm32/no-outputs -20731 53/push-ebx/inouts # hack: reuse stmt-var from call stmt as (list var) in function declaration -20732 68/push 0x11/imm32/alloc-id:fake -20733 68/push 0/imm32/name -20734 68/push 0/imm32/name -20735 89/<- %ebx 4/r32/esp -20736 $test-emit-subx-stmt-select-primitive-2:initialize-primitive-name: -20737 # primitives->name = "increment" -20738 (copy-array Heap "increment" %ebx) # Primitive-name -20739 $test-emit-subx-stmt-select-primitive-2:initialize-primitive-subx-name: -20740 # primitives->subx-name = "ff 0/subop/increment" -20741 8d/copy-address *(ebx+0x18) 0/r32/eax # Primitive-subx-name -20742 (copy-array Heap "ff 0/subop/increment" %eax) -20743 # convert -20744 c7 0/subop/copy *Curr-block-depth 0/imm32 -20745 (emit-subx-stmt _test-output-buffered-file %esi %ebx Stderr 0) -20746 (flush _test-output-buffered-file) -20747 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -20753 # check output -20754 (check-next-stream-line-equal _test-output-stream "ff 0/subop/increment %eax" "F - test-emit-subx-stmt-select-primitive-2") -20755 # . epilogue -20756 89/<- %esp 5/r32/ebp -20757 5d/pop-to-ebp -20758 c3/return -20759 -20760 test-increment-register: -20761 # Select the right register between overloads. -20762 # foo <- increment -20763 # => -20764 # 50/increment-eax -20765 # -20766 # There's a variable on the var stack as follows: -20767 # name: 'foo' -20768 # type: int -20769 # register: 'eax' -20770 # -20771 # Primitives are the global definitions. -20772 # -20773 # . prologue -20774 55/push-ebp -20775 89/<- %ebp 4/r32/esp -20776 # setup -20777 (clear-stream _test-output-stream) -20778 (clear-stream $_test-output-buffered-file->buffer) -20779 $test-increment-register:initialize-type: -20780 # var type/ecx: (payload type-tree) = int -20781 68/push 0/imm32/right:null -20782 68/push 0/imm32/right:null -20783 68/push 0/imm32/left:unused -20784 68/push 1/imm32/value:int -20785 68/push 1/imm32/is-atom?:true -20786 68/push 0x11/imm32/alloc-id:fake:payload -20787 89/<- %ecx 4/r32/esp -20788 $test-increment-register:initialize-var: -20789 # var var-foo/ecx: (payload var) -20790 68/push 0/imm32/register -20791 68/push 0/imm32/register -20792 68/push 0/imm32/no-stack-offset -20793 68/push 1/imm32/block-depth -20794 51/push-ecx -20795 68/push 0x11/imm32/alloc-id:fake -20796 68/push 0/imm32/name -20797 68/push 0/imm32/name -20798 68/push 0x11/imm32/alloc-id:fake:payload -20799 89/<- %ecx 4/r32/esp -20800 $test-increment-register:initialize-var-name: -20801 # var-foo->name = "foo" -20802 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -20803 (copy-array Heap "foo" %eax) -20804 $test-increment-register:initialize-var-register: -20805 # var-foo->register = "eax" -20806 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 -20807 (copy-array Heap "eax" %eax) -20808 $test-increment-register:initialize-stmt-var: -20809 # var operand/ebx: (payload stmt-var) -20810 68/push 0/imm32/is-deref:false -20811 68/push 0/imm32/next -20812 68/push 0/imm32/next -20813 51/push-ecx/var-foo -20814 68/push 0x11/imm32/alloc-id:fake -20815 68/push 0x11/imm32/alloc-id:fake:payload -20816 89/<- %ebx 4/r32/esp -20817 $test-increment-register:initialize-stmt: -20818 # var stmt/esi: (addr statement) -20819 53/push-ebx/outputs -20820 68/push 0x11/imm32/alloc-id:fake -20821 68/push 0/imm32/no-inouts -20822 68/push 0/imm32/no-inouts -20823 68/push 0/imm32/operation -20824 68/push 0/imm32/operation -20825 68/push 1/imm32 -20826 89/<- %esi 4/r32/esp -20827 $test-increment-register:initialize-stmt-operation: -20828 # stmt->operation = "increment" -20829 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -20830 (copy-array Heap "increment" %eax) -20831 # convert -20832 c7 0/subop/copy *Curr-block-depth 0/imm32 -20833 (emit-subx-stmt _test-output-buffered-file %esi Primitives Stderr 0) -20834 (flush _test-output-buffered-file) -20835 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -20841 # check output -20842 (check-next-stream-line-equal _test-output-stream "40/increment-eax" "F - test-increment-register") -20843 # . epilogue -20844 89/<- %esp 5/r32/ebp -20845 5d/pop-to-ebp -20846 c3/return -20847 -20848 test-add-reg-to-reg: -20849 # var1/reg <- add var2/reg -20850 # => -20851 # 01/add-to %var1 var2 -20852 # +19138 _string-loop/imm32/name +19139 0/imm32/no-inouts +19140 0/imm32/no-inouts +19141 0/imm32/no-outputs +19142 0/imm32/no-outputs +19143 0x11/imm32/alloc-id:fake +19144 _string_e9_jump_loop/imm32/subx-name +19145 0/imm32/no-rm32 +19146 0/imm32/no-r32 +19147 0/imm32/no-imm32 +19148 0/imm32/no-imm8 +19149 0/imm32/no-disp32 +19150 0/imm32/no-output +19151 0x11/imm32/alloc-id:fake +19152 _Primitive-break-if-addr<-named/imm32/next +19153 # - branches to named blocks +19154 _Primitive-break-if-addr<-named: # (payload primitive) +19155 0x11/imm32/alloc-id:fake:payload +19156 0x11/imm32/alloc-id:fake +19157 _string-break-if-addr</imm32/name +19158 0x11/imm32/alloc-id:fake +19159 Single-lit-var/imm32/inouts +19160 0/imm32/no-outputs +19161 0/imm32/no-outputs +19162 0x11/imm32/alloc-id:fake +19163 _string_0f_82_jump_label/imm32/subx-name +19164 0/imm32/no-rm32 +19165 0/imm32/no-r32 +19166 0/imm32/no-imm32 +19167 0/imm32/no-imm8 +19168 1/imm32/disp32-is-first-inout +19169 0/imm32/no-output +19170 0x11/imm32/alloc-id:fake +19171 _Primitive-break-if-addr>=-named/imm32/next +19172 _Primitive-break-if-addr>=-named: # (payload primitive) +19173 0x11/imm32/alloc-id:fake:payload +19174 0x11/imm32/alloc-id:fake +19175 _string-break-if-addr>=/imm32/name +19176 0x11/imm32/alloc-id:fake +19177 Single-lit-var/imm32/inouts +19178 0/imm32/no-outputs +19179 0/imm32/no-outputs +19180 0x11/imm32/alloc-id:fake +19181 _string_0f_83_jump_label/imm32/subx-name +19182 0/imm32/no-rm32 +19183 0/imm32/no-r32 +19184 0/imm32/no-imm32 +19185 0/imm32/no-imm8 +19186 1/imm32/disp32-is-first-inout +19187 0/imm32/no-output +19188 0x11/imm32/alloc-id:fake +19189 _Primitive-break-if-=-named/imm32/next +19190 _Primitive-break-if-=-named: # (payload primitive) +19191 0x11/imm32/alloc-id:fake:payload +19192 0x11/imm32/alloc-id:fake +19193 _string-break-if-=/imm32/name +19194 0x11/imm32/alloc-id:fake +19195 Single-lit-var/imm32/inouts +19196 0/imm32/no-outputs +19197 0/imm32/no-outputs +19198 0x11/imm32/alloc-id:fake +19199 _string_0f_84_jump_label/imm32/subx-name +19200 0/imm32/no-rm32 +19201 0/imm32/no-r32 +19202 0/imm32/no-imm32 +19203 0/imm32/no-imm8 +19204 1/imm32/disp32-is-first-inout +19205 0/imm32/no-output +19206 0x11/imm32/alloc-id:fake +19207 _Primitive-break-if-!=-named/imm32/next +19208 _Primitive-break-if-!=-named: # (payload primitive) +19209 0x11/imm32/alloc-id:fake:payload +19210 0x11/imm32/alloc-id:fake +19211 _string-break-if-!=/imm32/name +19212 0x11/imm32/alloc-id:fake +19213 Single-lit-var/imm32/inouts +19214 0/imm32/no-outputs +19215 0/imm32/no-outputs +19216 0x11/imm32/alloc-id:fake +19217 _string_0f_85_jump_label/imm32/subx-name +19218 0/imm32/no-rm32 +19219 0/imm32/no-r32 +19220 0/imm32/no-imm32 +19221 0/imm32/no-imm8 +19222 1/imm32/disp32-is-first-inout +19223 0/imm32/no-output +19224 0x11/imm32/alloc-id:fake +19225 _Primitive-break-if-addr<=-named/imm32/next +19226 _Primitive-break-if-addr<=-named: # (payload primitive) +19227 0x11/imm32/alloc-id:fake:payload +19228 0x11/imm32/alloc-id:fake +19229 _string-break-if-addr<=/imm32/name +19230 0x11/imm32/alloc-id:fake +19231 Single-lit-var/imm32/inouts +19232 0/imm32/no-outputs +19233 0/imm32/no-outputs +19234 0x11/imm32/alloc-id:fake +19235 _string_0f_86_jump_label/imm32/subx-name +19236 0/imm32/no-rm32 +19237 0/imm32/no-r32 +19238 0/imm32/no-imm32 +19239 0/imm32/no-imm8 +19240 1/imm32/disp32-is-first-inout +19241 0/imm32/no-output +19242 0x11/imm32/alloc-id:fake +19243 _Primitive-break-if-addr>-named/imm32/next +19244 _Primitive-break-if-addr>-named: # (payload primitive) +19245 0x11/imm32/alloc-id:fake:payload +19246 0x11/imm32/alloc-id:fake +19247 _string-break-if-addr>/imm32/name +19248 0x11/imm32/alloc-id:fake +19249 Single-lit-var/imm32/inouts +19250 0/imm32/no-outputs +19251 0/imm32/no-outputs +19252 0x11/imm32/alloc-id:fake +19253 _string_0f_87_jump_label/imm32/subx-name +19254 0/imm32/no-rm32 +19255 0/imm32/no-r32 +19256 0/imm32/no-imm32 +19257 0/imm32/no-imm8 +19258 1/imm32/disp32-is-first-inout +19259 0/imm32/no-output +19260 0x11/imm32/alloc-id:fake +19261 _Primitive-break-if-<-named/imm32/next +19262 _Primitive-break-if-<-named: # (payload primitive) +19263 0x11/imm32/alloc-id:fake:payload +19264 0x11/imm32/alloc-id:fake +19265 _string-break-if-</imm32/name +19266 0x11/imm32/alloc-id:fake +19267 Single-lit-var/imm32/inouts +19268 0/imm32/no-outputs +19269 0/imm32/no-outputs +19270 0x11/imm32/alloc-id:fake +19271 _string_0f_8c_jump_label/imm32/subx-name +19272 0/imm32/no-rm32 +19273 0/imm32/no-r32 +19274 0/imm32/no-imm32 +19275 0/imm32/no-imm8 +19276 1/imm32/disp32-is-first-inout +19277 0/imm32/no-output +19278 0x11/imm32/alloc-id:fake +19279 _Primitive-break-if->=-named/imm32/next +19280 _Primitive-break-if->=-named: # (payload primitive) +19281 0x11/imm32/alloc-id:fake:payload +19282 0x11/imm32/alloc-id:fake +19283 _string-break-if->=/imm32/name +19284 0x11/imm32/alloc-id:fake +19285 Single-lit-var/imm32/inouts +19286 0/imm32/no-outputs +19287 0/imm32/no-outputs +19288 0x11/imm32/alloc-id:fake +19289 _string_0f_8d_jump_label/imm32/subx-name +19290 0/imm32/no-rm32 +19291 0/imm32/no-r32 +19292 0/imm32/no-imm32 +19293 0/imm32/no-imm8 +19294 1/imm32/disp32-is-first-inout +19295 0/imm32/no-output +19296 0x11/imm32/alloc-id:fake +19297 _Primitive-break-if-<=-named/imm32/next +19298 _Primitive-break-if-<=-named: # (payload primitive) +19299 0x11/imm32/alloc-id:fake:payload +19300 0x11/imm32/alloc-id:fake +19301 _string-break-if-<=/imm32/name +19302 0x11/imm32/alloc-id:fake +19303 Single-lit-var/imm32/inouts +19304 0/imm32/no-outputs +19305 0/imm32/no-outputs +19306 0x11/imm32/alloc-id:fake +19307 _string_0f_8e_jump_label/imm32/subx-name +19308 0/imm32/no-rm32 +19309 0/imm32/no-r32 +19310 0/imm32/no-imm32 +19311 0/imm32/no-imm8 +19312 1/imm32/disp32-is-first-inout +19313 0/imm32/no-output +19314 0x11/imm32/alloc-id:fake +19315 _Primitive-break-if->-named/imm32/next +19316 _Primitive-break-if->-named: # (payload primitive) +19317 0x11/imm32/alloc-id:fake:payload +19318 0x11/imm32/alloc-id:fake +19319 _string-break-if->/imm32/name +19320 0x11/imm32/alloc-id:fake +19321 Single-lit-var/imm32/inouts +19322 0/imm32/no-outputs +19323 0/imm32/no-outputs +19324 0x11/imm32/alloc-id:fake +19325 _string_0f_8f_jump_label/imm32/subx-name +19326 0/imm32/no-rm32 +19327 0/imm32/no-r32 +19328 0/imm32/no-imm32 +19329 0/imm32/no-imm8 +19330 1/imm32/disp32-is-first-inout +19331 0/imm32/no-output +19332 0x11/imm32/alloc-id:fake +19333 _Primitive-break-named/imm32/next +19334 _Primitive-break-named: # (payload primitive) +19335 0x11/imm32/alloc-id:fake:payload +19336 0x11/imm32/alloc-id:fake +19337 _string-break/imm32/name +19338 0x11/imm32/alloc-id:fake +19339 Single-lit-var/imm32/inouts +19340 0/imm32/no-outputs +19341 0/imm32/no-outputs +19342 0x11/imm32/alloc-id:fake +19343 _string_e9_jump_label/imm32/subx-name +19344 0/imm32/no-rm32 +19345 0/imm32/no-r32 +19346 0/imm32/no-imm32 +19347 0/imm32/no-imm8 +19348 1/imm32/disp32-is-first-inout +19349 0/imm32/no-output +19350 0x11/imm32/alloc-id:fake +19351 _Primitive-loop-if-addr<-named/imm32/next +19352 _Primitive-loop-if-addr<-named: # (payload primitive) +19353 0x11/imm32/alloc-id:fake:payload +19354 0x11/imm32/alloc-id:fake +19355 _string-loop-if-addr</imm32/name +19356 0x11/imm32/alloc-id:fake +19357 Single-lit-var/imm32/inouts +19358 0/imm32/no-outputs +19359 0/imm32/no-outputs +19360 0x11/imm32/alloc-id:fake +19361 _string_0f_82_jump_label/imm32/subx-name +19362 0/imm32/no-rm32 +19363 0/imm32/no-r32 +19364 0/imm32/no-imm32 +19365 0/imm32/no-imm8 +19366 1/imm32/disp32-is-first-inout +19367 0/imm32/no-output +19368 0x11/imm32/alloc-id:fake +19369 _Primitive-loop-if-addr>=-named/imm32/next +19370 _Primitive-loop-if-addr>=-named: # (payload primitive) +19371 0x11/imm32/alloc-id:fake:payload +19372 0x11/imm32/alloc-id:fake +19373 _string-loop-if-addr>=/imm32/name +19374 0x11/imm32/alloc-id:fake +19375 Single-lit-var/imm32/inouts +19376 0/imm32/no-outputs +19377 0/imm32/no-outputs +19378 0x11/imm32/alloc-id:fake +19379 _string_0f_83_jump_label/imm32/subx-name +19380 0/imm32/no-rm32 +19381 0/imm32/no-r32 +19382 0/imm32/no-imm32 +19383 0/imm32/no-imm8 +19384 1/imm32/disp32-is-first-inout +19385 0/imm32/no-output +19386 0x11/imm32/alloc-id:fake +19387 _Primitive-loop-if-=-named/imm32/next +19388 _Primitive-loop-if-=-named: # (payload primitive) +19389 0x11/imm32/alloc-id:fake:payload +19390 0x11/imm32/alloc-id:fake +19391 _string-loop-if-=/imm32/name +19392 0x11/imm32/alloc-id:fake +19393 Single-lit-var/imm32/inouts +19394 0/imm32/no-outputs +19395 0/imm32/no-outputs +19396 0x11/imm32/alloc-id:fake +19397 _string_0f_84_jump_label/imm32/subx-name +19398 0/imm32/no-rm32 +19399 0/imm32/no-r32 +19400 0/imm32/no-imm32 +19401 0/imm32/no-imm8 +19402 1/imm32/disp32-is-first-inout +19403 0/imm32/no-output +19404 0x11/imm32/alloc-id:fake +19405 _Primitive-loop-if-!=-named/imm32/next +19406 _Primitive-loop-if-!=-named: # (payload primitive) +19407 0x11/imm32/alloc-id:fake:payload +19408 0x11/imm32/alloc-id:fake +19409 _string-loop-if-!=/imm32/name +19410 0x11/imm32/alloc-id:fake +19411 Single-lit-var/imm32/inouts +19412 0/imm32/no-outputs +19413 0/imm32/no-outputs +19414 0x11/imm32/alloc-id:fake +19415 _string_0f_85_jump_label/imm32/subx-name +19416 0/imm32/no-rm32 +19417 0/imm32/no-r32 +19418 0/imm32/no-imm32 +19419 0/imm32/no-imm8 +19420 1/imm32/disp32-is-first-inout +19421 0/imm32/no-output +19422 0x11/imm32/alloc-id:fake +19423 _Primitive-loop-if-addr<=-named/imm32/next +19424 _Primitive-loop-if-addr<=-named: # (payload primitive) +19425 0x11/imm32/alloc-id:fake:payload +19426 0x11/imm32/alloc-id:fake +19427 _string-loop-if-addr<=/imm32/name +19428 0x11/imm32/alloc-id:fake +19429 Single-lit-var/imm32/inouts +19430 0/imm32/no-outputs +19431 0/imm32/no-outputs +19432 0x11/imm32/alloc-id:fake +19433 _string_0f_86_jump_label/imm32/subx-name +19434 0/imm32/no-rm32 +19435 0/imm32/no-r32 +19436 0/imm32/no-imm32 +19437 0/imm32/no-imm8 +19438 1/imm32/disp32-is-first-inout +19439 0/imm32/no-output +19440 0x11/imm32/alloc-id:fake +19441 _Primitive-loop-if-addr>-named/imm32/next +19442 _Primitive-loop-if-addr>-named: # (payload primitive) +19443 0x11/imm32/alloc-id:fake:payload +19444 0x11/imm32/alloc-id:fake +19445 _string-loop-if-addr>/imm32/name +19446 0x11/imm32/alloc-id:fake +19447 Single-lit-var/imm32/inouts +19448 0/imm32/no-outputs +19449 0/imm32/no-outputs +19450 0x11/imm32/alloc-id:fake +19451 _string_0f_87_jump_label/imm32/subx-name +19452 0/imm32/no-rm32 +19453 0/imm32/no-r32 +19454 0/imm32/no-imm32 +19455 0/imm32/no-imm8 +19456 1/imm32/disp32-is-first-inout +19457 0/imm32/no-output +19458 0x11/imm32/alloc-id:fake +19459 _Primitive-loop-if-<-named/imm32/next +19460 _Primitive-loop-if-<-named: # (payload primitive) +19461 0x11/imm32/alloc-id:fake:payload +19462 0x11/imm32/alloc-id:fake +19463 _string-loop-if-</imm32/name +19464 0x11/imm32/alloc-id:fake +19465 Single-lit-var/imm32/inouts +19466 0/imm32/no-outputs +19467 0/imm32/no-outputs +19468 0x11/imm32/alloc-id:fake +19469 _string_0f_8c_jump_label/imm32/subx-name +19470 0/imm32/no-rm32 +19471 0/imm32/no-r32 +19472 0/imm32/no-imm32 +19473 0/imm32/no-imm8 +19474 1/imm32/disp32-is-first-inout +19475 0/imm32/no-output +19476 0x11/imm32/alloc-id:fake +19477 _Primitive-loop-if->=-named/imm32/next +19478 _Primitive-loop-if->=-named: # (payload primitive) +19479 0x11/imm32/alloc-id:fake:payload +19480 0x11/imm32/alloc-id:fake +19481 _string-loop-if->=/imm32/name +19482 0x11/imm32/alloc-id:fake +19483 Single-lit-var/imm32/inouts +19484 0/imm32/no-outputs +19485 0/imm32/no-outputs +19486 0x11/imm32/alloc-id:fake +19487 _string_0f_8d_jump_label/imm32/subx-name +19488 0/imm32/no-rm32 +19489 0/imm32/no-r32 +19490 0/imm32/no-imm32 +19491 0/imm32/no-imm8 +19492 1/imm32/disp32-is-first-inout +19493 0/imm32/no-output +19494 0x11/imm32/alloc-id:fake +19495 _Primitive-loop-if-<=-named/imm32/next +19496 _Primitive-loop-if-<=-named: # (payload primitive) +19497 0x11/imm32/alloc-id:fake:payload +19498 0x11/imm32/alloc-id:fake +19499 _string-loop-if-<=/imm32/name +19500 0x11/imm32/alloc-id:fake +19501 Single-lit-var/imm32/inouts +19502 0/imm32/no-outputs +19503 0/imm32/no-outputs +19504 0x11/imm32/alloc-id:fake +19505 _string_0f_8e_jump_label/imm32/subx-name +19506 0/imm32/no-rm32 +19507 0/imm32/no-r32 +19508 0/imm32/no-imm32 +19509 0/imm32/no-imm8 +19510 1/imm32/disp32-is-first-inout +19511 0/imm32/no-output +19512 0x11/imm32/alloc-id:fake +19513 _Primitive-loop-if->-named/imm32/next +19514 _Primitive-loop-if->-named: # (payload primitive) +19515 0x11/imm32/alloc-id:fake:payload +19516 0x11/imm32/alloc-id:fake +19517 _string-loop-if->/imm32/name +19518 0x11/imm32/alloc-id:fake +19519 Single-lit-var/imm32/inouts +19520 0/imm32/no-outputs +19521 0/imm32/no-outputs +19522 0x11/imm32/alloc-id:fake +19523 _string_0f_8f_jump_label/imm32/subx-name +19524 0/imm32/no-rm32 +19525 0/imm32/no-r32 +19526 0/imm32/no-imm32 +19527 0/imm32/no-imm8 +19528 1/imm32/disp32-is-first-inout +19529 0/imm32/no-output +19530 0x11/imm32/alloc-id:fake +19531 _Primitive-loop-named/imm32/next # we probably don't need an unconditional break +19532 _Primitive-loop-named: # (payload primitive) +19533 0x11/imm32/alloc-id:fake:payload +19534 0x11/imm32/alloc-id:fake +19535 _string-loop/imm32/name +19536 0x11/imm32/alloc-id:fake +19537 Single-lit-var/imm32/inouts +19538 0/imm32/no-outputs +19539 0/imm32/no-outputs +19540 0x11/imm32/alloc-id:fake +19541 _string_e9_jump_label/imm32/subx-name +19542 0/imm32/no-rm32 +19543 0/imm32/no-r32 +19544 0/imm32/no-imm32 +19545 0/imm32/no-imm8 +19546 1/imm32/disp32-is-first-inout +19547 0/imm32/no-output +19548 0/imm32/next +19549 0/imm32/next +19550 +19551 # string literals for Mu instructions +19552 _string-add: # (payload array byte) +19553 0x11/imm32/alloc-id:fake:payload +19554 # "add" +19555 0x3/imm32/size +19556 0x61/a 0x64/d 0x64/d +19557 _string-address: # (payload array byte) +19558 0x11/imm32/alloc-id:fake:payload +19559 # "address" +19560 0x7/imm32/size +19561 0x61/a 0x64/d 0x64/d 0x72/r 0x65/e 0x73/s 0x73/s +19562 _string-add-to: # (payload array byte) +19563 0x11/imm32/alloc-id:fake:payload +19564 # "add-to" +19565 0x6/imm32/size +19566 0x61/a 0x64/d 0x64/d 0x2d/dash 0x74/t 0x6f/o +19567 _string-and: # (payload array byte) +19568 0x11/imm32/alloc-id:fake:payload +19569 # "and" +19570 0x3/imm32/size +19571 0x61/a 0x6e/n 0x64/d +19572 _string-and-with: # (payload array byte) +19573 0x11/imm32/alloc-id:fake:payload +19574 # "and-with" +19575 0x8/imm32/size +19576 0x61/a 0x6e/n 0x64/d 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h +19577 _string-break: # (payload array byte) +19578 0x11/imm32/alloc-id:fake:payload +19579 # "break" +19580 0x5/imm32/size +19581 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k +19582 _string-break-if-<: # (payload array byte) +19583 0x11/imm32/alloc-id:fake:payload +19584 # "break-if-<" +19585 0xa/imm32/size +19586 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/< +19587 _string-break-if-<=: # (payload array byte) +19588 0x11/imm32/alloc-id:fake:payload +19589 # "break-if-<=" +19590 0xb/imm32/size +19591 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/< 0x3d/= +19592 _string-break-if-=: # (payload array byte) +19593 0x11/imm32/alloc-id:fake:payload +19594 # "break-if-=" +19595 0xa/imm32/size +19596 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3d/= +19597 _string-break-if->: # (payload array byte) +19598 0x11/imm32/alloc-id:fake:payload +19599 # "break-if->" +19600 0xa/imm32/size +19601 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/> +19602 _string-break-if->=: # (payload array byte) +19603 0x11/imm32/alloc-id:fake:payload +19604 # "break-if->=" +19605 0xb/imm32/size +19606 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/> 0x3d/= +19607 _string-break-if-!=: # (payload array byte) +19608 0x11/imm32/alloc-id:fake:payload +19609 # "break-if-!=" +19610 0xb/imm32/size +19611 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x21/! 0x3d/= +19612 _string-break-if-addr<: # (payload array byte) +19613 0x11/imm32/alloc-id:fake:payload +19614 # "break-if-addr<" +19615 0xe/imm32/size +19616 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3c/< +19617 _string-break-if-addr<=: # (payload array byte) +19618 0x11/imm32/alloc-id:fake:payload +19619 # "break-if-addr<=" +19620 0xf/imm32/size +19621 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3c/< 0x3d/= +19622 _string-break-if-addr>: # (payload array byte) +19623 0x11/imm32/alloc-id:fake:payload +19624 # "break-if-addr>" +19625 0xe/imm32/size +19626 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3e/> +19627 _string-break-if-addr>=: # (payload array byte) +19628 0x11/imm32/alloc-id:fake:payload +19629 # "break-if-addr>=" +19630 0xf/imm32/size +19631 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3e/> 0x3d/= +19632 _string-compare: # (payload array byte) +19633 0x11/imm32/alloc-id:fake:payload +19634 # "compare" +19635 0x7/imm32/size +19636 0x63/c 0x6f/o 0x6d/m 0x70/p 0x61/a 0x72/r 0x65/e +19637 _string-copy: # (payload array byte) +19638 0x11/imm32/alloc-id:fake:payload +19639 # "copy" +19640 0x4/imm32/size +19641 0x63/c 0x6f/o 0x70/p 0x79/y +19642 _string-copy-to: # (payload array byte) +19643 0x11/imm32/alloc-id:fake:payload +19644 # "copy-to" +19645 0x7/imm32/size +19646 0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/dash 0x74/t 0x6f/o +19647 _string-copy-byte: +19648 0x11/imm32/alloc-id:fake:payload +19649 # "copy-byte" +19650 0x9/imm32/size +19651 0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/- 0x62/b 0x79/y 0x74/t 0x65/e +19652 _string-copy-byte-to: +19653 0x11/imm32/alloc-id:fake:payload +19654 # "copy-byte-to" +19655 0xc/imm32/size +19656 0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/- 0x62/b 0x79/y 0x74/t 0x65/e 0x2d/- 0x74/t 0x6f/o +19657 _string-decrement: # (payload array byte) +19658 0x11/imm32/alloc-id:fake:payload +19659 # "decrement" +19660 0x9/imm32/size +19661 0x64/d 0x65/e 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t +19662 _string-increment: # (payload array byte) +19663 0x11/imm32/alloc-id:fake:payload +19664 # "increment" +19665 0x9/imm32/size +19666 0x69/i 0x6e/n 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t +19667 _string-loop: # (payload array byte) +19668 0x11/imm32/alloc-id:fake:payload +19669 # "loop" +19670 0x4/imm32/size +19671 0x6c/l 0x6f/o 0x6f/o 0x70/p +19672 _string-loop-if-<: # (payload array byte) +19673 0x11/imm32/alloc-id:fake:payload +19674 # "loop-if-<" +19675 0x9/imm32/size +19676 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/< +19677 _string-loop-if-<=: # (payload array byte) +19678 0x11/imm32/alloc-id:fake:payload +19679 # "loop-if-<=" +19680 0xa/imm32/size +19681 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/< 0x3d/= +19682 _string-loop-if-=: # (payload array byte) +19683 0x11/imm32/alloc-id:fake:payload +19684 # "loop-if-=" +19685 0x9/imm32/size +19686 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3d/= +19687 _string-loop-if->: # (payload array byte) +19688 0x11/imm32/alloc-id:fake:payload +19689 # "loop-if->" +19690 0x9/imm32/size +19691 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/> +19692 _string-loop-if->=: # (payload array byte) +19693 0x11/imm32/alloc-id:fake:payload +19694 # "loop-if->=" +19695 0xa/imm32/size +19696 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/> 0x3d/= +19697 _string-loop-if-!=: # (payload array byte) +19698 0x11/imm32/alloc-id:fake:payload +19699 # "loop-if-!=" +19700 0xa/imm32/size +19701 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x21/! 0x3d/= +19702 _string-loop-if-addr<: # (payload array byte) +19703 0x11/imm32/alloc-id:fake:payload +19704 # "loop-if-addr<" +19705 0xd/imm32/size +19706 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3c/< +19707 _string-loop-if-addr<=: # (payload array byte) +19708 0x11/imm32/alloc-id:fake:payload +19709 # "loop-if-addr<=" +19710 0xe/imm32/size +19711 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3c/< 0x3d/= +19712 _string-loop-if-addr>: # (payload array byte) +19713 0x11/imm32/alloc-id:fake:payload +19714 # "loop-if-addr>" +19715 0xd/imm32/size +19716 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3e/> +19717 _string-loop-if-addr>=: # (payload array byte) +19718 0x11/imm32/alloc-id:fake:payload +19719 # "loop-if-addr>=" +19720 0xe/imm32/size +19721 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3e/> 0x3d/= +19722 _string-multiply: # (payload array byte) +19723 0x11/imm32/alloc-id:fake:payload +19724 # "multiply" +19725 0x8/imm32/size +19726 0x6d/m 0x75/u 0x6c/l 0x74/t 0x69/i 0x70/p 0x6c/l 0x79/y +19727 _string-or: # (payload array byte) +19728 0x11/imm32/alloc-id:fake:payload +19729 # "or" +19730 0x2/imm32/size +19731 0x6f/o 0x72/r +19732 _string-or-with: # (payload array byte) +19733 0x11/imm32/alloc-id:fake:payload +19734 # "or-with" +19735 0x7/imm32/size +19736 0x6f/o 0x72/r 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h +19737 _string-subtract: # (payload array byte) +19738 0x11/imm32/alloc-id:fake:payload +19739 # "subtract" +19740 0x8/imm32/size +19741 0x73/s 0x75/u 0x62/b 0x74/t 0x72/r 0x61/a 0x63/c 0x74/t +19742 _string-subtract-from: # (payload array byte) +19743 0x11/imm32/alloc-id:fake:payload +19744 # "subtract-from" +19745 0xd/imm32/size +19746 0x73/s 0x75/u 0x62/b 0x74/t 0x72/r 0x61/a 0x63/c 0x74/t 0x2d/dash 0x66/f 0x72/r 0x6f/o 0x6d/m +19747 _string-xor: # (payload array byte) +19748 0x11/imm32/alloc-id:fake:payload +19749 # "xor" +19750 0x3/imm32/size +19751 0x78/x 0x6f/o 0x72/r +19752 _string-xor-with: # (payload array byte) +19753 0x11/imm32/alloc-id:fake:payload +19754 # "xor-with" +19755 0x8/imm32/size +19756 0x78/x 0x6f/o 0x72/r 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h +19757 _string-shift-left: # (payload array byte) +19758 0x11/imm32/alloc-id:fake:payload +19759 # "shift-left" +19760 0xa/imm32/size +19761 0x73/s 0x68/h 0x69/i 0x66/f 0x74/t 0x2d/dash 0x6c/l 0x65/e 0x66/f 0x74/t +19762 _string-shift-right: # (payload array byte) +19763 0x11/imm32/alloc-id:fake:payload +19764 # "shift-right" +19765 0xb/imm32/size +19766 0x73/s 0x68/h 0x69/i 0x66/f 0x74/t 0x2d/dash 0x72/r 0x69/i 0x67/g 0x68/h 0x74/t +19767 _string-shift-right-signed: # (payload array byte) +19768 0x11/imm32/alloc-id:fake:payload +19769 # "shift-right-signed" +19770 0x12/imm32/size +19771 0x73/s 0x68/h 0x69/i 0x66/f 0x74/t 0x2d/dash 0x72/r 0x69/i 0x67/g 0x68/h 0x74/t 0x2d/dash 0x73/s 0x69/i 0x67/g 0x6e/n 0x65/e 0x64/d +19772 +19773 # string literals for SubX instructions +19774 _string_01_add_to: # (payload array byte) +19775 0x11/imm32/alloc-id:fake:payload +19776 # "01/add-to" +19777 0x9/imm32/size +19778 0x30/0 0x31/1 0x2f/slash 0x61/a 0x64/d 0x64/d 0x2d/dash 0x74/t 0x6f/o +19779 _string_03_add: # (payload array byte) +19780 0x11/imm32/alloc-id:fake:payload +19781 # "03/add" +19782 0x6/imm32/size +19783 0x30/0 0x33/3 0x2f/slash 0x61/a 0x64/d 0x64/d +19784 _string_05_add_to_eax: # (payload array byte) +19785 0x11/imm32/alloc-id:fake:payload +19786 # "05/add-to-eax" +19787 0xd/imm32/size +19788 0x30/0 0x35/5 0x2f/slash 0x61/a 0x64/d 0x64/d 0x2d/dash 0x74/t 0x6f/o 0x2d/dash 0x65/e 0x61/a 0x78/x +19789 _string_09_or_with: # (payload array byte) +19790 0x11/imm32/alloc-id:fake:payload +19791 # "09/or-with" +19792 0xa/imm32/size +19793 0x30/0 0x39/9 0x2f/slash 0x6f/o 0x72/r 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h +19794 _string_0b_or: # (payload array byte) +19795 0x11/imm32/alloc-id:fake:payload +19796 # "0b/or" +19797 0x5/imm32/size +19798 0x30/0 0x62/b 0x2f/slash 0x6f/o 0x72/r +19799 _string_0d_or_with_eax: # (payload array byte) +19800 0x11/imm32/alloc-id:fake:payload +19801 # "0d/or-with-eax" +19802 0xe/imm32/size +19803 0x30/0 0x64/d 0x2f/slash 0x6f/o 0x72/r 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h 0x2d/dash 0x65/e 0x61/a 0x78/x +19804 _string_0f_82_jump_label: # (payload array byte) +19805 0x11/imm32/alloc-id:fake:payload +19806 # "0f 82/jump-if-addr<" +19807 0x13/imm32/size +19808 0x30/0 0x66/f 0x20/space 0x38/8 0x32/2 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3c/< +19809 _string_0f_82_jump_break: # (payload array byte) +19810 0x11/imm32/alloc-id:fake:payload +19811 # "0f 82/jump-if-addr< break/disp32" +19812 0x20/imm32/size +19813 0x30/0 0x66/f 0x20/space 0x38/8 0x32/2 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3c/< 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 +19814 _string_0f_82_jump_loop: # (payload array byte) +19815 0x11/imm32/alloc-id:fake:payload +19816 # "0f 82/jump-if-addr< loop/disp32" +19817 0x1f/imm32/size +19818 0x30/0 0x66/f 0x20/space 0x38/8 0x32/2 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3c/< 0x20/space 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 +19819 _string_0f_83_jump_label: # (payload array byte) +19820 0x11/imm32/alloc-id:fake:payload +19821 # "0f 83/jump-if-addr>=" +19822 0x14/imm32/size +19823 0x30/0 0x66/f 0x20/space 0x38/8 0x33/3 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3e/> 0x3d/= +19824 _string_0f_83_jump_break: # (payload array byte) +19825 0x11/imm32/alloc-id:fake:payload +19826 # "0f 83/jump-if-addr>= break/disp32" +19827 0x21/imm32/size +19828 0x30/0 0x66/f 0x20/space 0x38/8 0x33/3 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3e/> 0x3d/= 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 +19829 _string_0f_83_jump_loop: # (payload array byte) +19830 0x11/imm32/alloc-id:fake:payload +19831 # "0f 83/jump-if-addr>= loop/disp32" +19832 0x20/imm32/size +19833 0x30/0 0x66/f 0x20/space 0x38/8 0x33/3 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3e/> 0x3d/= 0x20/space 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 +19834 _string_0f_84_jump_label: # (payload array byte) +19835 0x11/imm32/alloc-id:fake:payload +19836 # "0f 84/jump-if-=" +19837 0xf/imm32/size +19838 0x30/0 0x66/f 0x20/space 0x38/8 0x34/4 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3d/= +19839 _string_0f_84_jump_break: # (payload array byte) +19840 0x11/imm32/alloc-id:fake:payload +19841 # "0f 84/jump-if-= break/disp32" +19842 0x1c/imm32/size +19843 0x30/0 0x66/f 0x20/space 0x38/8 0x34/4 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3d/= 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 +19844 _string_0f_84_jump_loop: # (payload array byte) +19845 0x11/imm32/alloc-id:fake:payload +19846 # "0f 84/jump-if-= loop/disp32" +19847 0x1b/imm32/size +19848 0x30/0 0x66/f 0x20/space 0x38/8 0x34/4 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3d/= 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 +19849 _string_0f_85_jump_label: # (payload array byte) +19850 0x11/imm32/alloc-id:fake:payload +19851 # "0f 85/jump-if-!=" +19852 0x10/imm32/size +19853 0x30/0 0x66/f 0x20/space 0x38/8 0x35/5 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x21/! 0x3d/= +19854 _string_0f_85_jump_break: # (payload array byte) +19855 0x11/imm32/alloc-id:fake:payload +19856 # "0f 85/jump-if-!= break/disp32" +19857 0x1d/imm32/size +19858 0x30/0 0x66/f 0x20/space 0x38/8 0x35/5 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x21/! 0x3d/= 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 +19859 _string_0f_85_jump_loop: # (payload array byte) +19860 0x11/imm32/alloc-id:fake:payload +19861 # "0f 85/jump-if-!= loop/disp32" +19862 0x1c/imm32/size +19863 0x30/0 0x66/f 0x20/space 0x38/8 0x35/5 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x21/! 0x3d/= 0x20/space 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 +19864 _string_0f_86_jump_label: # (payload array byte) +19865 0x11/imm32/alloc-id:fake:payload +19866 # "0f 86/jump-if-addr<=" +19867 0x14/imm32/size +19868 0x30/0 0x66/f 0x20/space 0x38/8 0x36/6 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3c/< 0x3d/= +19869 _string_0f_86_jump_break: # (payload array byte) +19870 0x11/imm32/alloc-id:fake:payload +19871 # "0f 86/jump-if-addr<= break/disp32" +19872 0x21/imm32/size +19873 0x30/0 0x66/f 0x20/space 0x38/8 0x36/6 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3c/< 0x3d/= 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 +19874 _string_0f_86_jump_loop: # (payload array byte) +19875 0x11/imm32/alloc-id:fake:payload +19876 # "0f 86/jump-if-addr<= loop/disp32" +19877 0x20/imm32/size +19878 0x30/0 0x66/f 0x20/space 0x38/8 0x36/6 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3c/< 0x3d/= 0x20/space 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 +19879 _string_0f_87_jump_label: # (payload array byte) +19880 0x11/imm32/alloc-id:fake:payload +19881 # "0f 87/jump-if-addr>" +19882 0x13/imm32/size +19883 0x30/0 0x66/f 0x20/space 0x38/8 0x37/7 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3e/> +19884 _string_0f_87_jump_break: # (payload array byte) +19885 0x11/imm32/alloc-id:fake:payload +19886 # "0f 87/jump-if-addr> break/disp32" +19887 0x20/imm32/size +19888 0x30/0 0x66/f 0x20/space 0x38/8 0x37/7 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3e/> 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 +19889 _string_0f_87_jump_loop: # (payload array byte) +19890 0x11/imm32/alloc-id:fake:payload +19891 # "0f 87/jump-if-addr> loop/disp32" +19892 0x1f/imm32/size +19893 0x30/0 0x66/f 0x20/space 0x38/8 0x37/7 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3e/> 0x20/space 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 +19894 _string_0f_8c_jump_label: # (payload array byte) +19895 0x11/imm32/alloc-id:fake:payload +19896 # "0f 8c/jump-if-<" +19897 0xf/imm32/size +19898 0x30/0 0x66/f 0x20/space 0x38/8 0x63/c 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/< +19899 _string_0f_8c_jump_break: # (payload array byte) +19900 0x11/imm32/alloc-id:fake:payload +19901 # "0f 8c/jump-if-< break/disp32" +19902 0x1c/imm32/size +19903 0x30/0 0x66/f 0x20/space 0x38/8 0x63/c 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/< 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 +19904 _string_0f_8c_jump_loop: # (payload array byte) +19905 0x11/imm32/alloc-id:fake:payload +19906 # "0f 8c/jump-if-< loop/disp32" +19907 0x1b/imm32/size +19908 0x30/0 0x66/f 0x20/space 0x38/8 0x63/c 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/< 0x20/space 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 +19909 _string_0f_8d_jump_label: # (payload array byte) +19910 0x11/imm32/alloc-id:fake:payload +19911 # "0f 8d/jump-if->=" +19912 0x10/imm32/size +19913 0x30/0 0x66/f 0x20/space 0x38/8 0x64/d 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/> 0x3d/= +19914 _string_0f_8d_jump_break: # (payload array byte) +19915 0x11/imm32/alloc-id:fake:payload +19916 # "0f 8d/jump-if->= break/disp32" +19917 0x1d/imm32/size +19918 0x30/0 0x66/f 0x20/space 0x38/8 0x64/d 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/> 0x3d/= 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 +19919 _string_0f_8d_jump_loop: # (payload array byte) +19920 0x11/imm32/alloc-id:fake:payload +19921 # "0f 8d/jump-if->= loop/disp32" +19922 0x1c/imm32/size +19923 0x30/0 0x66/f 0x20/space 0x38/8 0x64/d 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/> 0x3d/= 0x20/space 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 +19924 _string_0f_8e_jump_label: # (payload array byte) +19925 0x11/imm32/alloc-id:fake:payload +19926 # "0f 8e/jump-if-<=" +19927 0x10/imm32/size +19928 0x30/0 0x66/f 0x20/space 0x38/8 0x65/e 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/< 0x3d/= +19929 _string_0f_8e_jump_break: # (payload array byte) +19930 0x11/imm32/alloc-id:fake:payload +19931 # "0f 8e/jump-if-<= break/disp32" +19932 0x1d/imm32/size +19933 0x30/0 0x66/f 0x20/space 0x38/8 0x65/e 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/< 0x3d/= 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 +19934 _string_0f_8e_jump_loop: # (payload array byte) +19935 0x11/imm32/alloc-id:fake:payload +19936 # "0f 8e/jump-if-<= loop/disp32" +19937 0x1c/imm32/size +19938 0x30/0 0x66/f 0x20/space 0x38/8 0x65/e 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/< 0x3d/= 0x20/space 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 +19939 _string_0f_8f_jump_label: # (payload array byte) +19940 0x11/imm32/alloc-id:fake:payload +19941 # "0f 8f/jump-if->" +19942 0xf/imm32/size +19943 0x30/0 0x66/f 0x20/space 0x38/8 0x66/f 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/> +19944 _string_0f_8f_jump_break: # (payload array byte) +19945 0x11/imm32/alloc-id:fake:payload +19946 # "0f 8f/jump-if-> break/disp32" +19947 0x1c/imm32/size +19948 0x30/0 0x66/f 0x20/space 0x38/8 0x66/f 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/> 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 +19949 _string_0f_8f_jump_loop: # (payload array byte) +19950 0x11/imm32/alloc-id:fake:payload +19951 # "0f 8f/jump-if-> loop/disp32" +19952 0x1b/imm32/size +19953 0x30/0 0x66/f 0x20/space 0x38/8 0x66/f 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/> 0x20/space 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 +19954 _string_0f_af_multiply: # (payload array byte) +19955 0x11/imm32/alloc-id:fake:payload +19956 # "0f af/multiply" +19957 0xe/imm32/size +19958 0x30/0 0x66/f 0x20/space 0x61/a 0x66/f 0x2f/slash 0x6d/m 0x75/u 0x6c/l 0x74/t 0x69/i 0x70/p 0x6c/l 0x79/y +19959 _string_21_and_with: # (payload array byte) +19960 0x11/imm32/alloc-id:fake:payload +19961 # "21/and-with" +19962 0xb/imm32/size +19963 0x32/2 0x31/1 0x2f/slash 0x61/a 0x6e/n 0x64/d 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h +19964 _string_23_and: # (payload array byte) +19965 0x11/imm32/alloc-id:fake:payload +19966 # "23/and" +19967 0x6/imm32/size +19968 0x32/2 0x33/3 0x2f/slash 0x61/a 0x6e/n 0x64/d +19969 _string_25_and_with_eax: # (payload array byte) +19970 0x11/imm32/alloc-id:fake:payload +19971 # "25/and-with-eax" +19972 0xf/imm32/size +19973 0x32/2 0x35/5 0x2f/slash 0x61/a 0x6e/n 0x64/d 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h 0x2d/dash 0x65/e 0x61/a 0x78/x +19974 _string_29_subtract_from: # (payload array byte) +19975 0x11/imm32/alloc-id:fake:payload +19976 # "29/subtract-from" +19977 0x10/imm32/size +19978 0x32/2 0x39/9 0x2f/slash 0x73/s 0x75/u 0x62/b 0x74/t 0x72/r 0x61/a 0x63/c 0x74/t 0x2d/dash 0x66/f 0x72/r 0x6f/o 0x6d/m +19979 _string_2b_subtract: # (payload array byte) +19980 0x11/imm32/alloc-id:fake:payload +19981 # "2b/subtract" +19982 0xb/imm32/size +19983 0x32/2 0x62/b 0x2f/slash 0x73/s 0x75/u 0x62/b 0x74/t 0x72/r 0x61/a 0x63/c 0x74/t +19984 _string_2d_subtract_from_eax: # (payload array byte) +19985 0x11/imm32/alloc-id:fake:payload +19986 # "2d/subtract-from-eax" +19987 0x14/imm32/size +19988 0x32/2 0x64/d 0x2f/slash 0x73/s 0x75/u 0x62/b 0x74/t 0x72/r 0x61/a 0x63/c 0x74/t 0x2d/dash 0x66/f 0x72/r 0x6f/o 0x6d/m 0x2d/dash 0x65/e 0x61/a 0x78/x +19989 _string_31_xor_with: # (payload array byte) +19990 0x11/imm32/alloc-id:fake:payload +19991 # "31/xor-with" +19992 0xb/imm32/size +19993 0x33/3 0x31/1 0x2f/slash 0x78/x 0x6f/o 0x72/r 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h +19994 _string_33_xor: # (payload array byte) +19995 0x11/imm32/alloc-id:fake:payload +19996 # "33/xor" +19997 0x6/imm32/size +19998 0x33/3 0x33/3 0x2f/slash 0x78/x 0x6f/o 0x72/r +19999 _string_35_xor_with_eax: # (payload array byte) +20000 0x11/imm32/alloc-id:fake:payload +20001 # "35/xor-with-eax" +20002 0xf/imm32/size +20003 0x33/3 0x35/5 0x2f/slash 0x78/x 0x6f/o 0x72/r 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h 0x2d/dash 0x65/e 0x61/a 0x78/x +20004 _string_39_compare->: # (payload array byte) +20005 0x11/imm32/alloc-id:fake:payload +20006 # "39/compare->" +20007 0xc/imm32/size +20008 0x33/3 0x39/9 0x2f/slash 0x63/c 0x6f/o 0x6d/m 0x70/p 0x61/a 0x72/r 0x65/e 0x2d/dash 0x3e/> +20009 _string_3b_compare<-: # (payload array byte) +20010 0x11/imm32/alloc-id:fake:payload +20011 # "3b/compare<-" +20012 0xc/imm32/size +20013 0x33/3 0x62/b 0x2f/slash 0x63/c 0x6f/o 0x6d/m 0x70/p 0x61/a 0x72/r 0x65/e 0x3c/< 0x2d/dash +20014 _string_3d_compare_eax_with: # (payload array byte) +20015 0x11/imm32/alloc-id:fake:payload +20016 # "3d/compare-eax-with" +20017 0x13/imm32/size +20018 0x33/3 0x64/d 0x2f/slash 0x63/c 0x6f/o 0x6d/m 0x70/p 0x61/a 0x72/r 0x65/e 0x2d/dash 0x65/e 0x61/a 0x78/x 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h +20019 _string_40_increment_eax: # (payload array byte) +20020 0x11/imm32/alloc-id:fake:payload +20021 # "40/increment-eax" +20022 0x10/imm32/size +20023 0x34/4 0x30/0 0x2f/slash 0x69/i 0x6e/n 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t 0x2d/dash 0x65/e 0x61/a 0x78/x +20024 _string_41_increment_ecx: # (payload array byte) +20025 0x11/imm32/alloc-id:fake:payload +20026 # "41/increment-ecx" +20027 0x10/imm32/size +20028 0x34/4 0x31/1 0x2f/slash 0x69/i 0x6e/n 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t 0x2d/dash 0x65/e 0x63/c 0x78/x +20029 _string_42_increment_edx: # (payload array byte) +20030 0x11/imm32/alloc-id:fake:payload +20031 # "42/increment-edx" +20032 0x10/imm32/size +20033 0x34/4 0x32/2 0x2f/slash 0x69/i 0x6e/n 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t 0x2d/dash 0x65/e 0x64/d 0x78/x +20034 _string_43_increment_ebx: # (payload array byte) +20035 0x11/imm32/alloc-id:fake:payload +20036 # "43/increment-ebx" +20037 0x10/imm32/size +20038 0x34/4 0x33/3 0x2f/slash 0x69/i 0x6e/n 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t 0x2d/dash 0x65/e 0x62/b 0x78/x +20039 _string_46_increment_esi: # (payload array byte) +20040 0x11/imm32/alloc-id:fake:payload +20041 # "46/increment-esi" +20042 0x10/imm32/size +20043 0x34/4 0x36/6 0x2f/slash 0x69/i 0x6e/n 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t 0x2d/dash 0x65/e 0x73/s 0x69/i +20044 _string_47_increment_edi: # (payload array byte) +20045 0x11/imm32/alloc-id:fake:payload +20046 # "47/increment-edi" +20047 0x10/imm32/size +20048 0x34/4 0x37/7 0x2f/slash 0x69/i 0x6e/n 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t 0x2d/dash 0x65/e 0x64/d 0x69/i +20049 _string_48_decrement_eax: # (payload array byte) +20050 0x11/imm32/alloc-id:fake:payload +20051 # "48/decrement-eax" +20052 0x10/imm32/size +20053 0x34/4 0x38/8 0x2f/slash 0x64/d 0x65/e 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t 0x2d/dash 0x65/e 0x61/a 0x78/x +20054 _string_49_decrement_ecx: # (payload array byte) +20055 0x11/imm32/alloc-id:fake:payload +20056 # "49/decrement-ecx" +20057 0x10/imm32/size +20058 0x34/4 0x39/9 0x2f/slash 0x64/d 0x65/e 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t 0x2d/dash 0x65/e 0x63/c 0x78/x +20059 _string_4a_decrement_edx: # (payload array byte) +20060 0x11/imm32/alloc-id:fake:payload +20061 # "4a/decrement-edx" +20062 0x10/imm32/size +20063 0x34/4 0x61/a 0x2f/slash 0x64/d 0x65/e 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t 0x2d/dash 0x65/e 0x64/d 0x78/x +20064 _string_4b_decrement_ebx: # (payload array byte) +20065 0x11/imm32/alloc-id:fake:payload +20066 # "4b/decrement-ebx" +20067 0x10/imm32/size +20068 0x34/4 0x62/b 0x2f/slash 0x64/d 0x65/e 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t 0x2d/dash 0x65/e 0x62/b 0x78/x +20069 _string_4e_decrement_esi: # (payload array byte) +20070 0x11/imm32/alloc-id:fake:payload +20071 # "4e/decrement-esi" +20072 0x10/imm32/size +20073 0x34/4 0x65/e 0x2f/slash 0x64/d 0x65/e 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t 0x2d/dash 0x65/e 0x73/s 0x69/i +20074 _string_4f_decrement_edi: # (payload array byte) +20075 0x11/imm32/alloc-id:fake:payload +20076 # "4f/decrement-edi" +20077 0x10/imm32/size +20078 0x34/4 0x66/f 0x2f/slash 0x64/d 0x65/e 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t 0x2d/dash 0x65/e 0x64/d 0x69/i +20079 _string_81_subop_add: # (payload array byte) +20080 0x11/imm32/alloc-id:fake:payload +20081 # "81 0/subop/add" +20082 0xe/imm32/size +20083 0x38/8 0x31/1 0x20/space 0x30/0 0x2f/slash 0x73/s 0x75/u 0x62/b 0x6f/o 0x70/p 0x2f/slash 0x61/a 0x64/d 0x64/d +20084 _string_81_subop_or: # (payload array byte) +20085 0x11/imm32/alloc-id:fake:payload +20086 # "81 1/subop/or" +20087 0xd/imm32/size +20088 0x38/8 0x31/1 0x20/space 0x31/1 0x2f/slash 0x73/s 0x75/u 0x62/b 0x6f/o 0x70/p 0x2f/slash 0x6f/o 0x72/r +20089 _string_81_subop_and: # (payload array byte) +20090 0x11/imm32/alloc-id:fake:payload +20091 # "81 4/subop/and" +20092 0xe/imm32/size +20093 0x38/8 0x31/1 0x20/space 0x34/4 0x2f/slash 0x73/s 0x75/u 0x62/b 0x6f/o 0x70/p 0x2f/slash 0x61/a 0x6e/n 0x64/d +20094 _string_81_subop_subtract: # (payload array byte) +20095 0x11/imm32/alloc-id:fake:payload +20096 # "81 5/subop/subtract" +20097 0x13/imm32/size +20098 0x38/8 0x31/1 0x20/space 0x35/5 0x2f/slash 0x73/s 0x75/u 0x62/b 0x6f/o 0x70/p 0x2f/slash 0x73/s 0x75/u 0x62/b 0x74/t 0x72/r 0x61/a 0x63/c 0x74/t +20099 _string_81_subop_xor: # (payload array byte) +20100 0x11/imm32/alloc-id:fake:payload +20101 # "81 6/subop/xor" +20102 0xe/imm32/size +20103 0x38/8 0x31/1 0x20/space 0x36/6 0x2f/slash 0x73/s 0x75/u 0x62/b 0x6f/o 0x70/p 0x2f/slash 0x78/x 0x6f/o 0x72/r +20104 _string_81_subop_compare: # (payload array byte) +20105 0x11/imm32/alloc-id:fake:payload +20106 # "81 7/subop/compare" +20107 0x12/imm32/size +20108 0x38/8 0x31/1 0x20/space 0x37/7 0x2f/slash 0x73/s 0x75/u 0x62/b 0x6f/o 0x70/p 0x2f/slash 0x63/c 0x6f/o 0x6d/m 0x70/p 0x61/a 0x72/r 0x65/e +20109 _string_89_<-: # (payload array byte) +20110 0x11/imm32/alloc-id:fake:payload +20111 # "89/<-" +20112 0x5/imm32/size +20113 0x38/8 0x39/9 0x2f/slash 0x3c/< 0x2d/dash +20114 _string_8b_->: # (payload array byte) +20115 0x11/imm32/alloc-id:fake:payload +20116 # "8b/->" +20117 0x5/imm32/size +20118 0x38/8 0x62/b 0x2f/slash 0x2d/dash 0x3e/> +20119 _string_8a_copy_byte: +20120 0x11/imm32/alloc-id:fake:payload +20121 # "8a/byte->" +20122 0x9/imm32/size +20123 0x38/8 0x61/a 0x2f// 0x62/b 0x79/y 0x74/t 0x65/e 0x2d/- 0x3e/> +20124 _string_88_copy_byte: +20125 0x11/imm32/alloc-id:fake:payload +20126 # "88/byte<-" +20127 0x9/imm32/size +20128 0x38/8 0x38/8 0x2f// 0x62/b 0x79/y 0x74/t 0x65/e 0x3c/< 0x2d/- +20129 _string_8d_copy_address: # (payload array byte) +20130 0x11/imm32/alloc-id:fake:payload +20131 # "8d/copy-address" +20132 0xf/imm32/size +20133 0x38/8 0x64/d 0x2f/slash 0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x65/e 0x73/s 0x73/s +20134 _string_b8_copy_to_eax: # (payload array byte) +20135 0x11/imm32/alloc-id:fake:payload +20136 # "b8/copy-to-eax" +20137 0xe/imm32/size +20138 0x62/b 0x38/8 0x2f/slash 0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/dash 0x74/t 0x6f/o 0x2d/dash 0x65/e 0x61/a 0x78/x +20139 _string_b9_copy_to_ecx: # (payload array byte) +20140 0x11/imm32/alloc-id:fake:payload +20141 # "b9/copy-to-ecx" +20142 0xe/imm32/size +20143 0x62/b 0x39/9 0x2f/slash 0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/dash 0x74/t 0x6f/o 0x2d/dash 0x65/e 0x63/c 0x78/x +20144 _string_ba_copy_to_edx: # (payload array byte) +20145 0x11/imm32/alloc-id:fake:payload +20146 # "ba/copy-to-edx" +20147 0xe/imm32/size +20148 0x62/b 0x61/a 0x2f/slash 0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/dash 0x74/t 0x6f/o 0x2d/dash 0x65/e 0x64/d 0x78/x +20149 _string_bb_copy_to_ebx: # (payload array byte) +20150 0x11/imm32/alloc-id:fake:payload +20151 # "bb/copy-to-ebx" +20152 0xe/imm32/size +20153 0x62/b 0x62/b 0x2f/slash 0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/dash 0x74/t 0x6f/o 0x2d/dash 0x65/e 0x62/b 0x78/x +20154 _string_be_copy_to_esi: # (payload array byte) +20155 0x11/imm32/alloc-id:fake:payload +20156 # "be/copy-to-esi" +20157 0xe/imm32/size +20158 0x62/b 0x65/e 0x2f/slash 0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/dash 0x74/t 0x6f/o 0x2d/dash 0x65/e 0x73/s 0x69/i +20159 _string_bf_copy_to_edi: # (payload array byte) +20160 0x11/imm32/alloc-id:fake:payload +20161 # "bf/copy-to-edi" +20162 0xe/imm32/size +20163 0x62/b 0x66/f 0x2f/slash 0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/dash 0x74/t 0x6f/o 0x2d/dash 0x65/e 0x64/d 0x69/i +20164 _string_c7_subop_copy: # (payload array byte) +20165 0x11/imm32/alloc-id:fake:payload +20166 # "c7 0/subop/copy" +20167 0xf/imm32/size +20168 0x63/c 0x37/7 0x20/space 0x30/0 0x2f/slash 0x73/s 0x75/u 0x62/b 0x6f/o 0x70/p 0x2f/slash 0x63/c 0x6f/o 0x70/p 0x79/y +20169 _string_e9_jump_label: # (payload array byte) +20170 0x11/imm32/alloc-id:fake:payload +20171 # "e9/jump" +20172 0x7/imm32/size +20173 0x65/e 0x39/9 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p +20174 _string_e9_jump_break: # (payload array byte) +20175 0x11/imm32/alloc-id:fake:payload +20176 # "e9/jump break/disp32" +20177 0x14/imm32/size +20178 0x65/e 0x39/9 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 +20179 _string_e9_jump_loop: # (payload array byte) +20180 0x11/imm32/alloc-id:fake:payload +20181 # "e9/jump loop/disp32" +20182 0x13/imm32/size +20183 0x65/e 0x39/9 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x20/space 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 +20184 _string_ff_subop_increment: # (payload array byte) +20185 0x11/imm32/alloc-id:fake:payload +20186 # "ff 0/subop/increment" +20187 0x14/imm32/size +20188 0x66/f 0x66/f 0x20/space 0x30/0 0x2f/slash 0x73/s 0x75/u 0x62/b 0x6f/o 0x70/p 0x2f/slash 0x69/i 0x6e/n 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t +20189 _string_ff_subop_decrement: # (payload array byte) +20190 0x11/imm32/alloc-id:fake:payload +20191 # "ff 1/subop/decrement" +20192 0x14/imm32/size +20193 0x66/f 0x66/f 0x20/space 0x31/1 0x2f/slash 0x73/s 0x75/u 0x62/b 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x65/e 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t +20194 _string_c1_subop_shift_left: # (payload array byte) +20195 0x11/imm32/alloc-id:fake:payload +20196 # "c1/shift 4/subop/left" +20197 0x15/imm32/size +20198 0x63/c 0x31/1 0x2f/slash 0x73/s 0x68/h 0x69/i 0x66/f 0x74/t 0x20/space 0x34/4 0x2f/slash 0x73/s 0x75/u 0x62/b 0x6f/o 0x70/p 0x2f/slash 0x6c/l 0x65/e 0x66/f 0x74/t +20199 _string_c1_subop_shift_right_padding_zeroes: # (payload array byte) +20200 0x11/imm32/alloc-id:fake:payload +20201 # "c1/shift 5/subop/right-padding-zeroes" +20202 0x25/imm32/size +20203 0x63/c 0x31/1 0x2f/slash 0x73/s 0x68/h 0x69/i 0x66/f 0x74/t 0x20/space 0x35/5 0x2f/slash 0x73/s 0x75/u 0x62/b 0x6f/o 0x70/p 0x2f/slash 0x72/r 0x69/i 0x67/g 0x68/h 0x74/t 0x2d/dash 0x70/p 0x61/a 0x64/d 0x64/d 0x69/i 0x6e/n 0x67/g 0x2d/dash 0x7a/z 0x65/e 0x72/r 0x6f/o 0x65/e 0x73/s +20204 _string_c1_subop_shift_right_preserving_sign: # (payload array byte) +20205 0x11/imm32/alloc-id:fake:payload +20206 # "c1/shift 7/subop/right-preserving-sign" +20207 0x26/imm32/size +20208 0x63/c 0x31/1 0x2f/slash 0x73/s 0x68/h 0x69/i 0x66/f 0x74/t 0x20/space 0x37/7 0x2f/slash 0x73/s 0x75/u 0x62/b 0x6f/o 0x70/p 0x2f/slash 0x72/r 0x69/i 0x67/g 0x68/h 0x74/t 0x2d/dash 0x70/p 0x72/r 0x65/e 0x73/s 0x65/e 0x72/r 0x76/v 0x69/i 0x6e/n 0x67/g 0x2d/dash 0x73/s 0x69/i 0x67/g 0x6e/n +20209 +20210 Single-int-var-in-mem: # (payload list var) +20211 0x11/imm32/alloc-id:fake:payload +20212 0x11/imm32/alloc-id:fake +20213 Int-var-in-mem/imm32 +20214 0/imm32/next +20215 0/imm32/next +20216 +20217 Int-var-in-mem: # (payload var) +20218 0x11/imm32/alloc-id:fake:payload +20219 0/imm32/name +20220 0/imm32/name +20221 0x11/imm32/alloc-id:fake +20222 Type-int/imm32 +20223 1/imm32/some-block-depth +20224 1/imm32/some-stack-offset +20225 0/imm32/no-register +20226 0/imm32/no-register +20227 +20228 # Not really legal, but closest we can currently represent a dereference of an (addr byte) +20229 Single-byte-var-in-mem: # (payload list var) +20230 0x11/imm32/alloc-id:fake:payload +20231 0x11/imm32/alloc-id:fake +20232 Byte-var-in-mem/imm32 +20233 0/imm32/next +20234 0/imm32/next +20235 +20236 # Not really legal, but closest we can currently represent a dereference of an (addr byte) +20237 Byte-var-in-mem: # (payload var) +20238 0x11/imm32/alloc-id:fake:payload +20239 0/imm32/name +20240 0/imm32/name +20241 0x11/imm32/alloc-id:fake +20242 Type-byte/imm32 +20243 1/imm32/some-block-depth +20244 1/imm32/some-stack-offset +20245 0/imm32/no-register +20246 0/imm32/no-register +20247 +20248 Two-args-int-stack-int-reg: # (payload list var) +20249 0x11/imm32/alloc-id:fake:payload +20250 0x11/imm32/alloc-id:fake +20251 Int-var-in-mem/imm32 +20252 0x11/imm32/alloc-id:fake +20253 Single-int-var-in-some-register/imm32/next +20254 +20255 Two-int-args-in-regs: # (payload list var) +20256 0x11/imm32/alloc-id:fake:payload +20257 0x11/imm32/alloc-id:fake +20258 Int-var-in-some-register/imm32 +20259 0x11/imm32/alloc-id:fake +20260 Single-int-var-in-some-register/imm32/next +20261 +20262 # Not really legal, but closest we can currently represent a dereference of an (addr byte) +20263 Two-args-byte-stack-byte-reg: # (payload list var) +20264 0x11/imm32/alloc-id:fake:payload +20265 0x11/imm32/alloc-id:fake +20266 Byte-var-in-mem/imm32 +20267 0x11/imm32/alloc-id:fake +20268 Single-byte-var-in-some-register/imm32/next +20269 +20270 Two-args-int-reg-int-stack: # (payload list var) +20271 0x11/imm32/alloc-id:fake:payload +20272 0x11/imm32/alloc-id:fake +20273 Int-var-in-some-register/imm32 +20274 0x11/imm32/alloc-id:fake +20275 Single-int-var-in-mem/imm32/next +20276 +20277 Two-args-int-eax-int-literal: # (payload list var) +20278 0x11/imm32/alloc-id:fake:payload +20279 0x11/imm32/alloc-id:fake +20280 Int-var-in-eax/imm32 +20281 0x11/imm32/alloc-id:fake +20282 Single-lit-var/imm32/next +20283 +20284 Int-var-and-literal: # (payload list var) +20285 0x11/imm32/alloc-id:fake:payload +20286 0x11/imm32/alloc-id:fake +20287 Int-var-in-mem/imm32 +20288 0x11/imm32/alloc-id:fake +20289 Single-lit-var/imm32/next +20290 +20291 Int-var-in-register-and-literal: # (payload list var) +20292 0x11/imm32/alloc-id:fake:payload +20293 0x11/imm32/alloc-id:fake +20294 Int-var-in-some-register/imm32 +20295 0x11/imm32/alloc-id:fake +20296 Single-lit-var/imm32/next +20297 +20298 Single-int-var-in-some-register: # (payload list var) +20299 0x11/imm32/alloc-id:fake:payload +20300 0x11/imm32/alloc-id:fake +20301 Int-var-in-some-register/imm32 +20302 0/imm32/next +20303 0/imm32/next +20304 +20305 Single-addr-var-in-some-register: # (payload list var) +20306 0x11/imm32/alloc-id:fake:payload +20307 0x11/imm32/alloc-id:fake +20308 Addr-var-in-some-register/imm32 +20309 0/imm32/next +20310 0/imm32/next +20311 +20312 Single-byte-var-in-some-register: # (payload list var) +20313 0x11/imm32/alloc-id:fake:payload +20314 0x11/imm32/alloc-id:fake +20315 Byte-var-in-some-register/imm32 +20316 0/imm32/next +20317 0/imm32/next +20318 +20319 Int-var-in-some-register: # (payload var) +20320 0x11/imm32/alloc-id:fake:payload +20321 0/imm32/name +20322 0/imm32/name +20323 0x11/imm32/alloc-id:fake +20324 Type-int/imm32 +20325 1/imm32/some-block-depth +20326 0/imm32/no-stack-offset +20327 0x11/imm32/alloc-id:fake +20328 Any-register/imm32 +20329 +20330 Any-register: # (payload array byte) +20331 0x11/imm32/alloc-id:fake:payload +20332 1/imm32/size +20333 # data +20334 2a/asterisk +20335 +20336 Addr-var-in-some-register: # (payload var) +20337 0x11/imm32/alloc-id:fake:payload +20338 0/imm32/name +20339 0/imm32/name +20340 0x11/imm32/alloc-id:fake +20341 Type-addr/imm32 +20342 1/imm32/some-block-depth +20343 0/imm32/no-stack-offset +20344 0x11/imm32/alloc-id:fake +20345 Any-register/imm32 +20346 +20347 Byte-var-in-some-register: # (payload var) +20348 0x11/imm32/alloc-id:fake:payload +20349 0/imm32/name +20350 0/imm32/name +20351 0x11/imm32/alloc-id:fake +20352 Type-byte/imm32 +20353 1/imm32/some-block-depth +20354 0/imm32/no-stack-offset +20355 0x11/imm32/alloc-id:fake +20356 Any-register/imm32 +20357 +20358 Single-int-var-in-eax: # (payload list var) +20359 0x11/imm32/alloc-id:fake:payload +20360 0x11/imm32/alloc-id:fake +20361 Int-var-in-eax/imm32 +20362 0/imm32/next +20363 0/imm32/next +20364 +20365 Int-var-in-eax: +20366 0x11/imm32/alloc-id:fake:payload +20367 0/imm32/name +20368 0/imm32/name +20369 0x11/imm32/alloc-id:fake +20370 Type-int/imm32 +20371 1/imm32/some-block-depth +20372 0/imm32/no-stack-offset +20373 0x11/imm32/alloc-id:fake +20374 $Register-eax/imm32 +20375 +20376 Single-int-var-in-ecx: # (payload list var) +20377 0x11/imm32/alloc-id:fake:payload +20378 0x11/imm32/alloc-id:fake +20379 Int-var-in-ecx/imm32 +20380 0/imm32/next +20381 0/imm32/next +20382 +20383 Int-var-in-ecx: +20384 0x11/imm32/alloc-id:fake:payload +20385 0/imm32/name +20386 0/imm32/name +20387 0x11/imm32/alloc-id:fake +20388 Type-int/imm32 +20389 1/imm32/some-block-depth +20390 0/imm32/no-stack-offset +20391 0x11/imm32/alloc-id:fake +20392 $Register-ecx/imm32/register +20393 +20394 Single-int-var-in-edx: # (payload list var) +20395 0x11/imm32/alloc-id:fake:payload +20396 0x11/imm32/alloc-id:fake +20397 Int-var-in-edx/imm32 +20398 0/imm32/next +20399 0/imm32/next +20400 +20401 Int-var-in-edx: # (payload list var) +20402 0x11/imm32/alloc-id:fake:payload +20403 0/imm32/name +20404 0/imm32/name +20405 0x11/imm32/alloc-id:fake +20406 Type-int/imm32 +20407 1/imm32/some-block-depth +20408 0/imm32/no-stack-offset +20409 0x11/imm32/alloc-id:fake +20410 $Register-edx/imm32/register +20411 +20412 Single-int-var-in-ebx: # (payload list var) +20413 0x11/imm32/alloc-id:fake:payload +20414 0x11/imm32/alloc-id:fake +20415 Int-var-in-ebx/imm32 +20416 0/imm32/next +20417 0/imm32/next +20418 +20419 Int-var-in-ebx: # (payload list var) +20420 0x11/imm32/alloc-id:fake:payload +20421 0/imm32/name +20422 0/imm32/name +20423 0x11/imm32/alloc-id:fake +20424 Type-int/imm32 +20425 1/imm32/some-block-depth +20426 0/imm32/no-stack-offset +20427 0x11/imm32/alloc-id:fake +20428 $Register-ebx/imm32/register +20429 +20430 Single-int-var-in-esi: # (payload list var) +20431 0x11/imm32/alloc-id:fake:payload +20432 0x11/imm32/alloc-id:fake +20433 Int-var-in-esi/imm32 +20434 0/imm32/next +20435 0/imm32/next +20436 +20437 Int-var-in-esi: # (payload list var) +20438 0x11/imm32/alloc-id:fake:payload +20439 0/imm32/name +20440 0/imm32/name +20441 0x11/imm32/alloc-id:fake +20442 Type-int/imm32 +20443 1/imm32/some-block-depth +20444 0/imm32/no-stack-offset +20445 0x11/imm32/alloc-id:fake +20446 $Register-esi/imm32/register +20447 +20448 Single-int-var-in-edi: # (payload list var) +20449 0x11/imm32/alloc-id:fake:payload +20450 0x11/imm32/alloc-id:fake +20451 Int-var-in-edi/imm32 +20452 0/imm32/next +20453 0/imm32/next +20454 +20455 Int-var-in-edi: # (payload list var) +20456 0x11/imm32/alloc-id:fake:payload +20457 0/imm32/name +20458 0/imm32/name +20459 0x11/imm32/alloc-id:fake +20460 Type-int/imm32 +20461 1/imm32/some-block-depth +20462 0/imm32/no-stack-offset +20463 0x11/imm32/alloc-id:fake +20464 $Register-edi/imm32/register +20465 +20466 Single-lit-var: # (payload list var) +20467 0x11/imm32/alloc-id:fake:payload +20468 0x11/imm32/alloc-id:fake +20469 Lit-var/imm32 +20470 0/imm32/next +20471 0/imm32/next +20472 +20473 Lit-var: # (payload var) +20474 0x11/imm32/alloc-id:fake:payload +20475 0/imm32/name +20476 0/imm32/name +20477 0x11/imm32/alloc-id:fake +20478 Type-literal/imm32 +20479 1/imm32/some-block-depth +20480 0/imm32/no-stack-offset +20481 0/imm32/no-register +20482 0/imm32/no-register +20483 +20484 Type-int: # (payload type-tree) +20485 0x11/imm32/alloc-id:fake:payload +20486 1/imm32/is-atom +20487 1/imm32/value:int +20488 0/imm32/left:unused +20489 0/imm32/right:null +20490 0/imm32/right:null +20491 +20492 Type-literal: # (payload type-tree) +20493 0x11/imm32/alloc-id:fake:payload +20494 1/imm32/is-atom +20495 0/imm32/value:literal +20496 0/imm32/left:unused +20497 0/imm32/right:null +20498 0/imm32/right:null +20499 +20500 Type-addr: # (payload type-tree) +20501 0x11/imm32/alloc-id:fake:payload +20502 1/imm32/is-atom +20503 2/imm32/value:addr +20504 0/imm32/left:unused +20505 0/imm32/right:null +20506 0/imm32/right:null +20507 +20508 Type-byte: # (payload type-tree) +20509 0x11/imm32/alloc-id:fake:payload +20510 1/imm32/is-atom +20511 8/imm32/value:byte +20512 0/imm32/left:unused +20513 0/imm32/right:null +20514 0/imm32/right:null +20515 +20516 == code +20517 emit-subx-primitive: # out: (addr buffered-file), stmt: (addr stmt), primitive: (addr primitive), err: (addr buffered-file), ed: (addr exit-descriptor) +20518 # . prologue +20519 55/push-ebp +20520 89/<- %ebp 4/r32/esp +20521 # . save registers +20522 50/push-eax +20523 51/push-ecx +20524 # ecx = primitive +20525 8b/-> *(ebp+0x10) 1/r32/ecx +20526 # emit primitive name +20527 (emit-indent *(ebp+8) *Curr-block-depth) +20528 (lookup *(ecx+0x18) *(ecx+0x1c)) # Primitive-subx-name Primitive-subx-name => eax +20529 (write-buffered *(ebp+8) %eax) +20530 # emit rm32 if necessary +20531 (emit-subx-rm32 *(ebp+8) *(ecx+0x20) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18)) # Primitive-subx-rm32 +20532 # emit r32 if necessary +20533 (emit-subx-r32 *(ebp+8) *(ecx+0x24) *(ebp+0xc)) # Primitive-subx-r32 +20534 # emit imm32 if necessary +20535 (emit-subx-imm32 *(ebp+8) *(ecx+0x28) *(ebp+0xc)) # Primitive-subx-imm32 +20536 # emit imm8 if necessary +20537 (emit-subx-imm8 *(ebp+8) *(ecx+0x2c) *(ebp+0xc)) # Primitive-subx-imm8 +20538 # emit disp32 if necessary +20539 (emit-subx-disp32 *(ebp+8) *(ecx+0x30) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18)) # Primitive-subx-disp32 +20540 (write-buffered *(ebp+8) Newline) +20541 $emit-subx-primitive:end: +20542 # . restore registers +20543 59/pop-to-ecx +20544 58/pop-to-eax +20545 # . epilogue +20546 89/<- %esp 5/r32/ebp +20547 5d/pop-to-ebp +20548 c3/return +20549 +20550 emit-subx-rm32: # out: (addr buffered-file), l: arg-location, stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) +20551 # . prologue +20552 55/push-ebp +20553 89/<- %ebp 4/r32/esp +20554 # . save registers +20555 50/push-eax +20556 # if (l == 0) return +20557 81 7/subop/compare *(ebp+0xc) 0/imm32 +20558 74/jump-if-= $emit-subx-rm32:end/disp8 +20559 # var v/eax: (addr stmt-var) +20560 (get-stmt-operand-from-arg-location *(ebp+0x10) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18)) # => eax +20561 (emit-subx-var-as-rm32 *(ebp+8) %eax) +20562 $emit-subx-rm32:end: +20563 # . restore registers +20564 58/pop-to-eax +20565 # . epilogue +20566 89/<- %esp 5/r32/ebp +20567 5d/pop-to-ebp +20568 c3/return +20569 +20570 get-stmt-operand-from-arg-location: # stmt: (addr stmt), l: arg-location, err: (addr buffered-file), ed: (addr exit-descriptor) -> var/eax: (addr stmt-var) +20571 # . prologue +20572 55/push-ebp +20573 89/<- %ebp 4/r32/esp +20574 # . save registers +20575 51/push-ecx +20576 # eax = l +20577 8b/-> *(ebp+0xc) 0/r32/eax +20578 # ecx = stmt +20579 8b/-> *(ebp+8) 1/r32/ecx +20580 # if (l == 1) return stmt->inouts +20581 { +20582 3d/compare-eax-and 1/imm32 +20583 75/jump-if-!= break/disp8 +20584 $get-stmt-operand-from-arg-location:1: +20585 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax +20586 eb/jump $get-stmt-operand-from-arg-location:end/disp8 +20587 } +20588 # if (l == 2) return stmt->inouts->next +20589 { +20590 3d/compare-eax-and 2/imm32 +20591 75/jump-if-!= break/disp8 +20592 $get-stmt-operand-from-arg-location:2: +20593 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax +20594 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax +20595 eb/jump $get-stmt-operand-from-arg-location:end/disp8 +20596 } +20597 # if (l == 3) return stmt->outputs +20598 { +20599 3d/compare-eax-and 3/imm32 +20600 75/jump-if-!= break/disp8 +20601 $get-stmt-operand-from-arg-location:3: +20602 (lookup *(ecx+0x14) *(ecx+0x18)) # Stmt1-outputs Stmt1-outputs => eax +20603 eb/jump $get-stmt-operand-from-arg-location:end/disp8 +20604 } +20605 # abort +20606 e9/jump $get-stmt-operand-from-arg-location:abort/disp32 +20607 $get-stmt-operand-from-arg-location:end: +20608 # . restore registers +20609 59/pop-to-ecx +20610 # . epilogue +20611 89/<- %esp 5/r32/ebp +20612 5d/pop-to-ebp +20613 c3/return +20614 +20615 $get-stmt-operand-from-arg-location:abort: +20616 # error("invalid arg-location " eax) +20617 (write-buffered *(ebp+0x10) "invalid arg-location ") +20618 (write-int32-hex-buffered *(ebp+0x10) %eax) +20619 (write-buffered *(ebp+0x10) Newline) +20620 (flush *(ebp+0x10)) +20621 (stop *(ebp+0x14) 1) +20622 # never gets here +20623 +20624 emit-subx-r32: # out: (addr buffered-file), l: arg-location, stmt: (addr stmt) +20625 # . prologue +20626 55/push-ebp +20627 89/<- %ebp 4/r32/esp +20628 # . save registers +20629 50/push-eax +20630 51/push-ecx +20631 # if (l == 0) return +20632 81 7/subop/compare *(ebp+0xc) 0/imm32 +20633 0f 84/jump-if-= $emit-subx-r32:end/disp32 +20634 # var v/eax: (addr stmt-var) +20635 (get-stmt-operand-from-arg-location *(ebp+0x10) *(ebp+0xc)) # => eax +20636 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +20637 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax +20638 (maybe-get Mu-registers %eax 0xc) # => eax: (addr register-index) +20639 (write-buffered *(ebp+8) Space) +20640 (write-int32-hex-buffered *(ebp+8) *eax) +20641 (write-buffered *(ebp+8) "/r32") +20642 $emit-subx-r32:end: +20643 # . restore registers +20644 59/pop-to-ecx +20645 58/pop-to-eax +20646 # . epilogue +20647 89/<- %esp 5/r32/ebp +20648 5d/pop-to-ebp +20649 c3/return +20650 +20651 emit-subx-imm32: # out: (addr buffered-file), l: arg-location, stmt: (addr stmt) +20652 # . prologue +20653 55/push-ebp +20654 89/<- %ebp 4/r32/esp +20655 # . save registers +20656 50/push-eax +20657 51/push-ecx +20658 # if (l == 0) return +20659 81 7/subop/compare *(ebp+0xc) 0/imm32 +20660 0f 84/jump-if-= $emit-subx-imm32:end/disp32 +20661 # var v/eax: (handle var) +20662 (get-stmt-operand-from-arg-location *(ebp+0x10) *(ebp+0xc)) # => eax +20663 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +20664 (lookup *eax *(eax+4)) # Var-name Var-name => eax +20665 (write-buffered *(ebp+8) Space) +20666 (write-buffered *(ebp+8) %eax) +20667 (write-buffered *(ebp+8) "/imm32") +20668 $emit-subx-imm32:end: +20669 # . restore registers +20670 59/pop-to-ecx +20671 58/pop-to-eax +20672 # . epilogue +20673 89/<- %esp 5/r32/ebp +20674 5d/pop-to-ebp +20675 c3/return +20676 +20677 emit-subx-imm8: # out: (addr buffered-file), l: arg-location, stmt: (addr stmt) +20678 # . prologue +20679 55/push-ebp +20680 89/<- %ebp 4/r32/esp +20681 # . save registers +20682 50/push-eax +20683 51/push-ecx +20684 # if (l == 0) return +20685 81 7/subop/compare *(ebp+0xc) 0/imm32 +20686 0f 84/jump-if-= $emit-subx-imm32:end/disp32 +20687 # var v/eax: (handle var) +20688 (get-stmt-operand-from-arg-location *(ebp+0x10) *(ebp+0xc)) # => eax +20689 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +20690 (lookup *eax *(eax+4)) # Var-name Var-name => eax +20691 (write-buffered *(ebp+8) Space) +20692 (write-buffered *(ebp+8) %eax) +20693 (write-buffered *(ebp+8) "/imm8") +20694 $emit-subx-imm8:end: +20695 # . restore registers +20696 59/pop-to-ecx +20697 58/pop-to-eax +20698 # . epilogue +20699 89/<- %esp 5/r32/ebp +20700 5d/pop-to-ebp +20701 c3/return +20702 +20703 emit-subx-disp32: # out: (addr buffered-file), l: arg-location, stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) +20704 # . prologue +20705 55/push-ebp +20706 89/<- %ebp 4/r32/esp +20707 # . save registers +20708 50/push-eax +20709 51/push-ecx +20710 # if (location == 0) return +20711 81 7/subop/compare *(ebp+0xc) 0/imm32 +20712 0f 84/jump-if-= $emit-subx-disp32:end/disp32 +20713 # var v/eax: (addr stmt-var) +20714 (get-stmt-operand-from-arg-location *(ebp+0x10) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18)) # => eax +20715 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +20716 (lookup *eax *(eax+4)) # Var-name Var-name => eax +20717 (write-buffered *(ebp+8) Space) +20718 (write-buffered *(ebp+8) %eax) +20719 # hack: if instruction operation starts with "break", emit ":break" +20720 # var name/ecx: (addr array byte) = lookup(stmt->operation) +20721 8b/-> *(ebp+0x10) 0/r32/eax +20722 (lookup *(eax+4) *(eax+8)) # Stmt1-operation Stmt1-operation => eax +20723 89/<- %ecx 0/r32/eax +20724 { +20725 (string-starts-with? %ecx "break") # => eax +20726 3d/compare-eax-and 0/imm32/false +20727 74/jump-if-= break/disp8 +20728 (write-buffered *(ebp+8) ":break") +20729 } +20730 # hack: if instruction operation starts with "loop", emit ":loop" +20731 { +20732 (string-starts-with? %ecx "loop") # => eax +20733 3d/compare-eax-and 0/imm32/false +20734 74/jump-if-= break/disp8 +20735 (write-buffered *(ebp+8) ":loop") +20736 } +20737 (write-buffered *(ebp+8) "/disp32") +20738 $emit-subx-disp32:end: +20739 # . restore registers +20740 59/pop-to-ecx +20741 58/pop-to-eax +20742 # . epilogue +20743 89/<- %esp 5/r32/ebp +20744 5d/pop-to-ebp +20745 c3/return +20746 +20747 emit-call: # out: (addr buffered-file), stmt: (addr stmt) +20748 # . prologue +20749 55/push-ebp +20750 89/<- %ebp 4/r32/esp +20751 # . save registers +20752 50/push-eax +20753 51/push-ecx +20754 # +20755 (emit-indent *(ebp+8) *Curr-block-depth) +20756 (write-buffered *(ebp+8) "(") +20757 # ecx = stmt +20758 8b/-> *(ebp+0xc) 1/r32/ecx +20759 # - emit function name +20760 (lookup *(ecx+4) *(ecx+8)) # Stmt1-operation Stmt1-operation => eax +20761 (write-buffered *(ebp+8) %eax) +20762 # - emit arguments +20763 # var curr/eax: (addr stmt-var) = lookup(stmt->inouts) +20764 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax +20765 { +20766 # if (curr == null) break +20767 3d/compare-eax-and 0/imm32 +20768 74/jump-if-= break/disp8 +20769 # +20770 (emit-subx-call-operand *(ebp+8) %eax) +20771 # curr = lookup(curr->next) +20772 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax +20773 eb/jump loop/disp8 +20774 } +20775 # +20776 (write-buffered *(ebp+8) ")\n") +20777 $emit-call:end: +20778 # . restore registers +20779 59/pop-to-ecx +20780 58/pop-to-eax +20781 # . epilogue +20782 89/<- %esp 5/r32/ebp +20783 5d/pop-to-ebp +20784 c3/return +20785 +20786 emit-subx-call-operand: # out: (addr buffered-file), s: (addr stmt-var) +20787 # shares code with emit-subx-var-as-rm32 +20788 # . prologue +20789 55/push-ebp +20790 89/<- %ebp 4/r32/esp +20791 # . save registers +20792 50/push-eax +20793 51/push-ecx +20794 56/push-esi +20795 # ecx = s +20796 8b/-> *(ebp+0xc) 1/r32/ecx +20797 # var operand/esi: (addr var) = lookup(s->value) +20798 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax +20799 89/<- %esi 0/r32/eax +20800 # if (operand->register && !s->is-deref?) emit "%__" +20801 { +20802 $emit-subx-call-operand:check-for-register-direct: +20803 81 7/subop/compare *(esi+0x18) 0/imm32 # Var-register +20804 74/jump-if-= break/disp8 +20805 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref +20806 75/jump-if-!= break/disp8 +20807 $emit-subx-call-operand:register-direct: +20808 (write-buffered *(ebp+8) " %") +20809 (lookup *(esi+0x18) *(esi+0x1c)) # Var-register Var-register => eax +20810 (write-buffered *(ebp+8) %eax) +20811 e9/jump $emit-subx-call-operand:end/disp32 +20812 } +20813 # else if (operand->register && s->is-deref?) emit "*__" +20814 { +20815 $emit-subx-call-operand:check-for-register-indirect: +20816 81 7/subop/compare *(esi+0x18) 0/imm32 # Var-register +20817 74/jump-if-= break/disp8 +20818 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref +20819 74/jump-if-= break/disp8 +20820 $emit-subx-call-operand:register-indirect: +20821 (emit-subx-call-operand-register-indirect *(ebp+8) %esi) +20822 e9/jump $emit-subx-call-operand:end/disp32 +20823 } +20824 # else if (operand->stack-offset) emit "*(ebp+__)" +20825 { +20826 81 7/subop/compare *(esi+0x14) 0/imm32 # Var-offset +20827 74/jump-if-= break/disp8 +20828 $emit-subx-call-operand:stack: +20829 (emit-subx-call-operand-stack *(ebp+8) %esi) +20830 e9/jump $emit-subx-call-operand:end/disp32 +20831 } +20832 # else if (operand->type == literal) emit "__" +20833 { +20834 (lookup *(esi+8) *(esi+0xc)) # Var-type Var-type => eax +20835 81 7/subop/compare *(eax+4) 0/imm32 # Type-tree-left +20836 75/jump-if-!= break/disp8 +20837 $emit-subx-call-operand:literal: +20838 (write-buffered *(ebp+8) Space) +20839 (lookup *esi *(esi+4)) # Var-name Var-name => eax +20840 (write-buffered *(ebp+8) %eax) +20841 } +20842 $emit-subx-call-operand:end: +20843 # . restore registers +20844 5e/pop-to-esi +20845 59/pop-to-ecx +20846 58/pop-to-eax +20847 # . epilogue +20848 89/<- %esp 5/r32/ebp +20849 5d/pop-to-ebp +20850 c3/return +20851 +20852 emit-subx-call-operand-register-indirect: # out: (addr buffered-file), v: (addr var) 20853 # . prologue 20854 55/push-ebp 20855 89/<- %ebp 4/r32/esp -20856 # setup -20857 (clear-stream _test-output-stream) -20858 (clear-stream $_test-output-buffered-file->buffer) -20859 $test-add-reg-to-reg:initialize-type: -20860 # var type/ecx: (payload type-tree) = int -20861 68/push 0/imm32/right:null -20862 68/push 0/imm32/right:null -20863 68/push 0/imm32/left:unused -20864 68/push 1/imm32/value:int -20865 68/push 1/imm32/is-atom?:true -20866 68/push 0x11/imm32/alloc-id:fake:payload -20867 89/<- %ecx 4/r32/esp -20868 $test-add-reg-to-reg:initialize-var1: -20869 # var var1/ecx: (payload var) -20870 68/push 0/imm32/register -20871 68/push 0/imm32/register -20872 68/push 0/imm32/no-stack-offset -20873 68/push 1/imm32/block-depth -20874 51/push-ecx -20875 68/push 0x11/imm32/alloc-id:fake -20876 68/push 0/imm32/name -20877 68/push 0/imm32/name -20878 68/push 0x11/imm32/alloc-id:fake:payload -20879 89/<- %ecx 4/r32/esp -20880 $test-add-reg-to-reg:initialize-var1-name: -20881 # var1->name = "var1" -20882 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -20883 (copy-array Heap "var1" %eax) -20884 $test-add-reg-to-reg:initialize-var1-register: -20885 # var1->register = "eax" -20886 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 -20887 (copy-array Heap "eax" %eax) -20888 $test-add-reg-to-reg:initialize-var2: -20889 # var var2/edx: (payload var) -20890 68/push 0/imm32/register -20891 68/push 0/imm32/register -20892 68/push 0/imm32/no-stack-offset -20893 68/push 1/imm32/block-depth -20894 ff 6/subop/push *(ecx+0x10) -20895 68/push 0x11/imm32/alloc-id:fake -20896 68/push 0/imm32/name -20897 68/push 0/imm32/name -20898 68/push 0x11/imm32/alloc-id:fake:payload -20899 89/<- %edx 4/r32/esp -20900 $test-add-reg-to-reg:initialize-var2-name: -20901 # var2->name = "var2" -20902 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 -20903 (copy-array Heap "var2" %eax) -20904 $test-add-reg-to-reg:initialize-var2-register: -20905 # var2->register = "ecx" -20906 8d/copy-address *(edx+0x1c) 0/r32/eax # Var-register + 4 -20907 (copy-array Heap "ecx" %eax) -20908 $test-add-reg-to-reg:initialize-inouts: -20909 # var inouts/esi: (payload stmt-var) = [var2] -20910 68/push 0/imm32/is-deref:false -20911 68/push 0/imm32/next -20912 68/push 0/imm32/next -20913 52/push-edx/var2 -20914 68/push 0x11/imm32/alloc-id:fake -20915 68/push 0x11/imm32/alloc-id:fake:payload -20916 89/<- %esi 4/r32/esp -20917 $test-add-reg-to-reg:initialize-outputs: -20918 # var outputs/edi: (payload stmt-var) = [var1] -20919 68/push 0/imm32/is-deref:false -20920 68/push 0/imm32/next -20921 68/push 0/imm32/next -20922 51/push-ecx/var1 -20923 68/push 0x11/imm32/alloc-id:fake -20924 68/push 0x11/imm32/alloc-id:fake:payload -20925 89/<- %edi 4/r32/esp -20926 $test-add-reg-to-reg:initialize-stmt: -20927 # var stmt/esi: (addr statement) -20928 68/push 0/imm32/next -20929 68/push 0/imm32/next -20930 57/push-edi/outputs -20931 68/push 0x11/imm32/alloc-id:fake -20932 56/push-esi/inouts -20933 68/push 0x11/imm32/alloc-id:fake -20934 68/push 0/imm32/operation -20935 68/push 0/imm32/operation -20936 68/push 1/imm32/tag:stmt1 -20937 89/<- %esi 4/r32/esp -20938 $test-add-reg-to-reg:initialize-stmt-operation: -20939 # stmt->operation = "add" -20940 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -20941 (copy-array Heap "add" %eax) -20942 # convert -20943 c7 0/subop/copy *Curr-block-depth 0/imm32 -20944 (emit-subx-stmt _test-output-buffered-file %esi Primitives Stderr 0) -20945 (flush _test-output-buffered-file) -20946 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -20952 # check output -20953 (check-next-stream-line-equal _test-output-stream "01/add-to %eax 0x00000001/r32" "F - test-add-reg-to-reg") -20954 # . epilogue -20955 89/<- %esp 5/r32/ebp -20956 5d/pop-to-ebp -20957 c3/return -20958 -20959 test-add-reg-to-mem: -20960 # add-to var1 var2/reg -20961 # => -20962 # 01/add-to *(ebp+__) var2 -20963 # -20964 # . prologue -20965 55/push-ebp -20966 89/<- %ebp 4/r32/esp -20967 # setup -20968 (clear-stream _test-output-stream) -20969 (clear-stream $_test-output-buffered-file->buffer) -20970 $test-add-reg-to-mem:initialize-type: -20971 # var type/ecx: (payload type-tree) = int -20972 68/push 0/imm32/right:null -20973 68/push 0/imm32/right:null -20974 68/push 0/imm32/left:unused -20975 68/push 1/imm32/value:int -20976 68/push 1/imm32/is-atom?:true -20977 68/push 0x11/imm32/alloc-id:fake:payload -20978 89/<- %ecx 4/r32/esp -20979 $test-add-reg-to-mem:initialize-var1: -20980 # var var1/ecx: (payload var) -20981 68/push 0/imm32/register -20982 68/push 0/imm32/register -20983 68/push 8/imm32/stack-offset -20984 68/push 1/imm32/block-depth -20985 51/push-ecx -20986 68/push 0x11/imm32/alloc-id:fake -20987 68/push 0/imm32/name -20988 68/push 0/imm32/name -20989 68/push 0x11/imm32/alloc-id:fake:payload -20990 89/<- %ecx 4/r32/esp -20991 $test-add-reg-to-mem:initialize-var1-name: -20992 # var1->name = "var1" -20993 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -20994 (copy-array Heap "var1" %eax) -20995 $test-add-reg-to-mem:initialize-var2: -20996 # var var2/edx: (payload var) -20997 68/push 0/imm32/register -20998 68/push 0/imm32/register -20999 68/push 0/imm32/no-stack-offset -21000 68/push 1/imm32/block-depth -21001 ff 6/subop/push *(ecx+0x10) -21002 68/push 0x11/imm32/alloc-id:fake -21003 68/push 0/imm32/name -21004 68/push 0/imm32/name -21005 68/push 0x11/imm32/alloc-id:fake:payload -21006 89/<- %edx 4/r32/esp -21007 $test-add-reg-to-mem:initialize-var2-name: -21008 # var2->name = "var2" -21009 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 -21010 (copy-array Heap "var2" %eax) -21011 $test-add-reg-to-mem:initialize-var2-register: -21012 # var2->register = "ecx" -21013 8d/copy-address *(edx+0x1c) 0/r32/eax # Var-register + 4 -21014 (copy-array Heap "ecx" %eax) -21015 $test-add-reg-to-mem:initialize-inouts: -21016 # var inouts/esi: (payload stmt-var) = [var2] -21017 68/push 0/imm32/is-deref:false -21018 68/push 0/imm32/next -21019 68/push 0/imm32/next -21020 52/push-edx/var2 -21021 68/push 0x11/imm32/alloc-id:fake -21022 68/push 0x11/imm32/alloc-id:fake:payload -21023 89/<- %esi 4/r32/esp -21024 # inouts = [var1, var2] -21025 68/push 0/imm32/is-deref:false -21026 56/push-esi/next -21027 68/push 0x11/imm32/alloc-id:fake -21028 51/push-ecx/var1 -21029 68/push 0x11/imm32/alloc-id:fake -21030 68/push 0x11/imm32/alloc-id:fake:payload -21031 89/<- %esi 4/r32/esp -21032 $test-add-reg-to-mem:initialize-stmt: -21033 # var stmt/esi: (addr statement) -21034 68/push 0/imm32/next -21035 68/push 0/imm32/next -21036 68/push 0/imm32/outputs -21037 68/push 0/imm32/outputs -21038 56/push-esi/inouts -21039 68/push 0x11/imm32/alloc-id:fake -21040 68/push 0/imm32/operation -21041 68/push 0/imm32/operation -21042 68/push 1/imm32/tag:stmt1 -21043 89/<- %esi 4/r32/esp -21044 $test-add-reg-to-mem:initialize-stmt-operation: -21045 # stmt->operation = "add-to" -21046 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -21047 (copy-array Heap "add-to" %eax) -21048 # convert -21049 c7 0/subop/copy *Curr-block-depth 0/imm32 -21050 (emit-subx-stmt _test-output-buffered-file %esi Primitives Stderr 0) -21051 (flush _test-output-buffered-file) -21052 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -21058 # check output -21059 (check-next-stream-line-equal _test-output-stream "01/add-to *(ebp+0x00000008) 0x00000001/r32" "F - test-add-reg-to-mem") -21060 # . epilogue -21061 89/<- %esp 5/r32/ebp -21062 5d/pop-to-ebp -21063 c3/return -21064 -21065 test-add-mem-to-reg: -21066 # var1/reg <- add var2 -21067 # => -21068 # 03/add *(ebp+__) var1 -21069 # -21070 # . prologue -21071 55/push-ebp -21072 89/<- %ebp 4/r32/esp -21073 # setup -21074 (clear-stream _test-output-stream) -21075 (clear-stream $_test-output-buffered-file->buffer) -21076 $test-add-mem-to-reg:initialize-type: -21077 # var type/ecx: (payload type-tree) = int -21078 68/push 0/imm32/right:null -21079 68/push 0/imm32/right:null -21080 68/push 0/imm32/left:unused -21081 68/push 1/imm32/value:int -21082 68/push 1/imm32/is-atom?:true -21083 68/push 0x11/imm32/alloc-id:fake:payload -21084 89/<- %ecx 4/r32/esp -21085 $test-add-mem-to-reg:initialize-var: -21086 # var var1/ecx: (payload var) -21087 68/push 0/imm32/register -21088 68/push 0/imm32/register -21089 68/push 0/imm32/no-stack-offset -21090 68/push 1/imm32/block-depth -21091 51/push-ecx -21092 68/push 0x11/imm32/alloc-id:fake -21093 68/push 0/imm32/name -21094 68/push 0/imm32/name -21095 68/push 0x11/imm32/alloc-id:fake:payload -21096 89/<- %ecx 4/r32/esp -21097 $test-add-mem-to-reg:initialize-var-name: -21098 # var1->name = "foo" -21099 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -21100 (copy-array Heap "var1" %eax) -21101 $test-add-mem-to-reg:initialize-var-register: -21102 # var1->register = "eax" -21103 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 -21104 (copy-array Heap "eax" %eax) -21105 $test-add-mem-to-reg:initialize-var2: -21106 # var var2/edx: (payload var) -21107 68/push 0/imm32/register -21108 68/push 0/imm32/register -21109 68/push 8/imm32/stack-offset -21110 68/push 1/imm32/block-depth -21111 ff 6/subop/push *(ecx+0x10) -21112 68/push 0x11/imm32/alloc-id:fake -21113 68/push 0/imm32/name -21114 68/push 0/imm32/name -21115 68/push 0x11/imm32/alloc-id:fake:payload -21116 89/<- %edx 4/r32/esp -21117 $test-add-mem-to-reg:initialize-var2-name: -21118 # var2->name = "var2" -21119 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 -21120 (copy-array Heap "var2" %eax) -21121 $test-add-mem-to-reg:initialize-inouts: -21122 # var inouts/esi: (payload stmt-var) = [var2] -21123 68/push 0/imm32/is-deref:false -21124 68/push 0/imm32/next -21125 68/push 0/imm32/next -21126 52/push-edx/var2 -21127 68/push 0x11/imm32/alloc-id:fake -21128 68/push 0x11/imm32/alloc-id:fake:payload -21129 89/<- %esi 4/r32/esp -21130 $test-add-mem-to-reg:initialize-outputs: -21131 # var outputs/edi: (payload stmt-var) = [var1] -21132 68/push 0/imm32/is-deref:false -21133 68/push 0/imm32/next -21134 68/push 0/imm32/next -21135 51/push-ecx/var1 -21136 68/push 0x11/imm32/alloc-id:fake -21137 68/push 0x11/imm32/alloc-id:fake:payload -21138 89/<- %edi 4/r32/esp -21139 $test-add-mem-to-reg:initialize-stmt: -21140 # var stmt/esi: (addr statement) -21141 68/push 0/imm32/next -21142 68/push 0/imm32/next -21143 57/push-edi/outputs -21144 68/push 0x11/imm32/alloc-id:fake -21145 56/push-esi/inouts -21146 68/push 0x11/imm32/alloc-id:fake -21147 68/push 0/imm32/operation -21148 68/push 0/imm32/operation -21149 68/push 1/imm32/tag:stmt1 -21150 89/<- %esi 4/r32/esp -21151 $test-add-mem-to-reg:initialize-stmt-operation: -21152 # stmt->operation = "add" -21153 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -21154 (copy-array Heap "add" %eax) -21155 # convert -21156 c7 0/subop/copy *Curr-block-depth 0/imm32 -21157 (emit-subx-stmt _test-output-buffered-file %esi Primitives Stderr 0) -21158 (flush _test-output-buffered-file) -21159 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -21165 # check output -21166 (check-next-stream-line-equal _test-output-stream "03/add *(ebp+0x00000008) 0x00000000/r32" "F - test-add-mem-to-reg") -21167 # . epilogue -21168 89/<- %esp 5/r32/ebp -21169 5d/pop-to-ebp -21170 c3/return -21171 -21172 test-add-literal-to-eax: -21173 # var1/eax <- add 0x34 -21174 # => -21175 # 05/add-to-eax 0x34/imm32 -21176 # -21177 # . prologue -21178 55/push-ebp -21179 89/<- %ebp 4/r32/esp -21180 # setup -21181 (clear-stream _test-output-stream) -21182 (clear-stream $_test-output-buffered-file->buffer) -21183 $test-add-literal-to-eax:initialize-var-type: -21184 # var type/ecx: (payload type-tree) = int -21185 68/push 0/imm32/right:null -21186 68/push 0/imm32/right:null -21187 68/push 0/imm32/left:unused -21188 68/push 1/imm32/value:int -21189 68/push 1/imm32/is-atom?:true -21190 68/push 0x11/imm32/alloc-id:fake:payload -21191 89/<- %ecx 4/r32/esp -21192 $test-add-literal-to-eax:initialize-var: -21193 # var v/ecx: (payload var) -21194 68/push 0/imm32/register -21195 68/push 0/imm32/register -21196 68/push 0/imm32/no-stack-offset -21197 68/push 1/imm32/block-depth -21198 51/push-ecx -21199 68/push 0x11/imm32/alloc-id:fake -21200 68/push 0/imm32/name -21201 68/push 0/imm32/name -21202 68/push 0x11/imm32/alloc-id:fake:payload -21203 89/<- %ecx 4/r32/esp -21204 $test-add-literal-to-eax:initialize-var-name: -21205 # v->name = "v" -21206 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -21207 (copy-array Heap "v" %eax) -21208 $test-add-literal-to-eax:initialize-var-register: -21209 # v->register = "eax" -21210 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 -21211 (copy-array Heap "eax" %eax) -21212 $test-add-literal-to-eax:initialize-literal-type: -21213 # var type/edx: (payload type-tree) = literal -21214 68/push 0/imm32/right:null -21215 68/push 0/imm32/right:null -21216 68/push 0/imm32/left:unused -21217 68/push 0/imm32/value:literal -21218 68/push 1/imm32/is-atom?:true -21219 68/push 0x11/imm32/alloc-id:fake:payload -21220 89/<- %edx 4/r32/esp -21221 $test-add-literal-to-eax:initialize-literal: -21222 # var l/edx: (payload var) -21223 68/push 0/imm32/register -21224 68/push 0/imm32/register -21225 68/push 0/imm32/no-stack-offset -21226 68/push 1/imm32/block-depth -21227 52/push-edx -21228 68/push 0x11/imm32/alloc-id:fake -21229 68/push 0/imm32/name -21230 68/push 0/imm32/name -21231 68/push 0x11/imm32/alloc-id:fake:payload -21232 89/<- %edx 4/r32/esp -21233 $test-add-literal-to-eax:initialize-literal-value: -21234 # l->name = "0x34" -21235 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 -21236 (copy-array Heap "0x34" %eax) -21237 $test-add-literal-to-eax:initialize-inouts: -21238 # var inouts/esi: (payload stmt-var) = [l] -21239 68/push 0/imm32/is-deref:false -21240 68/push 0/imm32/next -21241 68/push 0/imm32/next -21242 52/push-edx/l -21243 68/push 0x11/imm32/alloc-id:fake -21244 68/push 0x11/imm32/alloc-id:fake:payload -21245 89/<- %esi 4/r32/esp -21246 $test-add-literal-to-eax:initialize-outputs: -21247 # var outputs/edi: (payload stmt-var) = [v] -21248 68/push 0/imm32/is-deref:false -21249 68/push 0/imm32/next -21250 68/push 0/imm32/next -21251 51/push-ecx/v -21252 68/push 0x11/imm32/alloc-id:fake -21253 68/push 0x11/imm32/alloc-id:fake:payload -21254 89/<- %edi 4/r32/esp -21255 $test-add-literal-to-eax:initialize-stmt: -21256 # var stmt/esi: (addr statement) -21257 68/push 0/imm32/next -21258 68/push 0/imm32/next -21259 57/push-edi/outputs -21260 68/push 0x11/imm32/alloc-id:fake -21261 56/push-esi/inouts -21262 68/push 0x11/imm32/alloc-id:fake -21263 68/push 0/imm32/operation -21264 68/push 0/imm32/operation -21265 68/push 1/imm32/tag:stmt1 -21266 89/<- %esi 4/r32/esp -21267 $test-add-literal-to-eax:initialize-stmt-operation: -21268 # stmt->operation = "add" -21269 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -21270 (copy-array Heap "add" %eax) -21271 # convert -21272 c7 0/subop/copy *Curr-block-depth 0/imm32 -21273 (emit-subx-stmt _test-output-buffered-file %esi Primitives Stderr 0) -21274 (flush _test-output-buffered-file) -21275 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -21281 # check output -21282 (check-next-stream-line-equal _test-output-stream "05/add-to-eax 0x34/imm32" "F - test-add-literal-to-eax") +20856 # . save registers +20857 50/push-eax +20858 51/push-ecx +20859 56/push-esi +20860 # esi = v +20861 8b/-> *(ebp+0xc) 6/r32/esi +20862 # var size/ecx: int = size-of-deref(v) +20863 (size-of-deref %esi) # => eax +20864 89/<- %ecx 0/r32/eax +20865 # var reg-name/esi: (addr array byte) = lookup(v->register) +20866 (lookup *(esi+0x18) *(esi+0x1c)) # Var-register Var-register => eax +20867 89/<- %esi 0/r32/eax +20868 # TODO: assert size is a multiple of 4 +20869 # var i/eax: int = 0 +20870 b8/copy-to-eax 0/imm32 +20871 { +20872 $emit-subx-call-operand-register-indirect:loop: +20873 # if (i >= size) break +20874 39/compare %eax 1/r32/ecx +20875 7d/jump-if->= break/disp8 +20876 # emit " *(" v->register "+" i ")" +20877 (write-buffered *(ebp+8) " *(") +20878 (write-buffered *(ebp+8) %esi) +20879 (write-buffered *(ebp+8) "+") +20880 (write-int32-hex-buffered *(ebp+8) %eax) +20881 (write-buffered *(ebp+8) ")") +20882 # i += 4 +20883 05/add-to-eax 4/imm32 +20884 # +20885 eb/jump loop/disp8 +20886 } +20887 $emit-subx-call-operand-register-indirect:end: +20888 # . restore registers +20889 5e/pop-to-esi +20890 59/pop-to-ecx +20891 58/pop-to-eax +20892 # . epilogue +20893 89/<- %esp 5/r32/ebp +20894 5d/pop-to-ebp +20895 c3/return +20896 +20897 emit-subx-call-operand-stack: # out: (addr buffered-file), v: (addr var) +20898 # . prologue +20899 55/push-ebp +20900 89/<- %ebp 4/r32/esp +20901 # . save registers +20902 50/push-eax +20903 51/push-ecx +20904 56/push-esi +20905 # esi = v +20906 8b/-> *(ebp+0xc) 6/r32/esi +20907 # var curr/ecx: int = v->offset +20908 8b/-> *(esi+0x14) 1/r32/ecx # Var-offset +20909 # var max/eax: int = v->offset + size-of(v) +20910 (size-of %esi) # => eax +20911 # TODO: assert size is a multiple of 4 +20912 01/add-to %eax 1/r32/ecx +20913 { +20914 $emit-subx-call-operand-stack:loop: +20915 # if (curr >= max) break +20916 39/compare %ecx 0/r32/eax +20917 7d/jump-if->= break/disp8 +20918 # emit " *(ebp+" curr ")" +20919 (write-buffered *(ebp+8) " *(ebp+") +20920 (write-int32-hex-buffered *(ebp+8) %ecx) +20921 (write-buffered *(ebp+8) ")") +20922 # i += 4 +20923 81 0/subop/add %ecx 4/imm32 +20924 # +20925 eb/jump loop/disp8 +20926 } +20927 $emit-subx-call-operand-stack:end: +20928 # . restore registers +20929 5e/pop-to-esi +20930 59/pop-to-ecx +20931 58/pop-to-eax +20932 # . epilogue +20933 89/<- %esp 5/r32/ebp +20934 5d/pop-to-ebp +20935 c3/return +20936 +20937 emit-subx-var-as-rm32: # out: (addr buffered-file), s: (addr stmt-var) +20938 # . prologue +20939 55/push-ebp +20940 89/<- %ebp 4/r32/esp +20941 # . save registers +20942 50/push-eax +20943 51/push-ecx +20944 56/push-esi +20945 # ecx = s +20946 8b/-> *(ebp+0xc) 1/r32/ecx +20947 # var operand/esi: (addr var) = lookup(s->value) +20948 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax +20949 89/<- %esi 0/r32/eax +20950 # if (operand->register && s->is-deref?) emit "*__" +20951 { +20952 $emit-subx-var-as-rm32:check-for-register-indirect: +20953 81 7/subop/compare *(esi+0x18) 0/imm32 # Var-register +20954 74/jump-if-= break/disp8 +20955 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref +20956 74/jump-if-= break/disp8 +20957 $emit-subx-var-as-rm32:register-indirect: +20958 (write-buffered *(ebp+8) " *") +20959 (lookup *(esi+0x18) *(esi+0x1c)) # Var-register Var-register => eax +20960 (write-buffered *(ebp+8) %eax) +20961 e9/jump $emit-subx-var-as-rm32:end/disp32 +20962 } +20963 # if (operand->register && !s->is-deref?) emit "%__" +20964 { +20965 $emit-subx-var-as-rm32:check-for-register-direct: +20966 81 7/subop/compare *(esi+0x18) 0/imm32 # Var-register +20967 74/jump-if-= break/disp8 +20968 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref +20969 75/jump-if-!= break/disp8 +20970 $emit-subx-var-as-rm32:register-direct: +20971 (write-buffered *(ebp+8) " %") +20972 (lookup *(esi+0x18) *(esi+0x1c)) # Var-register Var-register => eax +20973 (write-buffered *(ebp+8) %eax) +20974 e9/jump $emit-subx-var-as-rm32:end/disp32 +20975 } +20976 # else if (operand->stack-offset) emit "*(ebp+__)" +20977 { +20978 81 7/subop/compare *(esi+0x14) 0/imm32 # Var-offset +20979 74/jump-if-= break/disp8 +20980 $emit-subx-var-as-rm32:stack: +20981 (write-buffered *(ebp+8) Space) +20982 (write-buffered *(ebp+8) "*(ebp+") +20983 (write-int32-hex-buffered *(ebp+8) *(esi+0x14)) # Var-offset +20984 (write-buffered *(ebp+8) ")") +20985 } +20986 $emit-subx-var-as-rm32:end: +20987 # . restore registers +20988 5e/pop-to-esi +20989 59/pop-to-ecx +20990 58/pop-to-eax +20991 # . epilogue +20992 89/<- %esp 5/r32/ebp +20993 5d/pop-to-ebp +20994 c3/return +20995 +20996 find-matching-primitive: # primitives: (addr primitive), stmt: (addr stmt) -> result/eax: (addr primitive) +20997 # . prologue +20998 55/push-ebp +20999 89/<- %ebp 4/r32/esp +21000 # . save registers +21001 51/push-ecx +21002 # var curr/ecx: (addr primitive) = primitives +21003 8b/-> *(ebp+8) 1/r32/ecx +21004 { +21005 $find-matching-primitive:loop: +21006 # if (curr == null) break +21007 81 7/subop/compare %ecx 0/imm32 +21008 74/jump-if-= break/disp8 +21009 # if match(curr, stmt) return curr +21010 { +21011 (mu-stmt-matches-primitive? *(ebp+0xc) %ecx) # => eax +21012 3d/compare-eax-and 0/imm32/false +21013 74/jump-if-= break/disp8 +21014 89/<- %eax 1/r32/ecx +21015 eb/jump $find-matching-primitive:end/disp8 +21016 } +21017 $find-matching-primitive:next-primitive: +21018 # curr = curr->next +21019 (lookup *(ecx+0x38) *(ecx+0x3c)) # Primitive-next Primitive-next => eax +21020 89/<- %ecx 0/r32/eax +21021 # +21022 e9/jump loop/disp32 +21023 } +21024 # return null +21025 b8/copy-to-eax 0/imm32 +21026 $find-matching-primitive:end: +21027 # . restore registers +21028 59/pop-to-ecx +21029 # . epilogue +21030 89/<- %esp 5/r32/ebp +21031 5d/pop-to-ebp +21032 c3/return +21033 +21034 mu-stmt-matches-primitive?: # stmt: (addr stmt), primitive: (addr primitive) -> result/eax: boolean +21035 # A mu stmt matches a primitive if the name matches, all the inout vars +21036 # match, and all the output vars match. +21037 # Vars match if types match and registers match. +21038 # In addition, a stmt output matches a primitive's output if types match +21039 # and the primitive has a wildcard register. +21040 # . prologue +21041 55/push-ebp +21042 89/<- %ebp 4/r32/esp +21043 # . save registers +21044 51/push-ecx +21045 52/push-edx +21046 53/push-ebx +21047 56/push-esi +21048 57/push-edi +21049 # ecx = stmt +21050 8b/-> *(ebp+8) 1/r32/ecx +21051 # edx = primitive +21052 8b/-> *(ebp+0xc) 2/r32/edx +21053 { +21054 $mu-stmt-matches-primitive?:check-name: +21055 # if (primitive->name != stmt->operation) return false +21056 # . var esi: (addr array byte) = lookup(stmt->operation) +21057 (lookup *(ecx+4) *(ecx+8)) # Stmt1-operation Stmt1-operation => eax +21058 89/<- %esi 0/r32/eax +21059 # . var edi: (addr array byte) = lookup(primitive->name) +21060 (lookup *edx *(edx+4)) # Primitive-name Primitive-name => eax +21061 89/<- %edi 0/r32/eax +21062 (string-equal? %esi %edi) # => eax +21063 3d/compare-eax-and 0/imm32/false +21064 75/jump-if-!= break/disp8 +21065 b8/copy-to-eax 0/imm32 +21066 e9/jump $mu-stmt-matches-primitive?:end/disp32 +21067 } +21068 # var curr/esi: (addr stmt-var) = lookup(stmt->inouts) +21069 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax +21070 89/<- %esi 0/r32/eax +21071 # var curr2/edi: (addr list var) = lookup(primitive->inouts) +21072 (lookup *(edx+8) *(edx+0xc)) # Primitive-inouts Primitive-inouts => eax +21073 89/<- %edi 0/r32/eax +21074 { +21075 $mu-stmt-matches-primitive?:inouts-loop: +21076 # if (curr == 0 && curr2 == 0) move on to check outputs +21077 { +21078 $mu-stmt-matches-primitive?:check-both-inouts-null: +21079 81 7/subop/compare %esi 0/imm32 +21080 75/jump-if-!= break/disp8 +21081 $mu-stmt-matches-primitive?:stmt-inout-null: +21082 81 7/subop/compare %edi 0/imm32 +21083 0f 84/jump-if-= $mu-stmt-matches-primitive?:check-outputs/disp32 +21084 $mu-stmt-matches-primitive?:stmt-inout-null-and-prim-inout-not-null: +21085 # return false +21086 b8/copy-to-eax 0/imm32/false +21087 e9/jump $mu-stmt-matches-primitive?:end/disp32 +21088 } +21089 # if (curr2 == 0) return false +21090 { +21091 $mu-stmt-matches-primitive?:check-prim-inout-null: +21092 81 7/subop/compare %edi 0/imm32 +21093 75/jump-if-!= break/disp8 +21094 $mu-stmt-matches-primitive?:prim-inout-null: +21095 b8/copy-to-eax 0/imm32/false +21096 e9/jump $mu-stmt-matches-primitive?:end/disp32 +21097 } +21098 # if (curr != curr2) return false +21099 { +21100 $mu-stmt-matches-primitive?:check-inouts-match: +21101 (lookup *edi *(edi+4)) # List-value List-value => eax +21102 (operand-matches-primitive? %esi %eax) # => eax +21103 3d/compare-eax-and 0/imm32/false +21104 75/jump-if-!= break/disp8 +21105 $mu-stmt-matches-primitive?:inouts-match: +21106 b8/copy-to-eax 0/imm32/false +21107 e9/jump $mu-stmt-matches-primitive?:end/disp32 +21108 } +21109 $mu-stmt-matches-primitive?:next-inout: +21110 # curr = lookup(curr->next) +21111 (lookup *(esi+8) *(esi+0xc)) # Stmt-var-next Stmt-var-next => eax +21112 89/<- %esi 0/r32/eax +21113 # curr2 = lookup(curr2->next) +21114 (lookup *(edi+8) *(edi+0xc)) # List-next List-next => eax +21115 89/<- %edi 0/r32/eax +21116 # +21117 e9/jump loop/disp32 +21118 } +21119 $mu-stmt-matches-primitive?:check-outputs: +21120 # var curr/esi: (addr stmt-var) = lookup(stmt->outputs) +21121 (lookup *(ecx+0x14) *(ecx+0x18)) # Stmt1-outputs Stmt1-outputs => eax +21122 89/<- %esi 0/r32/eax +21123 # var curr2/edi: (addr list var) = lookup(primitive->outputs) +21124 (lookup *(edx+0x10) *(edx+0x14)) # Primitive-outputs Primitive-outputs => eax +21125 89/<- %edi 0/r32/eax +21126 { +21127 $mu-stmt-matches-primitive?:outputs-loop: +21128 # if (curr == 0) return (curr2 == 0) +21129 { +21130 $mu-stmt-matches-primitive?:check-both-outputs-null: +21131 81 7/subop/compare %esi 0/imm32 +21132 75/jump-if-!= break/disp8 +21133 { +21134 $mu-stmt-matches-primitive?:stmt-output-null: +21135 81 7/subop/compare %edi 0/imm32 +21136 75/jump-if-!= break/disp8 +21137 $mu-stmt-matches-primitive?:both-outputs-null: +21138 # return true +21139 b8/copy-to-eax 1/imm32 +21140 e9/jump $mu-stmt-matches-primitive?:end/disp32 +21141 } +21142 $mu-stmt-matches-primitive?:stmt-output-null-and-prim-output-not-null: +21143 # return false +21144 b8/copy-to-eax 0/imm32 +21145 e9/jump $mu-stmt-matches-primitive?:end/disp32 +21146 } +21147 # if (curr2 == 0) return false +21148 { +21149 $mu-stmt-matches-primitive?:check-prim-output-null: +21150 81 7/subop/compare %edi 0/imm32 +21151 75/jump-if-!= break/disp8 +21152 $mu-stmt-matches-primitive?:prim-output-is-null: +21153 b8/copy-to-eax 0/imm32 +21154 e9/jump $mu-stmt-matches-primitive?:end/disp32 +21155 } +21156 # if (curr != curr2) return false +21157 { +21158 $mu-stmt-matches-primitive?:check-outputs-match: +21159 (lookup *edi *(edi+4)) # List-value List-value => eax +21160 (operand-matches-primitive? %esi %eax) # => eax +21161 3d/compare-eax-and 0/imm32/false +21162 75/jump-if-!= break/disp8 +21163 $mu-stmt-matches-primitive?:outputs-match: +21164 b8/copy-to-eax 0/imm32 +21165 e9/jump $mu-stmt-matches-primitive?:end/disp32 +21166 } +21167 $mu-stmt-matches-primitive?:next-output: +21168 # curr = lookup(curr->next) +21169 (lookup *(esi+8) *(esi+0xc)) # Stmt-var-next Stmt-var-next => eax +21170 89/<- %esi 0/r32/eax +21171 # curr2 = lookup(curr2->next) +21172 (lookup *(edi+8) *(edi+0xc)) # List-next List-next => eax +21173 89/<- %edi 0/r32/eax +21174 # +21175 e9/jump loop/disp32 +21176 } +21177 $mu-stmt-matches-primitive?:return-true: +21178 b8/copy-to-eax 1/imm32 +21179 $mu-stmt-matches-primitive?:end: +21180 # . restore registers +21181 5f/pop-to-edi +21182 5e/pop-to-esi +21183 5b/pop-to-ebx +21184 5a/pop-to-edx +21185 59/pop-to-ecx +21186 # . epilogue +21187 89/<- %esp 5/r32/ebp +21188 5d/pop-to-ebp +21189 c3/return +21190 +21191 operand-matches-primitive?: # s: (addr stmt-var), prim-var: (addr var) -> result/eax: boolean +21192 # . prologue +21193 55/push-ebp +21194 89/<- %ebp 4/r32/esp +21195 # . save registers +21196 51/push-ecx +21197 52/push-edx +21198 53/push-ebx +21199 56/push-esi +21200 57/push-edi +21201 # ecx = s +21202 8b/-> *(ebp+8) 1/r32/ecx +21203 # var var/esi: (addr var) = lookup(s->value) +21204 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax +21205 89/<- %esi 0/r32/eax +21206 # edi = prim-var +21207 8b/-> *(ebp+0xc) 7/r32/edi +21208 $operand-matches-primitive?:check-type: +21209 # if !category-match?(var->type, prim-var->type) return false +21210 # . var vtype/ebx: (addr type-tree) = lookup(var->type) +21211 (lookup *(esi+8) *(esi+0xc)) # Var-type Var-type => eax +21212 89/<- %ebx 0/r32/eax +21213 # . var ptype/eax: (addr type-tree) = lookup(prim-var->type) +21214 (lookup *(edi+8) *(edi+0xc)) # Var-type Var-type => eax +21215 (subx-type-category-match? %ebx %eax) # => eax +21216 3d/compare-eax-and 0/imm32/false +21217 0f 84/jump-if-= $operand-matches-primitive?:return-false/disp32 +21218 { +21219 $operand-matches-primitive?:check-register: +21220 # if prim-var is in memory and var is in register but dereference, match +21221 { +21222 81 7/subop/compare *(edi+0x18) 0/imm32 # Var-register +21223 0f 85/jump-if-!= break/disp32 +21224 81 7/subop/compare *(esi+0x18) 0/imm32 # Var-register +21225 74/jump-if-= break/disp8 +21226 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref +21227 74/jump-if-= break/disp8 +21228 $operand-matches-primitive?:var-deref-match: +21229 e9/jump $operand-matches-primitive?:return-true/disp32 +21230 } +21231 # if prim-var is in register and var is in register but dereference, no match +21232 { +21233 81 7/subop/compare *(edi+0x18) 0/imm32 # Var-register +21234 0f 84/jump-if-= break/disp32 +21235 81 7/subop/compare *(esi+0x18) 0/imm32 # Var-register +21236 0f 84/jump-if-= break/disp32 +21237 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref +21238 74/jump-if-= break/disp8 +21239 $operand-matches-primitive?:var-deref-no-match: +21240 e9/jump $operand-matches-primitive?:return-false/disp32 +21241 } +21242 # return false if var->register doesn't match prim-var->register +21243 { +21244 # if register addresses are equal, it's a match +21245 # var vreg/ebx: (addr array byte) = lookup(var->register) +21246 (lookup *(esi+0x18) *(esi+0x1c)) # Var-register Var-register => eax +21247 89/<- %ebx 0/r32/eax +21248 # var preg/ecx: (addr array byte) = lookup(prim-var->register) +21249 (lookup *(edi+0x18) *(edi+0x1c)) # Var-register Var-register => eax +21250 89/<- %ecx 0/r32/eax +21251 # if (vreg == preg) break +21252 39/compare %ecx 3/r32/ebx +21253 74/jump-if-= break/disp8 +21254 $operand-matches-primitive?:var-register-no-match: +21255 # if either address is 0, return false +21256 81 7/subop/compare %ebx 0/imm32 +21257 74/jump-if-= $operand-matches-primitive?:return-false/disp8 +21258 81 7/subop/compare %ecx 0/imm32 +21259 74/jump-if-= $operand-matches-primitive?:return-false/disp8 +21260 # if prim-var->register is wildcard, it's a match +21261 (string-equal? %ecx "*") # Any-register => eax +21262 3d/compare-eax-and 0/imm32/false +21263 75/jump-if-!= break/disp8 +21264 $operand-matches-primitive?:wildcard-no-match: +21265 # if string contents aren't equal, return false +21266 (string-equal? %ecx %ebx) # => eax +21267 3d/compare-eax-and 0/imm32/false +21268 74/jump-if-= $operand-matches-primitive?:return-false/disp8 +21269 } +21270 } +21271 $operand-matches-primitive?:return-true: +21272 b8/copy-to-eax 1/imm32/true +21273 eb/jump $operand-matches-primitive?:end/disp8 +21274 $operand-matches-primitive?:return-false: +21275 b8/copy-to-eax 0/imm32/false +21276 $operand-matches-primitive?:end: +21277 # . restore registers +21278 5f/pop-to-edi +21279 5e/pop-to-esi +21280 5b/pop-to-ebx +21281 5a/pop-to-edx +21282 59/pop-to-ecx 21283 # . epilogue 21284 89/<- %esp 5/r32/ebp 21285 5d/pop-to-ebp 21286 c3/return 21287 -21288 test-add-literal-to-reg: -21289 # var1/ecx <- add 0x34 -21290 # => -21291 # 81 0/subop/add %ecx 0x34/imm32 -21292 # -21293 # . prologue -21294 55/push-ebp -21295 89/<- %ebp 4/r32/esp -21296 # setup -21297 (clear-stream _test-output-stream) -21298 (clear-stream $_test-output-buffered-file->buffer) -21299 $test-add-literal-to-reg:initialize-var-type: -21300 # var type/ecx: (payload type-tree) = int -21301 68/push 0/imm32/right:null -21302 68/push 0/imm32/right:null -21303 68/push 0/imm32/left:unused -21304 68/push 1/imm32/value:int -21305 68/push 1/imm32/is-atom?:true -21306 68/push 0x11/imm32/alloc-id:fake:payload -21307 89/<- %ecx 4/r32/esp -21308 $test-add-literal-to-reg:initialize-var: -21309 # var v/ecx: (payload var) -21310 68/push 0/imm32/register -21311 68/push 0/imm32/register -21312 68/push 0/imm32/no-stack-offset -21313 68/push 1/imm32/block-depth -21314 51/push-ecx -21315 68/push 0x11/imm32/alloc-id:fake -21316 68/push 0/imm32/name -21317 68/push 0/imm32/name -21318 68/push 0x11/imm32/alloc-id:fake:payload -21319 89/<- %ecx 4/r32/esp -21320 $test-add-literal-to-reg:initialize-var-name: -21321 # v->name = "v" -21322 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -21323 (copy-array Heap "v" %eax) -21324 $test-add-literal-to-reg:initialize-var-register: -21325 # v->register = "ecx" -21326 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 -21327 (copy-array Heap "ecx" %eax) -21328 $test-add-literal-to-reg:initialize-literal-type: -21329 # var type/edx: (payload type-tree) = literal -21330 68/push 0/imm32/right:null -21331 68/push 0/imm32/right:null -21332 68/push 0/imm32/left:unused -21333 68/push 0/imm32/value:literal -21334 68/push 1/imm32/is-atom?:true -21335 68/push 0x11/imm32/alloc-id:fake:payload -21336 89/<- %edx 4/r32/esp -21337 $test-add-literal-to-reg:initialize-literal: -21338 # var l/edx: (payload var) -21339 68/push 0/imm32/register -21340 68/push 0/imm32/register -21341 68/push 0/imm32/no-stack-offset -21342 68/push 1/imm32/block-depth -21343 52/push-edx -21344 68/push 0x11/imm32/alloc-id:fake -21345 68/push 0/imm32/name -21346 68/push 0/imm32/name -21347 68/push 0x11/imm32/alloc-id:fake:payload -21348 89/<- %edx 4/r32/esp -21349 $test-add-literal-to-reg:initialize-literal-value: -21350 # l->name = "0x34" -21351 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 -21352 (copy-array Heap "0x34" %eax) -21353 $test-add-literal-to-reg:initialize-inouts: -21354 # var inouts/esi: (payload stmt-var) = [l] -21355 68/push 0/imm32/is-deref:false -21356 68/push 0/imm32/next -21357 68/push 0/imm32/next -21358 52/push-edx/l -21359 68/push 0x11/imm32/alloc-id:fake -21360 68/push 0x11/imm32/alloc-id:fake:payload -21361 89/<- %esi 4/r32/esp -21362 $test-add-literal-to-reg:initialize-outputs: -21363 # var outputs/edi: (payload stmt-var) = [v] -21364 68/push 0/imm32/is-deref:false -21365 68/push 0/imm32/next -21366 68/push 0/imm32/next -21367 51/push-ecx/v -21368 68/push 0x11/imm32/alloc-id:fake -21369 68/push 0x11/imm32/alloc-id:fake:payload -21370 89/<- %edi 4/r32/esp -21371 $test-add-literal-to-reg:initialize-stmt: -21372 # var stmt/esi: (addr statement) -21373 68/push 0/imm32/next -21374 68/push 0/imm32/next -21375 57/push-edi/outputs -21376 68/push 0x11/imm32/alloc-id:fake -21377 56/push-esi/inouts -21378 68/push 0x11/imm32/alloc-id:fake -21379 68/push 0/imm32/operation -21380 68/push 0/imm32/operation -21381 68/push 1/imm32/tag:stmt1 -21382 89/<- %esi 4/r32/esp -21383 $test-add-literal-to-reg:initialize-stmt-operation: -21384 # stmt->operation = "add" -21385 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -21386 (copy-array Heap "add" %eax) -21387 # convert -21388 c7 0/subop/copy *Curr-block-depth 0/imm32 -21389 (emit-subx-stmt _test-output-buffered-file %esi Primitives Stderr 0) -21390 (flush _test-output-buffered-file) -21391 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -21397 # check output -21398 (check-next-stream-line-equal _test-output-stream "81 0/subop/add %ecx 0x34/imm32" "F - test-add-literal-to-reg") -21399 # . epilogue -21400 89/<- %esp 5/r32/ebp -21401 5d/pop-to-ebp -21402 c3/return -21403 -21404 test-add-literal-to-mem: -21405 # add-to var1, 0x34 -21406 # => -21407 # 81 0/subop/add %eax 0x34/imm32 -21408 # -21409 # . prologue -21410 55/push-ebp -21411 89/<- %ebp 4/r32/esp -21412 # setup -21413 (clear-stream _test-output-stream) -21414 (clear-stream $_test-output-buffered-file->buffer) -21415 $test-add-literal-to-mem:initialize-type: -21416 # var type/ecx: (payload type-tree) = int -21417 68/push 0/imm32/right:null -21418 68/push 0/imm32/right:null -21419 68/push 0/imm32/left:unused -21420 68/push 1/imm32/value:int -21421 68/push 1/imm32/is-atom?:true -21422 68/push 0x11/imm32/alloc-id:fake:payload -21423 89/<- %ecx 4/r32/esp -21424 $test-add-literal-to-mem:initialize-var1: -21425 # var var1/ecx: (payload var) -21426 68/push 0/imm32/register -21427 68/push 0/imm32/register -21428 68/push 8/imm32/stack-offset -21429 68/push 1/imm32/block-depth -21430 51/push-ecx -21431 68/push 0x11/imm32/alloc-id:fake -21432 68/push 0/imm32/name -21433 68/push 0/imm32/name -21434 68/push 0x11/imm32/alloc-id:fake:payload -21435 89/<- %ecx 4/r32/esp -21436 $test-add-literal-to-mem:initialize-var1-name: -21437 # var1->name = "var1" -21438 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -21439 (copy-array Heap "var1" %eax) -21440 $test-add-literal-to-mem:initialize-literal-type: -21441 # var type/edx: (payload type-tree) = literal -21442 68/push 0/imm32/right:null -21443 68/push 0/imm32/right:null -21444 68/push 0/imm32/left:unused -21445 68/push 0/imm32/value:literal -21446 68/push 1/imm32/is-atom?:true -21447 68/push 0x11/imm32/alloc-id:fake:payload -21448 89/<- %edx 4/r32/esp -21449 $test-add-literal-to-mem:initialize-literal: -21450 # var l/edx: (payload var) -21451 68/push 0/imm32/register -21452 68/push 0/imm32/register -21453 68/push 0/imm32/no-stack-offset -21454 68/push 1/imm32/block-depth -21455 52/push-edx -21456 68/push 0x11/imm32/alloc-id:fake -21457 68/push 0/imm32/name -21458 68/push 0/imm32/name -21459 68/push 0x11/imm32/alloc-id:fake:payload -21460 89/<- %edx 4/r32/esp -21461 $test-add-literal-to-mem:initialize-literal-value: -21462 # l->name = "0x34" -21463 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 -21464 (copy-array Heap "0x34" %eax) -21465 $test-add-literal-to-mem:initialize-inouts: -21466 # var inouts/esi: (payload stmt-var) = [l] -21467 68/push 0/imm32/is-deref:false -21468 68/push 0/imm32/next -21469 68/push 0/imm32/next -21470 52/push-edx/l -21471 68/push 0x11/imm32/alloc-id:fake -21472 68/push 0x11/imm32/alloc-id:fake:payload -21473 89/<- %esi 4/r32/esp -21474 # var inouts = (handle stmt-var) = [var1, var2] -21475 68/push 0/imm32/is-deref:false -21476 56/push-esi/next -21477 68/push 0x11/imm32/alloc-id:fake -21478 51/push-ecx/var1 -21479 68/push 0x11/imm32/alloc-id:fake -21480 68/push 0x11/imm32/alloc-id:fake:payload -21481 89/<- %esi 4/r32/esp -21482 $test-add-literal-to-mem:initialize-stmt: -21483 # var stmt/esi: (addr statement) -21484 68/push 0/imm32/next -21485 68/push 0/imm32/next -21486 68/push 0/imm32/outputs -21487 68/push 0/imm32/outputs -21488 56/push-esi/inouts -21489 68/push 0x11/imm32/alloc-id:fake -21490 68/push 0/imm32/operation -21491 68/push 0/imm32/operation -21492 68/push 1/imm32/tag:stmt1 -21493 89/<- %esi 4/r32/esp -21494 $test-add-literal-to-mem:initialize-stmt-operation: -21495 # stmt->operation = "add-to" -21496 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -21497 (copy-array Heap "add-to" %eax) -21498 # convert -21499 c7 0/subop/copy *Curr-block-depth 0/imm32 -21500 (emit-subx-stmt _test-output-buffered-file %esi Primitives Stderr 0) -21501 (flush _test-output-buffered-file) -21502 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -21508 # check output -21509 (check-next-stream-line-equal _test-output-stream "81 0/subop/add *(ebp+0x00000008) 0x34/imm32" "F - test-add-literal-to-mem") -21510 # . epilogue -21511 89/<- %esp 5/r32/ebp -21512 5d/pop-to-ebp -21513 c3/return -21514 -21515 test-shift-reg-by-literal: -21516 # var1/ecx <- shift-left 2 -21517 # => -21518 # c1/shift 4/subop/left %ecx 2/imm8 -21519 # -21520 # . prologue -21521 55/push-ebp -21522 89/<- %ebp 4/r32/esp -21523 # setup -21524 (clear-stream _test-output-stream) -21525 (clear-stream $_test-output-buffered-file->buffer) -21526 $test-shift-reg-by-literal:initialize-var-type: -21527 # var type/ecx: (payload type-tree) = int -21528 68/push 0/imm32/right:null -21529 68/push 0/imm32/right:null -21530 68/push 0/imm32/left:unused -21531 68/push 1/imm32/value:int -21532 68/push 1/imm32/is-atom?:true -21533 68/push 0x11/imm32/alloc-id:fake:payload -21534 89/<- %ecx 4/r32/esp -21535 $test-shift-reg-by-literal:initialize-var: -21536 # var v/ecx: (payload var) -21537 68/push 0/imm32/register -21538 68/push 0/imm32/register -21539 68/push 0/imm32/no-stack-offset -21540 68/push 1/imm32/block-depth -21541 51/push-ecx -21542 68/push 0x11/imm32/alloc-id:fake -21543 68/push 0/imm32/name -21544 68/push 0/imm32/name -21545 68/push 0x11/imm32/alloc-id:fake:payload -21546 89/<- %ecx 4/r32/esp -21547 $test-shift-reg-by-literal:initialize-var-name: -21548 # v->name = "v" -21549 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -21550 (copy-array Heap "v" %eax) -21551 $test-shift-reg-by-literal:initialize-var-register: -21552 # v->register = "ecx" -21553 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 -21554 (copy-array Heap "ecx" %eax) -21555 $test-shift-reg-by-literal:initialize-literal-type: -21556 # var type/edx: (payload type-tree) = literal -21557 68/push 0/imm32/right:null -21558 68/push 0/imm32/right:null -21559 68/push 0/imm32/left:unused -21560 68/push 0/imm32/value:literal -21561 68/push 1/imm32/is-atom?:true -21562 68/push 0x11/imm32/alloc-id:fake:payload -21563 89/<- %edx 4/r32/esp -21564 $test-shift-reg-by-literal:initialize-literal: -21565 # var l/edx: (payload var) -21566 68/push 0/imm32/register -21567 68/push 0/imm32/register -21568 68/push 0/imm32/no-stack-offset -21569 68/push 1/imm32/block-depth -21570 52/push-edx -21571 68/push 0x11/imm32/alloc-id:fake -21572 68/push 0/imm32/name -21573 68/push 0/imm32/name -21574 68/push 0x11/imm32/alloc-id:fake:payload -21575 89/<- %edx 4/r32/esp -21576 $test-shift-reg-by-literal:initialize-literal-value: -21577 # l->name = "2" -21578 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 -21579 (copy-array Heap "2" %eax) -21580 $test-shift-reg-by-literal:initialize-inouts: -21581 # var inouts/esi: (payload stmt-var) = [l] -21582 68/push 0/imm32/is-deref:false -21583 68/push 0/imm32/next -21584 68/push 0/imm32/next -21585 52/push-edx/l -21586 68/push 0x11/imm32/alloc-id:fake -21587 68/push 0x11/imm32/alloc-id:fake:payload -21588 89/<- %esi 4/r32/esp -21589 $test-shift-reg-by-literal:initialize-outputs: -21590 # var outputs/edi: (payload stmt-var) = [v] -21591 68/push 0/imm32/is-deref:false -21592 68/push 0/imm32/next -21593 68/push 0/imm32/next -21594 51/push-ecx/v -21595 68/push 0x11/imm32/alloc-id:fake -21596 68/push 0x11/imm32/alloc-id:fake:payload -21597 89/<- %edi 4/r32/esp -21598 $test-shift-reg-by-literal:initialize-stmt: -21599 # var stmt/esi: (addr statement) -21600 68/push 0/imm32/next -21601 68/push 0/imm32/next -21602 57/push-edi/outputs -21603 68/push 0x11/imm32/alloc-id:fake -21604 56/push-esi/inouts -21605 68/push 0x11/imm32/alloc-id:fake -21606 68/push 0/imm32/operation -21607 68/push 0/imm32/operation -21608 68/push 1/imm32/tag:stmt1 -21609 89/<- %esi 4/r32/esp -21610 $test-shift-reg-by-literal:initialize-stmt-operation: -21611 # stmt->operation = "shift-left" -21612 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -21613 (copy-array Heap "shift-left" %eax) -21614 # convert -21615 c7 0/subop/copy *Curr-block-depth 0/imm32 -21616 (emit-subx-stmt _test-output-buffered-file %esi Primitives Stderr 0) -21617 (flush _test-output-buffered-file) -21618 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -21624 # check output -21625 (check-next-stream-line-equal _test-output-stream "c1/shift 4/subop/left %ecx 2/imm8" "F - test-shift-reg-by-literal") -21626 # . epilogue -21627 89/<- %esp 5/r32/ebp -21628 5d/pop-to-ebp -21629 c3/return -21630 -21631 test-shift-mem-by-literal: -21632 # shift-left var 3 -21633 # => -21634 # c1/shift 4/subop/left *(ebp+8) 3/imm8 -21635 # -21636 # . prologue -21637 55/push-ebp -21638 89/<- %ebp 4/r32/esp -21639 # setup -21640 (clear-stream _test-output-stream) -21641 (clear-stream $_test-output-buffered-file->buffer) -21642 $test-shift-mem-by-literal:initialize-type: -21643 # var type/ecx: (payload type-tree) = int -21644 68/push 0/imm32/right:null -21645 68/push 0/imm32/right:null -21646 68/push 0/imm32/left:unused -21647 68/push 1/imm32/value:int -21648 68/push 1/imm32/is-atom?:true -21649 68/push 0x11/imm32/alloc-id:fake:payload -21650 89/<- %ecx 4/r32/esp -21651 $test-shift-mem-by-literal:initialize-var1: -21652 # var var1/ecx: (payload var) +21288 find-matching-function: # functions: (addr function), stmt: (addr stmt) -> result/eax: (addr function) +21289 # . prologue +21290 55/push-ebp +21291 89/<- %ebp 4/r32/esp +21292 # . save registers +21293 51/push-ecx +21294 # var curr/ecx: (handle function) = functions +21295 8b/-> *(ebp+8) 1/r32/ecx +21296 { +21297 # if (curr == null) break +21298 81 7/subop/compare %ecx 0/imm32 +21299 74/jump-if-= break/disp8 +21300 #? (write-buffered Stderr "iter\n") +21301 #? (flush Stderr) +21302 # if match(stmt, curr) return curr +21303 { +21304 (mu-stmt-matches-function? *(ebp+0xc) %ecx) # => eax +21305 3d/compare-eax-and 0/imm32/false +21306 74/jump-if-= break/disp8 +21307 89/<- %eax 1/r32/ecx +21308 eb/jump $find-matching-function:end/disp8 +21309 } +21310 # curr = curr->next +21311 (lookup *(ecx+0x20) *(ecx+0x24)) # Function-next Function-next => eax +21312 89/<- %ecx 0/r32/eax +21313 # +21314 eb/jump loop/disp8 +21315 } +21316 # return null +21317 b8/copy-to-eax 0/imm32 +21318 $find-matching-function:end: +21319 # . restore registers +21320 59/pop-to-ecx +21321 # . epilogue +21322 89/<- %esp 5/r32/ebp +21323 5d/pop-to-ebp +21324 c3/return +21325 +21326 # Just compare names; user-defined functions don't support overloading yet. +21327 mu-stmt-matches-function?: # stmt: (addr stmt1), function: (addr function) -> result/eax: boolean +21328 # . prologue +21329 55/push-ebp +21330 89/<- %ebp 4/r32/esp +21331 # . save registers +21332 51/push-ecx +21333 # return function->name == stmt->operation +21334 # ecx = lookup(stmt->operation) +21335 8b/-> *(ebp+8) 0/r32/eax +21336 (lookup *(eax+4) *(eax+8)) # Stmt1-operation Stmt1-operation => eax +21337 89/<- %ecx 0/r32/eax +21338 # eax = lookup(function->name) +21339 8b/-> *(ebp+0xc) 0/r32/eax +21340 (lookup *eax *(eax+4)) # Function-name Function-name => eax +21341 (string-equal? %eax %ecx) # => eax +21342 $mu-stmt-matches-function?:end: +21343 # . restore registers +21344 59/pop-to-ecx +21345 # . epilogue +21346 89/<- %esp 5/r32/ebp +21347 5d/pop-to-ebp +21348 c3/return +21349 +21350 # Type-checking happens elsewhere. This method is for selecting between +21351 # primitives. +21352 subx-type-category-match?: # a: (addr type-tree), b: (addr type-tree) -> result/eax: boolean +21353 # . prologue +21354 55/push-ebp +21355 89/<- %ebp 4/r32/esp +21356 # . save registers +21357 51/push-ecx +21358 # var alit/ecx: boolean = is-literal-type?(a) +21359 (is-simple-mu-type? *(ebp+8) 0) # => eax +21360 89/<- %ecx 0/r32/eax +21361 # var blit/eax: boolean = is-literal-type?(b) +21362 (is-simple-mu-type? *(ebp+0xc) 0) # => eax +21363 # return alit == blit +21364 39/compare %eax 1/r32/ecx +21365 0f 94/set-byte-if-= %al +21366 81 4/subop/and %eax 0xff/imm32 +21367 $subx-type-category-match?:end: +21368 # . restore registers +21369 59/pop-to-ecx +21370 # . epilogue +21371 89/<- %esp 5/r32/ebp +21372 5d/pop-to-ebp +21373 c3/return +21374 +21375 is-simple-mu-type?: # a: (addr type-tree), n: type-id -> result/eax: boolean +21376 # . prologue +21377 55/push-ebp +21378 89/<- %ebp 4/r32/esp +21379 # . save registers +21380 51/push-ecx +21381 # ecx = n +21382 8b/-> *(ebp+0xc) 1/r32/ecx +21383 # return (a->value == n) +21384 8b/-> *(ebp+8) 0/r32/eax +21385 39/compare *(eax+4) 1/r32/ecx # Type-tree-value +21386 0f 94/set-byte-if-= %al +21387 81 4/subop/and %eax 0xff/imm32 +21388 $is-simple-mu-type?:end: +21389 # . restore registers +21390 59/pop-to-ecx +21391 # . epilogue +21392 89/<- %esp 5/r32/ebp +21393 5d/pop-to-ebp +21394 c3/return +21395 +21396 is-mu-addr-type?: # a: (addr type-tree) -> result/eax: boolean +21397 # . prologue +21398 55/push-ebp +21399 89/<- %ebp 4/r32/esp +21400 # eax = a +21401 8b/-> *(ebp+8) 0/r32/eax +21402 # if (!a->is-atom?) a = a->left +21403 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom +21404 { +21405 75/jump-if-!= break/disp8 +21406 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +21407 } +21408 # return (a->value == addr) +21409 81 7/subop/compare *(eax+4) 2/imm32/addr # Type-tree-value +21410 0f 94/set-byte-if-= %al +21411 81 4/subop/and %eax 0xff/imm32 +21412 $is-mu-addr-type?:end: +21413 # . epilogue +21414 89/<- %esp 5/r32/ebp +21415 5d/pop-to-ebp +21416 c3/return +21417 +21418 is-mu-array-type?: # a: (addr type-tree) -> result/eax: boolean +21419 # . prologue +21420 55/push-ebp +21421 89/<- %ebp 4/r32/esp +21422 # eax = a +21423 8b/-> *(ebp+8) 0/r32/eax +21424 # if (!a->is-atom?) a = a->left +21425 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom +21426 { +21427 75/jump-if-!= break/disp8 +21428 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +21429 } +21430 # return (a->value == array) +21431 81 7/subop/compare *(eax+4) 3/imm32/array # Type-tree-value +21432 0f 94/set-byte-if-= %al +21433 81 4/subop/and %eax 0xff/imm32 +21434 $is-mu-array-type?:end: +21435 # . epilogue +21436 89/<- %esp 5/r32/ebp +21437 5d/pop-to-ebp +21438 c3/return +21439 +21440 is-mu-stream-type?: # a: (addr type-tree) -> result/eax: boolean +21441 # . prologue +21442 55/push-ebp +21443 89/<- %ebp 4/r32/esp +21444 # eax = a +21445 8b/-> *(ebp+8) 0/r32/eax +21446 # if (!a->is-atom?) a = a->left +21447 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom +21448 { +21449 75/jump-if-!= break/disp8 +21450 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +21451 } +21452 # return (a->value == stream) +21453 81 7/subop/compare *(eax+4) 0xb/imm32/stream # Type-tree-value +21454 0f 94/set-byte-if-= %al +21455 81 4/subop/and %eax 0xff/imm32 +21456 $is-mu-stream-type?:end: +21457 # . epilogue +21458 89/<- %esp 5/r32/ebp +21459 5d/pop-to-ebp +21460 c3/return +21461 +21462 test-emit-subx-stmt-primitive: +21463 # Primitive operation on a variable on the stack. +21464 # increment foo +21465 # => +21466 # ff 0/subop/increment *(ebp-8) +21467 # +21468 # There's a variable on the var stack as follows: +21469 # name: 'foo' +21470 # type: int +21471 # stack-offset: -8 +21472 # +21473 # There's a primitive with this info: +21474 # name: 'increment' +21475 # inouts: int/mem +21476 # value: 'ff 0/subop/increment' +21477 # +21478 # . prologue +21479 55/push-ebp +21480 89/<- %ebp 4/r32/esp +21481 # setup +21482 (clear-stream _test-output-stream) +21483 (clear-stream $_test-output-buffered-file->buffer) +21484 # simulate allocated payloads starting with an initial fake alloc-id (0x11) +21485 $test-emit-subx-stmt-primitive:initialize-type: +21486 # var type/ecx: (payload type-tree) = int +21487 68/push 0/imm32/right:null +21488 68/push 0/imm32/right:null +21489 68/push 0/imm32/left:unused +21490 68/push 1/imm32/value:int +21491 68/push 1/imm32/is-atom?:true +21492 68/push 0x11/imm32/alloc-id:fake:payload +21493 89/<- %ecx 4/r32/esp +21494 $test-emit-subx-stmt-primitive:initialize-var: +21495 # var var-foo/ecx: (payload var) = var(type) +21496 68/push 0/imm32/no-register +21497 68/push 0/imm32/no-register +21498 68/push -8/imm32/stack-offset +21499 68/push 1/imm32/block-depth +21500 51/push-ecx/type +21501 68/push 0x11/imm32/alloc-id:fake +21502 68/push 0/imm32/name +21503 68/push 0/imm32/name +21504 68/push 0x11/imm32/alloc-id:fake:payload +21505 89/<- %ecx 4/r32/esp +21506 $test-emit-subx-stmt-primitive:initialize-var-name: +21507 # var-foo->name = "foo" +21508 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +21509 (copy-array Heap "foo" %eax) +21510 $test-emit-subx-stmt-primitive:initialize-stmt-var: +21511 # var operand/ebx: (payload stmt-var) = stmt-var(var-foo) +21512 68/push 0/imm32/is-deref:false +21513 68/push 0/imm32/next +21514 68/push 0/imm32/next +21515 51/push-ecx/var-foo +21516 68/push 0x11/imm32/alloc-id:fake +21517 68/push 0x11/imm32/alloc-id:fake:payload +21518 89/<- %ebx 4/r32/esp +21519 $test-emit-subx-stmt-primitive:initialize-stmt: +21520 # var stmt/esi: (addr statement) +21521 68/push 0/imm32/no-outputs +21522 68/push 0/imm32/no-outputs +21523 53/push-ebx/inouts +21524 68/push 0x11/imm32/alloc-id:fake +21525 68/push 0/imm32/operation +21526 68/push 0/imm32/operation +21527 68/push 1/imm32/tag +21528 89/<- %esi 4/r32/esp +21529 $test-emit-subx-stmt-primitive:initialize-stmt-operation: +21530 # stmt->operation = "increment" +21531 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +21532 (copy-array Heap "increment" %eax) +21533 $test-emit-subx-stmt-primitive:initialize-primitive: +21534 # var primitives/ebx: (addr primitive) +21535 68/push 0/imm32/next +21536 68/push 0/imm32/next +21537 68/push 0/imm32/output-is-write-only +21538 68/push 0/imm32/no-disp32 +21539 68/push 0/imm32/no-imm8 +21540 68/push 0/imm32/no-imm32 +21541 68/push 0/imm32/no-r32 +21542 68/push 1/imm32/rm32-is-first-inout +21543 68/push 0/imm32/subx-name +21544 68/push 0/imm32/subx-name +21545 68/push 0/imm32/no-outputs +21546 68/push 0/imm32/no-outputs +21547 53/push-ebx/inouts # hack: reuse stmt-var from call stmt as (list var) in function declaration +21548 68/push 0x11/imm32/alloc-id:fake +21549 68/push 0/imm32/name +21550 68/push 0/imm32/name +21551 89/<- %ebx 4/r32/esp +21552 $test-emit-subx-stmt-primitive:initialize-primitive-name: +21553 # primitives->name = "increment" +21554 (copy-array Heap "increment" %ebx) # Primitive-name +21555 $test-emit-subx-stmt-primitive:initialize-primitive-subx-name: +21556 # primitives->subx-name = "ff 0/subop/increment" +21557 8d/copy-address *(ebx+0x18) 0/r32/eax # Primitive-subx-name +21558 (copy-array Heap "ff 0/subop/increment" %eax) +21559 # convert +21560 c7 0/subop/copy *Curr-block-depth 0/imm32 +21561 (emit-subx-stmt _test-output-buffered-file %esi %ebx Stderr 0) +21562 (flush _test-output-buffered-file) +21563 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +21569 # check output +21570 (check-next-stream-line-equal _test-output-stream "ff 0/subop/increment *(ebp+0xfffffff8)" "F - test-emit-subx-stmt-primitive") +21571 # . epilogue +21572 89/<- %esp 5/r32/ebp +21573 5d/pop-to-ebp +21574 c3/return +21575 +21576 test-emit-subx-stmt-primitive-register: +21577 # Primitive operation on a variable in a register. +21578 # foo <- increment +21579 # => +21580 # ff 0/subop/increment %eax # sub-optimal, but should suffice +21581 # +21582 # There's a variable on the var stack as follows: +21583 # name: 'foo' +21584 # type: int +21585 # register: 'eax' +21586 # +21587 # There's a primitive with this info: +21588 # name: 'increment' +21589 # out: int/reg +21590 # value: 'ff 0/subop/increment' +21591 # +21592 # . prologue +21593 55/push-ebp +21594 89/<- %ebp 4/r32/esp +21595 # setup +21596 (clear-stream _test-output-stream) +21597 (clear-stream $_test-output-buffered-file->buffer) +21598 $test-emit-subx-stmt-primitive-register:initialize-type: +21599 # var type/ecx: (payload type-tree) = int +21600 68/push 0/imm32/right:null +21601 68/push 0/imm32/right:null +21602 68/push 0/imm32/left:unused +21603 68/push 1/imm32/value:int +21604 68/push 1/imm32/is-atom?:true +21605 68/push 0x11/imm32/alloc-id:fake:payload +21606 89/<- %ecx 4/r32/esp +21607 $test-emit-subx-stmt-primitive-register:initialize-var: +21608 # var var-foo/ecx: (payload var) +21609 68/push 0/imm32/register +21610 68/push 0/imm32/register +21611 68/push 0/imm32/no-stack-offset +21612 68/push 1/imm32/block-depth +21613 51/push-ecx +21614 68/push 0x11/imm32/alloc-id:fake +21615 68/push 0/imm32/name +21616 68/push 0/imm32/name +21617 68/push 0x11/imm32/alloc-id:fake:payload +21618 89/<- %ecx 4/r32/esp +21619 $test-emit-subx-stmt-primitive-register:initialize-var-name: +21620 # var-foo->name = "foo" +21621 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +21622 (copy-array Heap "foo" %eax) +21623 $test-emit-subx-stmt-primitive-register:initialize-var-register: +21624 # var-foo->register = "eax" +21625 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 +21626 (copy-array Heap "eax" %eax) +21627 $test-emit-subx-stmt-primitive-register:initialize-stmt-var: +21628 # var operand/ebx: (payload stmt-var) +21629 68/push 0/imm32/is-deref:false +21630 68/push 0/imm32/next +21631 68/push 0/imm32/next +21632 51/push-ecx/var-foo +21633 68/push 0x11/imm32/alloc-id:fake +21634 68/push 0x11/imm32/alloc-id:fake:payload +21635 89/<- %ebx 4/r32/esp +21636 $test-emit-subx-stmt-primitive-register:initialize-stmt: +21637 # var stmt/esi: (addr statement) +21638 53/push-ebx/outputs +21639 68/push 0x11/imm32/alloc-id:fake +21640 68/push 0/imm32/no-inouts +21641 68/push 0/imm32/no-inouts +21642 68/push 0/imm32/operation +21643 68/push 0/imm32/operation +21644 68/push 1/imm32 +21645 89/<- %esi 4/r32/esp +21646 $test-emit-subx-stmt-primitive-register:initialize-stmt-operation: +21647 # stmt->operation = "increment" +21648 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +21649 (copy-array Heap "increment" %eax) +21650 $test-emit-subx-stmt-primitive-register:initialize-formal-var: +21651 # var formal-var/ebx: (payload var) +21652 68/push 0/imm32/register 21653 68/push 0/imm32/register -21654 68/push 0/imm32/register -21655 68/push 8/imm32/stack-offset -21656 68/push 1/imm32/block-depth -21657 51/push-ecx -21658 68/push 0x11/imm32/alloc-id:fake +21654 68/push 0/imm32/no-stack-offset +21655 68/push 1/imm32/block-depth +21656 ff 6/subop/push *(ecx+0x10) # Var-type + payload alloc id + handle alloc id +21657 68/push 0x11/imm32/alloc-id:fake +21658 68/push 0/imm32/name 21659 68/push 0/imm32/name -21660 68/push 0/imm32/name -21661 68/push 0x11/imm32/alloc-id:fake:payload -21662 89/<- %ecx 4/r32/esp -21663 $test-shift-mem-by-literal:initialize-var1-name: -21664 # var1->name = "var1" -21665 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -21666 (copy-array Heap "var1" %eax) -21667 $test-shift-mem-by-literal:initialize-literal-type: -21668 # var type/edx: (payload type-tree) = literal -21669 68/push 0/imm32/right:null -21670 68/push 0/imm32/right:null -21671 68/push 0/imm32/left:unused -21672 68/push 0/imm32/value:literal -21673 68/push 1/imm32/is-atom?:true -21674 68/push 0x11/imm32/alloc-id:fake:payload -21675 89/<- %edx 4/r32/esp -21676 $test-shift-mem-by-literal:initialize-literal: -21677 # var l/edx: (payload var) -21678 68/push 0/imm32/register -21679 68/push 0/imm32/register -21680 68/push 0/imm32/no-stack-offset -21681 68/push 1/imm32/block-depth -21682 52/push-edx -21683 68/push 0x11/imm32/alloc-id:fake -21684 68/push 0/imm32/name -21685 68/push 0/imm32/name -21686 68/push 0x11/imm32/alloc-id:fake:payload -21687 89/<- %edx 4/r32/esp -21688 $test-shift-mem-by-literal:initialize-literal-value: -21689 # l->name = "3" -21690 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 -21691 (copy-array Heap "3" %eax) -21692 $test-shift-mem-by-literal:initialize-inouts: -21693 # var inouts/esi: (payload stmt-var) = [l] -21694 68/push 0/imm32/is-deref:false -21695 68/push 0/imm32/next -21696 68/push 0/imm32/next -21697 52/push-edx/l -21698 68/push 0x11/imm32/alloc-id:fake -21699 68/push 0x11/imm32/alloc-id:fake:payload -21700 89/<- %esi 4/r32/esp -21701 # var inouts = (handle stmt-var) = [var1, var2] -21702 68/push 0/imm32/is-deref:false -21703 56/push-esi/next -21704 68/push 0x11/imm32/alloc-id:fake -21705 51/push-ecx/var1 -21706 68/push 0x11/imm32/alloc-id:fake -21707 68/push 0x11/imm32/alloc-id:fake:payload -21708 89/<- %esi 4/r32/esp -21709 $test-shift-mem-by-literal:initialize-stmt: -21710 # var stmt/esi: (addr statement) -21711 68/push 0/imm32/next -21712 68/push 0/imm32/next -21713 68/push 0/imm32/outputs -21714 68/push 0/imm32/outputs -21715 56/push-esi/inouts -21716 68/push 0x11/imm32/alloc-id:fake -21717 68/push 0/imm32/operation -21718 68/push 0/imm32/operation -21719 68/push 1/imm32/tag:stmt1 -21720 89/<- %esi 4/r32/esp -21721 $test-shift-mem-by-literal:initialize-stmt-operation: -21722 # stmt->operation = "shift-left" -21723 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -21724 (copy-array Heap "shift-left" %eax) -21725 # convert -21726 c7 0/subop/copy *Curr-block-depth 0/imm32 -21727 (emit-subx-stmt _test-output-buffered-file %esi Primitives Stderr 0) -21728 (flush _test-output-buffered-file) -21729 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -21735 # check output -21736 (check-next-stream-line-equal _test-output-stream "c1/shift 4/subop/left *(ebp+0x00000008) 3/imm8" "F - test-shift-mem-by-literal") -21737 # . epilogue -21738 89/<- %esp 5/r32/ebp -21739 5d/pop-to-ebp -21740 c3/return -21741 -21742 test-compare-reg-with-reg: -21743 # compare var1/ecx, var2/eax -21744 # => -21745 # 39/compare %ecx 0/r32/eax -21746 # -21747 # . prologue -21748 55/push-ebp -21749 89/<- %ebp 4/r32/esp -21750 # setup -21751 (clear-stream _test-output-stream) -21752 (clear-stream $_test-output-buffered-file->buffer) -21753 $test-compare-reg-with-reg:initialize-type: -21754 # var type/ecx: (payload type-tree) = int -21755 68/push 0/imm32/right:null -21756 68/push 0/imm32/right:null -21757 68/push 0/imm32/left:unused -21758 68/push 1/imm32/value:int -21759 68/push 1/imm32/is-atom?:true -21760 68/push 0x11/imm32/alloc-id:fake:payload -21761 89/<- %ecx 4/r32/esp -21762 $test-compare-reg-with-reg:initialize-var1: -21763 # var var1/ecx: (payload var) -21764 68/push 0/imm32/register -21765 68/push 0/imm32/register -21766 68/push 0/imm32/no-stack-offset -21767 68/push 1/imm32/block-depth -21768 51/push-ecx -21769 68/push 0x11/imm32/alloc-id:fake -21770 68/push 0/imm32/name -21771 68/push 0/imm32/name -21772 68/push 0x11/imm32/alloc-id:fake:payload -21773 89/<- %ecx 4/r32/esp -21774 $test-compare-reg-with-reg:initialize-var1-name: -21775 # var1->name = "var1" -21776 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -21777 (copy-array Heap "var1" %eax) -21778 $test-compare-reg-with-reg:initialize-var1-register: -21779 # var1->register = "ecx" -21780 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 -21781 (copy-array Heap "ecx" %eax) -21782 $test-compare-reg-with-reg:initialize-var2: -21783 # var var2/edx: (payload var) -21784 68/push 0/imm32/register -21785 68/push 0/imm32/register -21786 68/push 0/imm32/no-stack-offset -21787 68/push 1/imm32/block-depth -21788 ff 6/subop/push *(ecx+0x10) -21789 68/push 0x11/imm32/alloc-id:fake -21790 68/push 0/imm32/name -21791 68/push 0/imm32/name -21792 68/push 0x11/imm32/alloc-id:fake:payload -21793 89/<- %edx 4/r32/esp -21794 $test-compare-reg-with-reg:initialize-var2-name: -21795 # var2->name = "var2" -21796 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 -21797 (copy-array Heap "var2" %eax) -21798 $test-compare-reg-with-reg:initialize-var2-register: -21799 # var2->register = "eax" -21800 8d/copy-address *(edx+0x1c) 0/r32/eax # Var-register + 4 -21801 (copy-array Heap "eax" %eax) -21802 $test-compare-reg-with-reg:initialize-inouts: -21803 # var inouts/esi: (payload stmt-var) = [var2] -21804 68/push 0/imm32/is-deref:false -21805 68/push 0/imm32/next -21806 68/push 0/imm32/next -21807 52/push-edx/var2 -21808 68/push 0x11/imm32/alloc-id:fake -21809 68/push 0x11/imm32/alloc-id:fake:payload -21810 89/<- %esi 4/r32/esp -21811 # inouts = [var1, var2] -21812 68/push 0/imm32/is-deref:false -21813 56/push-esi/next -21814 68/push 0x11/imm32/alloc-id:fake -21815 51/push-ecx/var1 -21816 68/push 0x11/imm32/alloc-id:fake -21817 68/push 0x11/imm32/alloc-id:fake:payload -21818 89/<- %esi 4/r32/esp -21819 $test-compare-reg-with-reg:initialize-stmt: -21820 # var stmt/esi: (addr statement) +21660 68/push 0x11/imm32/alloc-id:fake:payload +21661 89/<- %ebx 4/r32/esp +21662 $test-emit-subx-stmt-primitive-register:initialize-formal-var-name: +21663 # formal-var->name = "dummy" +21664 8d/copy-address *(ebx+4) 0/r32/eax # Var-name + 4 +21665 (copy-array Heap "dummy" %eax) +21666 $test-emit-subx-stmt-primitive-register:initialize-formal-register: +21667 # formal-var->register = "*" +21668 8d/copy-address *(ebx+0x1c) 0/r32/eax # Var-register + 4 +21669 (copy-array Heap "*" %eax) # Any-register +21670 $test-emit-subx-stmt-primitive-register:initialize-var-list: +21671 # var formal-outputs/ebx: (payload list var) +21672 68/push 0/imm32/next +21673 68/push 0/imm32/next +21674 53/push-ebx/formal-var +21675 68/push 0x11/imm32/alloc-id:fake +21676 68/push 0x11/imm32/alloc-id:fake:payload +21677 89/<- %ebx 4/r32/esp +21678 $test-emit-subx-stmt-primitive-register:initialize-primitive: +21679 # var primitives/ebx: (addr primitive) +21680 68/push 0/imm32/next +21681 68/push 0/imm32/next +21682 68/push 0/imm32/output-is-write-only +21683 68/push 0/imm32/no-disp32 +21684 68/push 0/imm32/no-imm8 +21685 68/push 0/imm32/no-imm32 +21686 68/push 0/imm32/no-r32 +21687 68/push 3/imm32/rm32-is-first-output +21688 68/push 0/imm32/subx-name +21689 68/push 0/imm32/subx-name +21690 53/push-ebx/outputs +21691 68/push 0x11/imm32/alloc-id:fake +21692 68/push 0/imm32/no-inouts +21693 68/push 0/imm32/no-inouts +21694 68/push 0/imm32/name +21695 68/push 0/imm32/name +21696 89/<- %ebx 4/r32/esp +21697 $test-emit-subx-stmt-primitive-register:initialize-primitive-name: +21698 # primitives->name = "increment" +21699 (copy-array Heap "increment" %ebx) # Primitive-name +21700 $test-emit-subx-stmt-primitive-register:initialize-primitive-subx-name: +21701 # primitives->subx-name = "ff 0/subop/increment" +21702 8d/copy-address *(ebx+0x18) 0/r32/eax # Primitive-subx-name +21703 (copy-array Heap "ff 0/subop/increment" %eax) +21704 # convert +21705 c7 0/subop/copy *Curr-block-depth 0/imm32 +21706 (emit-subx-stmt _test-output-buffered-file %esi %ebx Stderr 0) +21707 (flush _test-output-buffered-file) +21708 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +21714 # check output +21715 (check-next-stream-line-equal _test-output-stream "ff 0/subop/increment %eax" "F - test-emit-subx-stmt-primitive-register") +21716 # . epilogue +21717 89/<- %esp 5/r32/ebp +21718 5d/pop-to-ebp +21719 c3/return +21720 +21721 test-emit-subx-stmt-select-primitive: +21722 # Select the right primitive between overloads. +21723 # foo <- increment +21724 # => +21725 # ff 0/subop/increment %eax # sub-optimal, but should suffice +21726 # +21727 # There's a variable on the var stack as follows: +21728 # name: 'foo' +21729 # type: int +21730 # register: 'eax' +21731 # +21732 # There's two primitives, as follows: +21733 # - name: 'increment' +21734 # out: int/reg +21735 # value: 'ff 0/subop/increment' +21736 # - name: 'increment' +21737 # inout: int/mem +21738 # value: 'ff 0/subop/increment' +21739 # +21740 # . prologue +21741 55/push-ebp +21742 89/<- %ebp 4/r32/esp +21743 # setup +21744 (clear-stream _test-output-stream) +21745 (clear-stream $_test-output-buffered-file->buffer) +21746 $test-emit-subx-stmt-select-primitive:initialize-type: +21747 # var type/ecx: (payload type-tree) = int +21748 68/push 0/imm32/right:null +21749 68/push 0/imm32/right:null +21750 68/push 0/imm32/left:unused +21751 68/push 1/imm32/value:int +21752 68/push 1/imm32/is-atom?:true +21753 68/push 0x11/imm32/alloc-id:fake:payload +21754 89/<- %ecx 4/r32/esp +21755 $test-emit-subx-stmt-select-primitive:initialize-var: +21756 # var var-foo/ecx: (payload var) +21757 68/push 0/imm32/register +21758 68/push 0/imm32/register +21759 68/push 0/imm32/no-stack-offset +21760 68/push 1/imm32/block-depth +21761 51/push-ecx +21762 68/push 0x11/imm32/alloc-id:fake +21763 68/push 0/imm32/name +21764 68/push 0/imm32/name +21765 68/push 0x11/imm32/alloc-id:fake:payload +21766 89/<- %ecx 4/r32/esp +21767 $test-emit-subx-stmt-select-primitive:initialize-var-name: +21768 # var-foo->name = "foo" +21769 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +21770 (copy-array Heap "foo" %eax) +21771 $test-emit-subx-stmt-select-primitive:initialize-var-register: +21772 # var-foo->register = "eax" +21773 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 +21774 (copy-array Heap "eax" %eax) +21775 $test-emit-subx-stmt-select-primitive:initialize-stmt-var: +21776 # var operand/ebx: (payload stmt-var) +21777 68/push 0/imm32/is-deref:false +21778 68/push 0/imm32/next +21779 68/push 0/imm32/next +21780 51/push-ecx/var-foo +21781 68/push 0x11/imm32/alloc-id:fake +21782 68/push 0x11/imm32/alloc-id:fake:payload +21783 89/<- %ebx 4/r32/esp +21784 $test-emit-subx-stmt-select-primitive:initialize-stmt: +21785 # var stmt/esi: (addr statement) +21786 53/push-ebx/outputs +21787 68/push 0x11/imm32/alloc-id:fake +21788 68/push 0/imm32/no-inouts +21789 68/push 0/imm32/no-inouts +21790 68/push 0/imm32/operation +21791 68/push 0/imm32/operation +21792 68/push 1/imm32 +21793 89/<- %esi 4/r32/esp +21794 $test-emit-subx-stmt-select-primitive:initialize-stmt-operation: +21795 # stmt->operation = "increment" +21796 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +21797 (copy-array Heap "increment" %eax) +21798 $test-emit-subx-stmt-select-primitive:initialize-formal-var: +21799 # var formal-var/ebx: (payload var) +21800 68/push 0/imm32/register +21801 68/push 0/imm32/register +21802 68/push 0/imm32/no-stack-offset +21803 68/push 1/imm32/block-depth +21804 ff 6/subop/push *(ecx+0x10) # Var-type + payload alloc id + handle alloc id +21805 68/push 0x11/imm32/alloc-id:fake +21806 68/push 0/imm32/name +21807 68/push 0/imm32/name +21808 68/push 0x11/imm32/alloc-id:fake:payload +21809 89/<- %ebx 4/r32/esp +21810 $test-emit-subx-stmt-select-primitive:initialize-formal-var-name: +21811 # formal-var->name = "dummy" +21812 8d/copy-address *(ebx+4) 0/r32/eax # Var-name + 4 +21813 (copy-array Heap "dummy" %eax) +21814 $test-emit-subx-stmt-select-primitive:initialize-formal-register: +21815 # formal-var->register = "*" +21816 8d/copy-address *(ebx+0x1c) 0/r32/eax # Var-register + 4 +21817 (copy-array Heap "*" %eax) # Any-register +21818 $test-emit-subx-stmt-select-primitive:initialize-var-list: +21819 # var formal-outputs/ebx: (payload list var) +21820 68/push 0/imm32/next 21821 68/push 0/imm32/next -21822 68/push 0/imm32/next -21823 68/push 0/imm32/outputs -21824 68/push 0/imm32/outputs -21825 56/push-esi/inouts -21826 68/push 0x11/imm32/alloc-id:fake -21827 68/push 0/imm32/operation -21828 68/push 0/imm32/operation -21829 68/push 1/imm32/tag:stmt1 -21830 89/<- %esi 4/r32/esp -21831 $test-compare-reg-with-reg:initialize-stmt-operation: -21832 # stmt->operation = "compare" -21833 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -21834 (copy-array Heap "compare" %eax) -21835 # convert -21836 c7 0/subop/copy *Curr-block-depth 0/imm32 -21837 (emit-subx-stmt _test-output-buffered-file %esi Primitives Stderr 0) -21838 (flush _test-output-buffered-file) -21839 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -21845 # check output -21846 (check-next-stream-line-equal _test-output-stream "39/compare-> %ecx 0x00000000/r32" "F - test-compare-reg-with-reg") -21847 # . epilogue -21848 89/<- %esp 5/r32/ebp -21849 5d/pop-to-ebp -21850 c3/return -21851 -21852 test-compare-mem-with-reg: -21853 # compare var1, var2/eax -21854 # => -21855 # 39/compare *(ebp+___) 0/r32/eax -21856 # -21857 # . prologue -21858 55/push-ebp -21859 89/<- %ebp 4/r32/esp -21860 # setup -21861 (clear-stream _test-output-stream) -21862 (clear-stream $_test-output-buffered-file->buffer) -21863 $test-compare-mem-with-reg:initialize-type: -21864 # var type/ecx: (payload type-tree) = int -21865 68/push 0/imm32/right:null -21866 68/push 0/imm32/right:null -21867 68/push 0/imm32/left:unused -21868 68/push 1/imm32/value:int -21869 68/push 1/imm32/is-atom?:true -21870 68/push 0x11/imm32/alloc-id:fake:payload -21871 89/<- %ecx 4/r32/esp -21872 $test-compare-mem-with-reg:initialize-var1: -21873 # var var1/ecx: (payload var) -21874 68/push 0/imm32/register -21875 68/push 0/imm32/register -21876 68/push 8/imm32/stack-offset -21877 68/push 1/imm32/block-depth -21878 51/push-ecx -21879 68/push 0x11/imm32/alloc-id:fake -21880 68/push 0/imm32/name -21881 68/push 0/imm32/name -21882 68/push 0x11/imm32/alloc-id:fake:payload -21883 89/<- %ecx 4/r32/esp -21884 $test-compare-mem-with-reg:initialize-var1-name: -21885 # var1->name = "var1" -21886 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -21887 (copy-array Heap "var1" %eax) -21888 $test-compare-mem-with-reg:initialize-var2: -21889 # var var2/edx: (payload var) -21890 68/push 0/imm32/register -21891 68/push 0/imm32/register -21892 68/push 0/imm32/no-stack-offset -21893 68/push 1/imm32/block-depth -21894 ff 6/subop/push *(ecx+0x10) -21895 68/push 0x11/imm32/alloc-id:fake -21896 68/push 0/imm32/name -21897 68/push 0/imm32/name -21898 68/push 0x11/imm32/alloc-id:fake:payload -21899 89/<- %edx 4/r32/esp -21900 $test-compare-mem-with-reg:initialize-var2-name: -21901 # var2->name = "var2" -21902 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 -21903 (copy-array Heap "var2" %eax) -21904 $test-compare-mem-with-reg:initialize-var2-register: -21905 # var2->register = "eax" -21906 8d/copy-address *(edx+0x1c) 0/r32/eax # Var-register + 4 -21907 (copy-array Heap "eax" %eax) -21908 $test-compare-mem-with-reg:initialize-inouts: -21909 # var inouts/esi: (payload stmt-var) = [var2] -21910 68/push 0/imm32/is-deref:false -21911 68/push 0/imm32/next -21912 68/push 0/imm32/next -21913 52/push-edx/var2 -21914 68/push 0x11/imm32/alloc-id:fake -21915 68/push 0x11/imm32/alloc-id:fake:payload -21916 89/<- %esi 4/r32/esp -21917 # inouts = [var1, var2] -21918 68/push 0/imm32/is-deref:false -21919 56/push-esi/next -21920 68/push 0x11/imm32/alloc-id:fake -21921 51/push-ecx/var1 -21922 68/push 0x11/imm32/alloc-id:fake -21923 68/push 0x11/imm32/alloc-id:fake:payload -21924 89/<- %esi 4/r32/esp -21925 $test-compare-mem-with-reg:initialize-stmt: -21926 # var stmt/esi: (addr statement) -21927 68/push 0/imm32/next -21928 68/push 0/imm32/next -21929 68/push 0/imm32/outputs -21930 68/push 0/imm32/outputs -21931 56/push-esi/inouts -21932 68/push 0x11/imm32/alloc-id:fake -21933 68/push 0/imm32/operation -21934 68/push 0/imm32/operation -21935 68/push 1/imm32/tag:stmt1 -21936 89/<- %esi 4/r32/esp -21937 $test-compare-mem-with-reg:initialize-stmt-operation: -21938 # stmt->operation = "compare" -21939 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -21940 (copy-array Heap "compare" %eax) -21941 # convert -21942 c7 0/subop/copy *Curr-block-depth 0/imm32 -21943 (emit-subx-stmt _test-output-buffered-file %esi Primitives Stderr 0) -21944 (flush _test-output-buffered-file) -21945 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -21951 # check output -21952 (check-next-stream-line-equal _test-output-stream "39/compare-> *(ebp+0x00000008) 0x00000000/r32" "F - test-compare-mem-with-reg") -21953 # . epilogue -21954 89/<- %esp 5/r32/ebp -21955 5d/pop-to-ebp -21956 c3/return -21957 -21958 test-compare-reg-with-mem: -21959 # compare var1/eax, var2 -21960 # => -21961 # 3b/compare<- *(ebp+___) 0/r32/eax -21962 # -21963 # . prologue -21964 55/push-ebp -21965 89/<- %ebp 4/r32/esp -21966 # setup -21967 (clear-stream _test-output-stream) -21968 (clear-stream $_test-output-buffered-file->buffer) -21969 $test-compare-reg-with-mem:initialize-type: -21970 # var type/ecx: (payload type-tree) = int -21971 68/push 0/imm32/right:null -21972 68/push 0/imm32/right:null -21973 68/push 0/imm32/left:unused -21974 68/push 1/imm32/value:int -21975 68/push 1/imm32/is-atom?:true -21976 68/push 0x11/imm32/alloc-id:fake:payload -21977 89/<- %ecx 4/r32/esp -21978 $test-compare-reg-with-mem:initialize-var1: -21979 # var var1/ecx: (payload var) -21980 68/push 0/imm32/register -21981 68/push 0/imm32/register -21982 68/push 0/imm32/no-stack-offset -21983 68/push 1/imm32/block-depth -21984 51/push-ecx -21985 68/push 0x11/imm32/alloc-id:fake -21986 68/push 0/imm32/name -21987 68/push 0/imm32/name -21988 68/push 0x11/imm32/alloc-id:fake:payload -21989 89/<- %ecx 4/r32/esp -21990 $test-compare-reg-with-mem:initialize-var1-name: -21991 # var1->name = "var1" -21992 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -21993 (copy-array Heap "var1" %eax) -21994 $test-compare-reg-with-mem:initialize-var1-register: -21995 # var1->register = "eax" -21996 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 -21997 (copy-array Heap "eax" %eax) -21998 $test-compare-reg-with-mem:initialize-var2: -21999 # var var2/edx: (payload var) -22000 68/push 0/imm32/register -22001 68/push 0/imm32/register -22002 68/push 8/imm32/stack-offset -22003 68/push 1/imm32/block-depth -22004 ff 6/subop/push *(ecx+0x10) -22005 68/push 0x11/imm32/alloc-id:fake -22006 68/push 0/imm32/name -22007 68/push 0/imm32/name -22008 68/push 0x11/imm32/alloc-id:fake:payload -22009 89/<- %edx 4/r32/esp -22010 $test-compare-reg-with-mem:initialize-var2-name: -22011 # var2->name = "var2" -22012 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 -22013 (copy-array Heap "var2" %eax) -22014 $test-compare-reg-with-mem:initialize-inouts: -22015 # var inouts/esi: (payload stmt-var) = [var2] -22016 68/push 0/imm32/is-deref:false -22017 68/push 0/imm32/next -22018 68/push 0/imm32/next -22019 52/push-edx/var2 -22020 68/push 0x11/imm32/alloc-id:fake -22021 68/push 0x11/imm32/alloc-id:fake:payload -22022 89/<- %esi 4/r32/esp -22023 # inouts = [var1, var2] -22024 68/push 0/imm32/is-deref:false -22025 56/push-esi/next -22026 68/push 0x11/imm32/alloc-id:fake -22027 51/push-ecx/var1 -22028 68/push 0x11/imm32/alloc-id:fake -22029 68/push 0x11/imm32/alloc-id:fake:payload -22030 89/<- %esi 4/r32/esp -22031 $test-compare-reg-with-mem:initialize-stmt: -22032 # var stmt/esi: (addr statement) -22033 68/push 0/imm32/next -22034 68/push 0/imm32/next -22035 68/push 0/imm32/outputs -22036 68/push 0/imm32/outputs -22037 56/push-esi/inouts -22038 68/push 0x11/imm32/alloc-id:fake -22039 68/push 0/imm32/operation -22040 68/push 0/imm32/operation -22041 68/push 1/imm32/tag:stmt1 -22042 89/<- %esi 4/r32/esp -22043 $test-compare-reg-with-mem:initialize-stmt-operation: -22044 # stmt->operation = "compare" -22045 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -22046 (copy-array Heap "compare" %eax) -22047 # convert -22048 c7 0/subop/copy *Curr-block-depth 0/imm32 -22049 (emit-subx-stmt _test-output-buffered-file %esi Primitives Stderr 0) -22050 (flush _test-output-buffered-file) -22051 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -22057 # check output -22058 (check-next-stream-line-equal _test-output-stream "3b/compare<- *(ebp+0x00000008) 0x00000000/r32" "F - test-compare-reg-with-mem") -22059 # . epilogue -22060 89/<- %esp 5/r32/ebp -22061 5d/pop-to-ebp -22062 c3/return -22063 -22064 test-compare-mem-with-literal: -22065 # compare var1, 0x34 -22066 # => -22067 # 81 7/subop/compare *(ebp+___) 0x34/imm32 -22068 # -22069 # . prologue -22070 55/push-ebp -22071 89/<- %ebp 4/r32/esp -22072 # setup -22073 (clear-stream _test-output-stream) -22074 (clear-stream $_test-output-buffered-file->buffer) -22075 $test-compare-mem-with-literal:initialize-type: -22076 # var type/ecx: (payload type-tree) = int -22077 68/push 0/imm32/right:null -22078 68/push 0/imm32/right:null -22079 68/push 0/imm32/left:unused -22080 68/push 1/imm32/value:int -22081 68/push 1/imm32/is-atom?:true -22082 68/push 0x11/imm32/alloc-id:fake:payload -22083 89/<- %ecx 4/r32/esp -22084 $test-compare-mem-with-literal:initialize-var1: -22085 # var var1/ecx: (payload var) -22086 68/push 0/imm32/register -22087 68/push 0/imm32/register -22088 68/push 8/imm32/stack-offset -22089 68/push 1/imm32/block-depth -22090 51/push-ecx -22091 68/push 0x11/imm32/alloc-id:fake -22092 68/push 0/imm32/name -22093 68/push 0/imm32/name -22094 68/push 0x11/imm32/alloc-id:fake:payload -22095 89/<- %ecx 4/r32/esp -22096 $test-compare-mem-with-literal:initialize-var1-name: -22097 # var1->name = "var1" -22098 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -22099 (copy-array Heap "var1" %eax) -22100 $test-compare-mem-with-literal:initialize-literal-type: -22101 # var type/edx: (payload type-tree) = literal -22102 68/push 0/imm32/right:null -22103 68/push 0/imm32/right:null -22104 68/push 0/imm32/left:unused -22105 68/push 0/imm32/value:literal -22106 68/push 1/imm32/is-atom?:true -22107 68/push 0x11/imm32/alloc-id:fake:payload -22108 89/<- %edx 4/r32/esp -22109 $test-compare-mem-with-literal:initialize-literal: -22110 # var l/edx: (payload var) -22111 68/push 0/imm32/register -22112 68/push 0/imm32/register -22113 68/push 0/imm32/no-stack-offset -22114 68/push 1/imm32/block-depth -22115 52/push-edx -22116 68/push 0x11/imm32/alloc-id:fake -22117 68/push 0/imm32/name -22118 68/push 0/imm32/name -22119 68/push 0x11/imm32/alloc-id:fake:payload -22120 89/<- %edx 4/r32/esp -22121 $test-compare-mem-with-literal:initialize-literal-value: -22122 # l->name = "0x34" -22123 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 -22124 (copy-array Heap "0x34" %eax) -22125 $test-compare-mem-with-literal:initialize-inouts: -22126 # var inouts/esi: (payload stmt-var) = [l] -22127 68/push 0/imm32/is-deref:false -22128 68/push 0/imm32/next -22129 68/push 0/imm32/next -22130 52/push-edx/l -22131 68/push 0x11/imm32/alloc-id:fake -22132 68/push 0x11/imm32/alloc-id:fake:payload -22133 89/<- %esi 4/r32/esp -22134 # var inouts = (handle stmt-var) = [var1, var2] -22135 68/push 0/imm32/is-deref:false -22136 56/push-esi/next -22137 68/push 0x11/imm32/alloc-id:fake -22138 51/push-ecx/var1 -22139 68/push 0x11/imm32/alloc-id:fake -22140 68/push 0x11/imm32/alloc-id:fake:payload -22141 89/<- %esi 4/r32/esp -22142 $test-compare-mem-with-literal:initialize-stmt: -22143 # var stmt/esi: (addr statement) -22144 68/push 0/imm32/next -22145 68/push 0/imm32/next -22146 68/push 0/imm32/outputs -22147 68/push 0/imm32/outputs -22148 56/push-esi/inouts -22149 68/push 0x11/imm32/alloc-id:fake -22150 68/push 0/imm32/operation -22151 68/push 0/imm32/operation -22152 68/push 1/imm32/tag:stmt1 -22153 89/<- %esi 4/r32/esp -22154 $test-compare-mem-with-literal:initialize-stmt-operation: -22155 # stmt->operation = "compare" -22156 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -22157 (copy-array Heap "compare" %eax) -22158 # convert -22159 c7 0/subop/copy *Curr-block-depth 0/imm32 -22160 (emit-subx-stmt _test-output-buffered-file %esi Primitives Stderr 0) -22161 (flush _test-output-buffered-file) -22162 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -22168 # check output -22169 (check-next-stream-line-equal _test-output-stream "81 7/subop/compare *(ebp+0x00000008) 0x34/imm32" "F - test-compare-mem-with-literal") -22170 # . epilogue -22171 89/<- %esp 5/r32/ebp -22172 5d/pop-to-ebp -22173 c3/return -22174 -22175 test-compare-eax-with-literal: -22176 # compare var1/eax 0x34 -22177 # => -22178 # 3d/compare-eax-with 0x34/imm32 -22179 # -22180 # . prologue -22181 55/push-ebp -22182 89/<- %ebp 4/r32/esp -22183 # setup -22184 (clear-stream _test-output-stream) -22185 (clear-stream $_test-output-buffered-file->buffer) -22186 $test-compare-eax-with-literal:initialize-type: -22187 # var type/ecx: (payload type-tree) = int -22188 68/push 0/imm32/right:null -22189 68/push 0/imm32/right:null -22190 68/push 0/imm32/left:unused -22191 68/push 1/imm32/value:int -22192 68/push 1/imm32/is-atom?:true -22193 68/push 0x11/imm32/alloc-id:fake:payload -22194 89/<- %ecx 4/r32/esp -22195 $test-compare-eax-with-literal:initialize-var1: -22196 # var var1/ecx: (payload var) -22197 68/push 0/imm32/register -22198 68/push 0/imm32/register -22199 68/push 0/imm32/no-stack-offset -22200 68/push 1/imm32/block-depth -22201 51/push-ecx -22202 68/push 0x11/imm32/alloc-id:fake -22203 68/push 0/imm32/name -22204 68/push 0/imm32/name -22205 68/push 0x11/imm32/alloc-id:fake:payload -22206 89/<- %ecx 4/r32/esp -22207 $test-compare-eax-with-literal:initialize-var1-name: -22208 # var1->name = "var1" -22209 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -22210 (copy-array Heap "var1" %eax) -22211 $test-compare-eax-with-literal:initialize-var1-register: -22212 # v->register = "eax" -22213 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 -22214 (copy-array Heap "eax" %eax) -22215 $test-compare-eax-with-literal:initialize-literal-type: -22216 # var type/edx: (payload type-tree) = literal -22217 68/push 0/imm32/right:null -22218 68/push 0/imm32/right:null -22219 68/push 0/imm32/left:unused -22220 68/push 0/imm32/value:literal -22221 68/push 1/imm32/is-atom?:true -22222 68/push 0x11/imm32/alloc-id:fake:payload -22223 89/<- %edx 4/r32/esp -22224 $test-compare-eax-with-literal:initialize-literal: -22225 # var l/edx: (payload var) -22226 68/push 0/imm32/register -22227 68/push 0/imm32/register -22228 68/push 0/imm32/no-stack-offset -22229 68/push 1/imm32/block-depth -22230 52/push-edx -22231 68/push 0x11/imm32/alloc-id:fake -22232 68/push 0/imm32/name -22233 68/push 0/imm32/name -22234 68/push 0x11/imm32/alloc-id:fake:payload -22235 89/<- %edx 4/r32/esp -22236 $test-compare-eax-with-literal:initialize-literal-value: -22237 # l->name = "0x34" -22238 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 -22239 (copy-array Heap "0x34" %eax) -22240 $test-compare-eax-with-literal:initialize-inouts: -22241 # var inouts/esi: (payload stmt-var) = [l] -22242 68/push 0/imm32/is-deref:false -22243 68/push 0/imm32/next -22244 68/push 0/imm32/next -22245 52/push-edx/l +21822 53/push-ebx/formal-var +21823 68/push 0x11/imm32/alloc-id:fake +21824 68/push 0x11/imm32/alloc-id:fake:payload +21825 89/<- %ebx 4/r32/esp +21826 $test-emit-subx-stmt-select-primitive:initialize-primitive2: +21827 # var primitive2/edi: (payload primitive) +21828 68/push 0/imm32/next +21829 68/push 0/imm32/next +21830 68/push 0/imm32/output-is-write-only +21831 68/push 0/imm32/no-disp32 +21832 68/push 0/imm32/no-imm8 +21833 68/push 0/imm32/no-imm32 +21834 68/push 0/imm32/no-r32 +21835 68/push 3/imm32/rm32-is-first-output +21836 68/push 0/imm32/subx-name +21837 68/push 0/imm32/subx-name +21838 53/push-ebx/outputs +21839 68/push 0x11/imm32/alloc-id:fake +21840 68/push 0/imm32/no-inouts +21841 68/push 0/imm32/no-inouts +21842 68/push 0/imm32/name +21843 68/push 0/imm32/name +21844 68/push 0x11/imm32/alloc-id:fake:payload +21845 89/<- %edi 4/r32/esp +21846 $test-emit-subx-stmt-select-primitive:initialize-primitive2-name: +21847 # primitives->name = "increment" +21848 8d/copy-address *(edi+4) 0/r32/eax # Primitive-name + 4 +21849 (copy-array Heap "increment" %eax) +21850 $test-emit-subx-stmt-select-primitive:initialize-primitive2-subx-name: +21851 # primitives->subx-name = "ff 0/subop/increment" +21852 8d/copy-address *(edi+0x1c) 0/r32/eax # Primitive-subx-name + 4 +21853 (copy-array Heap "ff 0/subop/increment" %eax) +21854 $test-emit-subx-stmt-select-primitive:initialize-primitive: +21855 # var primitives/ebx: (addr primitive) +21856 57/push-edi +21857 68/push 0x11/imm32/alloc-id:fake +21858 68/push 0/imm32/output-is-write-only +21859 68/push 0/imm32/no-disp32 +21860 68/push 0/imm32/no-imm8 +21861 68/push 0/imm32/no-imm32 +21862 68/push 0/imm32/no-r32 +21863 68/push 1/imm32/rm32-is-first-inout +21864 68/push 0/imm32/subx-name +21865 68/push 0/imm32/subx-name +21866 68/push 0/imm32/no-outputs +21867 68/push 0/imm32/no-outputs +21868 53/push-ebx/inouts # hack: reuse stmt-var from call stmt as (list var) in function declaration +21869 68/push 0x11/imm32/alloc-id:fake +21870 68/push 0/imm32/name +21871 68/push 0/imm32/name +21872 89/<- %ebx 4/r32/esp +21873 $test-emit-subx-stmt-select-primitive:initialize-primitive-name: +21874 # primitives->name = "increment" +21875 (copy-array Heap "increment" %ebx) # Primitive-name +21876 $test-emit-subx-stmt-select-primitive:initialize-primitive-subx-name: +21877 # primitives->subx-name = "ff 0/subop/increment" +21878 8d/copy-address *(ebx+0x18) 0/r32/eax # Primitive-subx-name +21879 (copy-array Heap "ff 0/subop/increment" %eax) +21880 # convert +21881 c7 0/subop/copy *Curr-block-depth 0/imm32 +21882 (emit-subx-stmt _test-output-buffered-file %esi %ebx Stderr 0) +21883 (flush _test-output-buffered-file) +21884 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +21890 # check output +21891 (check-next-stream-line-equal _test-output-stream "ff 0/subop/increment %eax" "F - test-emit-subx-stmt-select-primitive") +21892 # . epilogue +21893 89/<- %esp 5/r32/ebp +21894 5d/pop-to-ebp +21895 c3/return +21896 +21897 test-emit-subx-stmt-select-primitive-2: +21898 # Select the right primitive between overloads. +21899 # increment foo +21900 # => +21901 # ff 0/subop/increment %eax # sub-optimal, but should suffice +21902 # +21903 # There's a variable on the var stack as follows: +21904 # name: 'foo' +21905 # type: int +21906 # register: 'eax' +21907 # +21908 # There's two primitives, as follows: +21909 # - name: 'increment' +21910 # out: int/reg +21911 # value: 'ff 0/subop/increment' +21912 # - name: 'increment' +21913 # inout: int/mem +21914 # value: 'ff 0/subop/increment' +21915 # +21916 # . prologue +21917 55/push-ebp +21918 89/<- %ebp 4/r32/esp +21919 # setup +21920 (clear-stream _test-output-stream) +21921 (clear-stream $_test-output-buffered-file->buffer) +21922 $test-emit-subx-stmt-select-primitive-2:initialize-type: +21923 # var type/ecx: (payload type-tree) = int +21924 68/push 0/imm32/right:null +21925 68/push 0/imm32/right:null +21926 68/push 0/imm32/left:unused +21927 68/push 1/imm32/value:int +21928 68/push 1/imm32/is-atom?:true +21929 68/push 0x11/imm32/alloc-id:fake:payload +21930 89/<- %ecx 4/r32/esp +21931 $test-emit-subx-stmt-select-primitive-2:initialize-var: +21932 # var var-foo/ecx: (payload var) +21933 68/push 0/imm32/register +21934 68/push 0/imm32/register +21935 68/push 0/imm32/no-stack-offset +21936 68/push 1/imm32/block-depth +21937 51/push-ecx +21938 68/push 0x11/imm32/alloc-id:fake +21939 68/push 0/imm32/name +21940 68/push 0/imm32/name +21941 68/push 0x11/imm32/alloc-id:fake:payload +21942 89/<- %ecx 4/r32/esp +21943 $test-emit-subx-stmt-select-primitive-2:initialize-var-name: +21944 # var-foo->name = "foo" +21945 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +21946 (copy-array Heap "foo" %eax) +21947 $test-emit-subx-stmt-select-primitive-2:initialize-var-register: +21948 # var-foo->register = "eax" +21949 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 +21950 (copy-array Heap "eax" %eax) +21951 $test-emit-subx-stmt-select-primitive-2:initialize-stmt-var: +21952 # var operand/ebx: (payload stmt-var) +21953 68/push 0/imm32/is-deref:false +21954 68/push 0/imm32/next +21955 68/push 0/imm32/next +21956 51/push-ecx/var-foo +21957 68/push 0x11/imm32/alloc-id:fake +21958 68/push 0x11/imm32/alloc-id:fake:payload +21959 89/<- %ebx 4/r32/esp +21960 $test-emit-subx-stmt-select-primitive-2:initialize-stmt: +21961 # var stmt/esi: (addr statement) +21962 68/push 0/imm32/no-outputs +21963 68/push 0/imm32/no-outputs +21964 53/push-ebx/inouts +21965 68/push 0x11/imm32/alloc-id:fake +21966 68/push 0/imm32/operation +21967 68/push 0/imm32/operation +21968 68/push 1/imm32 +21969 89/<- %esi 4/r32/esp +21970 $test-emit-subx-stmt-select-primitive-2:initialize-stmt-operation: +21971 # stmt->operation = "increment" +21972 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +21973 (copy-array Heap "increment" %eax) +21974 $test-emit-subx-stmt-select-primitive-2:initialize-formal-var: +21975 # var formal-var/ebx: (payload var) +21976 68/push 0/imm32/register +21977 68/push 0/imm32/register +21978 68/push 0/imm32/no-stack-offset +21979 68/push 1/imm32/block-depth +21980 ff 6/subop/push *(ecx+0x10) # Var-type + payload alloc id + handle alloc id +21981 68/push 0x11/imm32/alloc-id:fake +21982 68/push 0/imm32/name +21983 68/push 0/imm32/name +21984 68/push 0x11/imm32/alloc-id:fake:payload +21985 89/<- %ebx 4/r32/esp +21986 $test-emit-subx-stmt-select-primitive-2:initialize-formal-var-name: +21987 # formal-var->name = "dummy" +21988 8d/copy-address *(ebx+4) 0/r32/eax # Var-name + 4 +21989 (copy-array Heap "dummy" %eax) +21990 $test-emit-subx-stmt-select-primitive-2:initialize-formal-register: +21991 # formal-var->register = "*" +21992 8d/copy-address *(ebx+0x1c) 0/r32/eax # Var-register + 4 +21993 (copy-array Heap "*" %eax) # Any-register +21994 $test-emit-subx-stmt-select-primitive-2:initialize-var-list: +21995 # var formal-outputs/ebx: (payload list stmt-var) +21996 68/push 0/imm32/next +21997 68/push 0/imm32/next +21998 53/push-ebx/formal-var +21999 68/push 0x11/imm32/alloc-id:fake +22000 68/push 0x11/imm32/alloc-id:fake:payload +22001 89/<- %ebx 4/r32/esp +22002 $test-emit-subx-stmt-select-primitive-2:initialize-primitive2: +22003 # var primitive2/edi: (payload primitive) +22004 68/push 0/imm32/next +22005 68/push 0/imm32/next +22006 68/push 0/imm32/output-is-write-only +22007 68/push 0/imm32/no-disp32 +22008 68/push 0/imm32/no-imm8 +22009 68/push 0/imm32/no-imm32 +22010 68/push 0/imm32/no-r32 +22011 68/push 3/imm32/rm32-is-first-output +22012 68/push 0/imm32/subx-name +22013 68/push 0/imm32/subx-name +22014 53/push-ebx/outputs +22015 68/push 0x11/imm32/alloc-id:fake +22016 68/push 0/imm32/no-inouts +22017 68/push 0/imm32/no-inouts +22018 68/push 0/imm32/name +22019 68/push 0/imm32/name +22020 68/push 0x11/imm32/alloc-id:fake:payload +22021 89/<- %edi 4/r32/esp +22022 $test-emit-subx-stmt-select-primitive-2:initialize-primitive2-name: +22023 # primitives->name = "increment" +22024 8d/copy-address *(edi+4) 0/r32/eax # Primitive-name + 4 +22025 (copy-array Heap "increment" %eax) +22026 $test-emit-subx-stmt-select-primitive-2:initialize-primitive2-subx-name: +22027 # primitives->subx-name = "ff 0/subop/increment" +22028 8d/copy-address *(edi+0x1c) 0/r32/eax # Primitive-subx-name + 4 +22029 (copy-array Heap "ff 0/subop/increment" %eax) +22030 $test-emit-subx-stmt-select-primitive-2:initialize-primitive: +22031 # var primitives/ebx: (addr primitive) +22032 57/push-edi +22033 68/push 0x11/imm32/alloc-id:fake +22034 68/push 0/imm32/output-is-write-only +22035 68/push 0/imm32/no-disp32 +22036 68/push 0/imm32/no-imm8 +22037 68/push 0/imm32/no-imm32 +22038 68/push 0/imm32/no-r32 +22039 68/push 1/imm32/rm32-is-first-inout +22040 68/push 0/imm32/subx-name +22041 68/push 0/imm32/subx-name +22042 68/push 0/imm32/no-outputs +22043 68/push 0/imm32/no-outputs +22044 53/push-ebx/inouts # hack: reuse stmt-var from call stmt as (list var) in function declaration +22045 68/push 0x11/imm32/alloc-id:fake +22046 68/push 0/imm32/name +22047 68/push 0/imm32/name +22048 89/<- %ebx 4/r32/esp +22049 $test-emit-subx-stmt-select-primitive-2:initialize-primitive-name: +22050 # primitives->name = "increment" +22051 (copy-array Heap "increment" %ebx) # Primitive-name +22052 $test-emit-subx-stmt-select-primitive-2:initialize-primitive-subx-name: +22053 # primitives->subx-name = "ff 0/subop/increment" +22054 8d/copy-address *(ebx+0x18) 0/r32/eax # Primitive-subx-name +22055 (copy-array Heap "ff 0/subop/increment" %eax) +22056 # convert +22057 c7 0/subop/copy *Curr-block-depth 0/imm32 +22058 (emit-subx-stmt _test-output-buffered-file %esi %ebx Stderr 0) +22059 (flush _test-output-buffered-file) +22060 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +22066 # check output +22067 (check-next-stream-line-equal _test-output-stream "ff 0/subop/increment %eax" "F - test-emit-subx-stmt-select-primitive-2") +22068 # . epilogue +22069 89/<- %esp 5/r32/ebp +22070 5d/pop-to-ebp +22071 c3/return +22072 +22073 test-increment-register: +22074 # Select the right register between overloads. +22075 # foo <- increment +22076 # => +22077 # 50/increment-eax +22078 # +22079 # There's a variable on the var stack as follows: +22080 # name: 'foo' +22081 # type: int +22082 # register: 'eax' +22083 # +22084 # Primitives are the global definitions. +22085 # +22086 # . prologue +22087 55/push-ebp +22088 89/<- %ebp 4/r32/esp +22089 # setup +22090 (clear-stream _test-output-stream) +22091 (clear-stream $_test-output-buffered-file->buffer) +22092 $test-increment-register:initialize-type: +22093 # var type/ecx: (payload type-tree) = int +22094 68/push 0/imm32/right:null +22095 68/push 0/imm32/right:null +22096 68/push 0/imm32/left:unused +22097 68/push 1/imm32/value:int +22098 68/push 1/imm32/is-atom?:true +22099 68/push 0x11/imm32/alloc-id:fake:payload +22100 89/<- %ecx 4/r32/esp +22101 $test-increment-register:initialize-var: +22102 # var var-foo/ecx: (payload var) +22103 68/push 0/imm32/register +22104 68/push 0/imm32/register +22105 68/push 0/imm32/no-stack-offset +22106 68/push 1/imm32/block-depth +22107 51/push-ecx +22108 68/push 0x11/imm32/alloc-id:fake +22109 68/push 0/imm32/name +22110 68/push 0/imm32/name +22111 68/push 0x11/imm32/alloc-id:fake:payload +22112 89/<- %ecx 4/r32/esp +22113 $test-increment-register:initialize-var-name: +22114 # var-foo->name = "foo" +22115 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +22116 (copy-array Heap "foo" %eax) +22117 $test-increment-register:initialize-var-register: +22118 # var-foo->register = "eax" +22119 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 +22120 (copy-array Heap "eax" %eax) +22121 $test-increment-register:initialize-stmt-var: +22122 # var operand/ebx: (payload stmt-var) +22123 68/push 0/imm32/is-deref:false +22124 68/push 0/imm32/next +22125 68/push 0/imm32/next +22126 51/push-ecx/var-foo +22127 68/push 0x11/imm32/alloc-id:fake +22128 68/push 0x11/imm32/alloc-id:fake:payload +22129 89/<- %ebx 4/r32/esp +22130 $test-increment-register:initialize-stmt: +22131 # var stmt/esi: (addr statement) +22132 53/push-ebx/outputs +22133 68/push 0x11/imm32/alloc-id:fake +22134 68/push 0/imm32/no-inouts +22135 68/push 0/imm32/no-inouts +22136 68/push 0/imm32/operation +22137 68/push 0/imm32/operation +22138 68/push 1/imm32 +22139 89/<- %esi 4/r32/esp +22140 $test-increment-register:initialize-stmt-operation: +22141 # stmt->operation = "increment" +22142 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +22143 (copy-array Heap "increment" %eax) +22144 # convert +22145 c7 0/subop/copy *Curr-block-depth 0/imm32 +22146 (emit-subx-stmt _test-output-buffered-file %esi Primitives Stderr 0) +22147 (flush _test-output-buffered-file) +22148 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +22154 # check output +22155 (check-next-stream-line-equal _test-output-stream "40/increment-eax" "F - test-increment-register") +22156 # . epilogue +22157 89/<- %esp 5/r32/ebp +22158 5d/pop-to-ebp +22159 c3/return +22160 +22161 test-add-reg-to-reg: +22162 # var1/reg <- add var2/reg +22163 # => +22164 # 01/add-to %var1 var2 +22165 # +22166 # . prologue +22167 55/push-ebp +22168 89/<- %ebp 4/r32/esp +22169 # setup +22170 (clear-stream _test-output-stream) +22171 (clear-stream $_test-output-buffered-file->buffer) +22172 $test-add-reg-to-reg:initialize-type: +22173 # var type/ecx: (payload type-tree) = int +22174 68/push 0/imm32/right:null +22175 68/push 0/imm32/right:null +22176 68/push 0/imm32/left:unused +22177 68/push 1/imm32/value:int +22178 68/push 1/imm32/is-atom?:true +22179 68/push 0x11/imm32/alloc-id:fake:payload +22180 89/<- %ecx 4/r32/esp +22181 $test-add-reg-to-reg:initialize-var1: +22182 # var var1/ecx: (payload var) +22183 68/push 0/imm32/register +22184 68/push 0/imm32/register +22185 68/push 0/imm32/no-stack-offset +22186 68/push 1/imm32/block-depth +22187 51/push-ecx +22188 68/push 0x11/imm32/alloc-id:fake +22189 68/push 0/imm32/name +22190 68/push 0/imm32/name +22191 68/push 0x11/imm32/alloc-id:fake:payload +22192 89/<- %ecx 4/r32/esp +22193 $test-add-reg-to-reg:initialize-var1-name: +22194 # var1->name = "var1" +22195 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +22196 (copy-array Heap "var1" %eax) +22197 $test-add-reg-to-reg:initialize-var1-register: +22198 # var1->register = "eax" +22199 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 +22200 (copy-array Heap "eax" %eax) +22201 $test-add-reg-to-reg:initialize-var2: +22202 # var var2/edx: (payload var) +22203 68/push 0/imm32/register +22204 68/push 0/imm32/register +22205 68/push 0/imm32/no-stack-offset +22206 68/push 1/imm32/block-depth +22207 ff 6/subop/push *(ecx+0x10) +22208 68/push 0x11/imm32/alloc-id:fake +22209 68/push 0/imm32/name +22210 68/push 0/imm32/name +22211 68/push 0x11/imm32/alloc-id:fake:payload +22212 89/<- %edx 4/r32/esp +22213 $test-add-reg-to-reg:initialize-var2-name: +22214 # var2->name = "var2" +22215 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 +22216 (copy-array Heap "var2" %eax) +22217 $test-add-reg-to-reg:initialize-var2-register: +22218 # var2->register = "ecx" +22219 8d/copy-address *(edx+0x1c) 0/r32/eax # Var-register + 4 +22220 (copy-array Heap "ecx" %eax) +22221 $test-add-reg-to-reg:initialize-inouts: +22222 # var inouts/esi: (payload stmt-var) = [var2] +22223 68/push 0/imm32/is-deref:false +22224 68/push 0/imm32/next +22225 68/push 0/imm32/next +22226 52/push-edx/var2 +22227 68/push 0x11/imm32/alloc-id:fake +22228 68/push 0x11/imm32/alloc-id:fake:payload +22229 89/<- %esi 4/r32/esp +22230 $test-add-reg-to-reg:initialize-outputs: +22231 # var outputs/edi: (payload stmt-var) = [var1] +22232 68/push 0/imm32/is-deref:false +22233 68/push 0/imm32/next +22234 68/push 0/imm32/next +22235 51/push-ecx/var1 +22236 68/push 0x11/imm32/alloc-id:fake +22237 68/push 0x11/imm32/alloc-id:fake:payload +22238 89/<- %edi 4/r32/esp +22239 $test-add-reg-to-reg:initialize-stmt: +22240 # var stmt/esi: (addr statement) +22241 68/push 0/imm32/next +22242 68/push 0/imm32/next +22243 57/push-edi/outputs +22244 68/push 0x11/imm32/alloc-id:fake +22245 56/push-esi/inouts 22246 68/push 0x11/imm32/alloc-id:fake -22247 68/push 0x11/imm32/alloc-id:fake:payload -22248 89/<- %esi 4/r32/esp -22249 # var inouts = (handle stmt-var) = [var1, var2] -22250 68/push 0/imm32/is-deref:false -22251 56/push-esi/next -22252 68/push 0x11/imm32/alloc-id:fake -22253 51/push-ecx/var1 -22254 68/push 0x11/imm32/alloc-id:fake -22255 68/push 0x11/imm32/alloc-id:fake:payload -22256 89/<- %esi 4/r32/esp -22257 $test-compare-eax-with-literal:initialize-stmt: -22258 # var stmt/esi: (addr statement) -22259 68/push 0/imm32/next -22260 68/push 0/imm32/next -22261 68/push 0/imm32/outputs -22262 68/push 0/imm32/outputs -22263 56/push-esi/inouts -22264 68/push 0x11/imm32/alloc-id:fake -22265 68/push 0/imm32/operation -22266 68/push 0/imm32/operation -22267 68/push 1/imm32/tag:stmt1 -22268 89/<- %esi 4/r32/esp -22269 $test-compare-eax-with-literal:initialize-stmt-operation: -22270 # stmt->operation = "compare" -22271 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -22272 (copy-array Heap "compare" %eax) -22273 # convert -22274 c7 0/subop/copy *Curr-block-depth 0/imm32 -22275 (emit-subx-stmt _test-output-buffered-file %esi Primitives Stderr 0) -22276 (flush _test-output-buffered-file) -22277 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -22283 # check output -22284 (check-next-stream-line-equal _test-output-stream "3d/compare-eax-with 0x34/imm32" "F - test-compare-eax-with-literal") -22285 # . epilogue -22286 89/<- %esp 5/r32/ebp -22287 5d/pop-to-ebp -22288 c3/return -22289 -22290 test-compare-reg-with-literal: -22291 # compare var1/ecx 0x34 -22292 # => -22293 # 81 7/subop/compare %ecx 0x34/imm32 -22294 # -22295 # . prologue -22296 55/push-ebp -22297 89/<- %ebp 4/r32/esp -22298 # setup -22299 (clear-stream _test-output-stream) -22300 (clear-stream $_test-output-buffered-file->buffer) -22301 $test-compare-reg-with-literal:initialize-type: -22302 # var type/ecx: (payload type-tree) = int -22303 68/push 0/imm32/right:null -22304 68/push 0/imm32/right:null -22305 68/push 0/imm32/left:unused -22306 68/push 1/imm32/value:int -22307 68/push 1/imm32/is-atom?:true -22308 68/push 0x11/imm32/alloc-id:fake:payload -22309 89/<- %ecx 4/r32/esp -22310 $test-compare-reg-with-literal:initialize-var1: -22311 # var var1/ecx: (payload var) -22312 68/push 0/imm32/register -22313 68/push 0/imm32/register -22314 68/push 0/imm32/no-stack-offset -22315 68/push 1/imm32/block-depth -22316 51/push-ecx -22317 68/push 0x11/imm32/alloc-id:fake -22318 68/push 0/imm32/name -22319 68/push 0/imm32/name -22320 68/push 0x11/imm32/alloc-id:fake:payload -22321 89/<- %ecx 4/r32/esp -22322 $test-compare-reg-with-literal:initialize-var1-name: -22323 # var1->name = "var1" -22324 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -22325 (copy-array Heap "var1" %eax) -22326 $test-compare-reg-with-literal:initialize-var1-register: -22327 # v->register = "ecx" -22328 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 -22329 (copy-array Heap "ecx" %eax) -22330 $test-compare-reg-with-literal:initialize-literal-type: -22331 # var type/edx: (payload type-tree) = literal -22332 68/push 0/imm32/right:null -22333 68/push 0/imm32/right:null -22334 68/push 0/imm32/left:unused -22335 68/push 0/imm32/value:literal -22336 68/push 1/imm32/is-atom?:true -22337 68/push 0x11/imm32/alloc-id:fake:payload -22338 89/<- %edx 4/r32/esp -22339 $test-compare-reg-with-literal:initialize-literal: -22340 # var l/edx: (payload var) -22341 68/push 0/imm32/register -22342 68/push 0/imm32/register -22343 68/push 0/imm32/no-stack-offset -22344 68/push 1/imm32/block-depth -22345 52/push-edx -22346 68/push 0x11/imm32/alloc-id:fake -22347 68/push 0/imm32/name -22348 68/push 0/imm32/name -22349 68/push 0x11/imm32/alloc-id:fake:payload -22350 89/<- %edx 4/r32/esp -22351 $test-compare-reg-with-literal:initialize-literal-value: -22352 # l->name = "0x34" -22353 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 -22354 (copy-array Heap "0x34" %eax) -22355 $test-compare-reg-with-literal:initialize-inouts: -22356 # var inouts/esi: (payload stmt-var) = [l] -22357 68/push 0/imm32/is-deref:false -22358 68/push 0/imm32/next -22359 68/push 0/imm32/next -22360 52/push-edx/l -22361 68/push 0x11/imm32/alloc-id:fake -22362 68/push 0x11/imm32/alloc-id:fake:payload -22363 89/<- %esi 4/r32/esp -22364 # var inouts = (handle stmt-var) = [var1, var2] -22365 68/push 0/imm32/is-deref:false -22366 56/push-esi/next -22367 68/push 0x11/imm32/alloc-id:fake -22368 51/push-ecx/var1 -22369 68/push 0x11/imm32/alloc-id:fake -22370 68/push 0x11/imm32/alloc-id:fake:payload -22371 89/<- %esi 4/r32/esp -22372 $test-compare-reg-with-literal:initialize-stmt: -22373 # var stmt/esi: (addr statement) -22374 68/push 0/imm32/next -22375 68/push 0/imm32/next -22376 68/push 0/imm32/outputs -22377 68/push 0/imm32/outputs -22378 56/push-esi/inouts -22379 68/push 0x11/imm32/alloc-id:fake -22380 68/push 0/imm32/operation -22381 68/push 0/imm32/operation -22382 68/push 1/imm32/tag:stmt1 -22383 89/<- %esi 4/r32/esp -22384 $test-compare-reg-with-literal:initialize-stmt-operation: -22385 # stmt->operation = "compare" -22386 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -22387 (copy-array Heap "compare" %eax) -22388 # convert -22389 c7 0/subop/copy *Curr-block-depth 0/imm32 -22390 (emit-subx-stmt _test-output-buffered-file %esi Primitives Stderr 0) -22391 (flush _test-output-buffered-file) -22392 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -22398 # check output -22399 (check-next-stream-line-equal _test-output-stream "81 7/subop/compare %ecx 0x34/imm32" "F - test-compare-reg-with-literal") -22400 # . epilogue -22401 89/<- %esp 5/r32/ebp -22402 5d/pop-to-ebp -22403 c3/return -22404 -22405 test-emit-subx-stmt-function-call: -22406 # Call a function on a variable on the stack. -22407 # f foo -22408 # => -22409 # (f *(ebp-8)) -22410 # (Changing the function name supports overloading in general, but here it -22411 # just serves to help disambiguate things.) -22412 # -22413 # There's a variable on the var stack as follows: -22414 # name: 'foo' -22415 # type: int -22416 # stack-offset: -8 -22417 # -22418 # There's nothing in primitives. -22419 # -22420 # We don't perform any checking here on the type of 'f'. -22421 # -22422 # . prologue -22423 55/push-ebp -22424 89/<- %ebp 4/r32/esp -22425 # setup -22426 (clear-stream _test-output-stream) -22427 (clear-stream $_test-output-buffered-file->buffer) -22428 $test-emit-subx-function-call:initialize-type: -22429 # var type/ecx: (payload type-tree) = int -22430 68/push 0/imm32/right:null -22431 68/push 0/imm32/right:null -22432 68/push 0/imm32/left:unused -22433 68/push 1/imm32/value:int -22434 68/push 1/imm32/is-atom?:true -22435 68/push 0x11/imm32/alloc-id:fake:payload -22436 89/<- %ecx 4/r32/esp -22437 $test-emit-subx-function-call:initialize-var: -22438 # var var-foo/ecx: (payload var) = var(type) -22439 68/push 0/imm32/no-register -22440 68/push 0/imm32/no-register -22441 68/push -8/imm32/stack-offset -22442 68/push 1/imm32/block-depth -22443 51/push-ecx/type -22444 68/push 0x11/imm32/alloc-id:fake -22445 68/push 0/imm32/name -22446 68/push 0/imm32/name -22447 68/push 0x11/imm32/alloc-id:fake:payload -22448 89/<- %ecx 4/r32/esp -22449 $test-emit-subx-function-call:initialize-var-name: -22450 # var-foo->name = "foo" -22451 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -22452 (copy-array Heap "foo" %eax) -22453 $test-emit-subx-function-call:initialize-stmt-var: -22454 # var operand/ebx: (payload stmt-var) = stmt-var(var-foo) -22455 68/push 0/imm32/is-deref:false -22456 68/push 0/imm32/next -22457 68/push 0/imm32/next -22458 51/push-ecx/var-foo +22247 68/push 0/imm32/operation +22248 68/push 0/imm32/operation +22249 68/push 1/imm32/tag:stmt1 +22250 89/<- %esi 4/r32/esp +22251 $test-add-reg-to-reg:initialize-stmt-operation: +22252 # stmt->operation = "add" +22253 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +22254 (copy-array Heap "add" %eax) +22255 # convert +22256 c7 0/subop/copy *Curr-block-depth 0/imm32 +22257 (emit-subx-stmt _test-output-buffered-file %esi Primitives Stderr 0) +22258 (flush _test-output-buffered-file) +22259 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +22265 # check output +22266 (check-next-stream-line-equal _test-output-stream "01/add-to %eax 0x00000001/r32" "F - test-add-reg-to-reg") +22267 # . epilogue +22268 89/<- %esp 5/r32/ebp +22269 5d/pop-to-ebp +22270 c3/return +22271 +22272 test-add-reg-to-mem: +22273 # add-to var1 var2/reg +22274 # => +22275 # 01/add-to *(ebp+__) var2 +22276 # +22277 # . prologue +22278 55/push-ebp +22279 89/<- %ebp 4/r32/esp +22280 # setup +22281 (clear-stream _test-output-stream) +22282 (clear-stream $_test-output-buffered-file->buffer) +22283 $test-add-reg-to-mem:initialize-type: +22284 # var type/ecx: (payload type-tree) = int +22285 68/push 0/imm32/right:null +22286 68/push 0/imm32/right:null +22287 68/push 0/imm32/left:unused +22288 68/push 1/imm32/value:int +22289 68/push 1/imm32/is-atom?:true +22290 68/push 0x11/imm32/alloc-id:fake:payload +22291 89/<- %ecx 4/r32/esp +22292 $test-add-reg-to-mem:initialize-var1: +22293 # var var1/ecx: (payload var) +22294 68/push 0/imm32/register +22295 68/push 0/imm32/register +22296 68/push 8/imm32/stack-offset +22297 68/push 1/imm32/block-depth +22298 51/push-ecx +22299 68/push 0x11/imm32/alloc-id:fake +22300 68/push 0/imm32/name +22301 68/push 0/imm32/name +22302 68/push 0x11/imm32/alloc-id:fake:payload +22303 89/<- %ecx 4/r32/esp +22304 $test-add-reg-to-mem:initialize-var1-name: +22305 # var1->name = "var1" +22306 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +22307 (copy-array Heap "var1" %eax) +22308 $test-add-reg-to-mem:initialize-var2: +22309 # var var2/edx: (payload var) +22310 68/push 0/imm32/register +22311 68/push 0/imm32/register +22312 68/push 0/imm32/no-stack-offset +22313 68/push 1/imm32/block-depth +22314 ff 6/subop/push *(ecx+0x10) +22315 68/push 0x11/imm32/alloc-id:fake +22316 68/push 0/imm32/name +22317 68/push 0/imm32/name +22318 68/push 0x11/imm32/alloc-id:fake:payload +22319 89/<- %edx 4/r32/esp +22320 $test-add-reg-to-mem:initialize-var2-name: +22321 # var2->name = "var2" +22322 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 +22323 (copy-array Heap "var2" %eax) +22324 $test-add-reg-to-mem:initialize-var2-register: +22325 # var2->register = "ecx" +22326 8d/copy-address *(edx+0x1c) 0/r32/eax # Var-register + 4 +22327 (copy-array Heap "ecx" %eax) +22328 $test-add-reg-to-mem:initialize-inouts: +22329 # var inouts/esi: (payload stmt-var) = [var2] +22330 68/push 0/imm32/is-deref:false +22331 68/push 0/imm32/next +22332 68/push 0/imm32/next +22333 52/push-edx/var2 +22334 68/push 0x11/imm32/alloc-id:fake +22335 68/push 0x11/imm32/alloc-id:fake:payload +22336 89/<- %esi 4/r32/esp +22337 # inouts = [var1, var2] +22338 68/push 0/imm32/is-deref:false +22339 56/push-esi/next +22340 68/push 0x11/imm32/alloc-id:fake +22341 51/push-ecx/var1 +22342 68/push 0x11/imm32/alloc-id:fake +22343 68/push 0x11/imm32/alloc-id:fake:payload +22344 89/<- %esi 4/r32/esp +22345 $test-add-reg-to-mem:initialize-stmt: +22346 # var stmt/esi: (addr statement) +22347 68/push 0/imm32/next +22348 68/push 0/imm32/next +22349 68/push 0/imm32/outputs +22350 68/push 0/imm32/outputs +22351 56/push-esi/inouts +22352 68/push 0x11/imm32/alloc-id:fake +22353 68/push 0/imm32/operation +22354 68/push 0/imm32/operation +22355 68/push 1/imm32/tag:stmt1 +22356 89/<- %esi 4/r32/esp +22357 $test-add-reg-to-mem:initialize-stmt-operation: +22358 # stmt->operation = "add-to" +22359 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +22360 (copy-array Heap "add-to" %eax) +22361 # convert +22362 c7 0/subop/copy *Curr-block-depth 0/imm32 +22363 (emit-subx-stmt _test-output-buffered-file %esi Primitives Stderr 0) +22364 (flush _test-output-buffered-file) +22365 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +22371 # check output +22372 (check-next-stream-line-equal _test-output-stream "01/add-to *(ebp+0x00000008) 0x00000001/r32" "F - test-add-reg-to-mem") +22373 # . epilogue +22374 89/<- %esp 5/r32/ebp +22375 5d/pop-to-ebp +22376 c3/return +22377 +22378 test-add-mem-to-reg: +22379 # var1/reg <- add var2 +22380 # => +22381 # 03/add *(ebp+__) var1 +22382 # +22383 # . prologue +22384 55/push-ebp +22385 89/<- %ebp 4/r32/esp +22386 # setup +22387 (clear-stream _test-output-stream) +22388 (clear-stream $_test-output-buffered-file->buffer) +22389 $test-add-mem-to-reg:initialize-type: +22390 # var type/ecx: (payload type-tree) = int +22391 68/push 0/imm32/right:null +22392 68/push 0/imm32/right:null +22393 68/push 0/imm32/left:unused +22394 68/push 1/imm32/value:int +22395 68/push 1/imm32/is-atom?:true +22396 68/push 0x11/imm32/alloc-id:fake:payload +22397 89/<- %ecx 4/r32/esp +22398 $test-add-mem-to-reg:initialize-var: +22399 # var var1/ecx: (payload var) +22400 68/push 0/imm32/register +22401 68/push 0/imm32/register +22402 68/push 0/imm32/no-stack-offset +22403 68/push 1/imm32/block-depth +22404 51/push-ecx +22405 68/push 0x11/imm32/alloc-id:fake +22406 68/push 0/imm32/name +22407 68/push 0/imm32/name +22408 68/push 0x11/imm32/alloc-id:fake:payload +22409 89/<- %ecx 4/r32/esp +22410 $test-add-mem-to-reg:initialize-var-name: +22411 # var1->name = "foo" +22412 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +22413 (copy-array Heap "var1" %eax) +22414 $test-add-mem-to-reg:initialize-var-register: +22415 # var1->register = "eax" +22416 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 +22417 (copy-array Heap "eax" %eax) +22418 $test-add-mem-to-reg:initialize-var2: +22419 # var var2/edx: (payload var) +22420 68/push 0/imm32/register +22421 68/push 0/imm32/register +22422 68/push 8/imm32/stack-offset +22423 68/push 1/imm32/block-depth +22424 ff 6/subop/push *(ecx+0x10) +22425 68/push 0x11/imm32/alloc-id:fake +22426 68/push 0/imm32/name +22427 68/push 0/imm32/name +22428 68/push 0x11/imm32/alloc-id:fake:payload +22429 89/<- %edx 4/r32/esp +22430 $test-add-mem-to-reg:initialize-var2-name: +22431 # var2->name = "var2" +22432 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 +22433 (copy-array Heap "var2" %eax) +22434 $test-add-mem-to-reg:initialize-inouts: +22435 # var inouts/esi: (payload stmt-var) = [var2] +22436 68/push 0/imm32/is-deref:false +22437 68/push 0/imm32/next +22438 68/push 0/imm32/next +22439 52/push-edx/var2 +22440 68/push 0x11/imm32/alloc-id:fake +22441 68/push 0x11/imm32/alloc-id:fake:payload +22442 89/<- %esi 4/r32/esp +22443 $test-add-mem-to-reg:initialize-outputs: +22444 # var outputs/edi: (payload stmt-var) = [var1] +22445 68/push 0/imm32/is-deref:false +22446 68/push 0/imm32/next +22447 68/push 0/imm32/next +22448 51/push-ecx/var1 +22449 68/push 0x11/imm32/alloc-id:fake +22450 68/push 0x11/imm32/alloc-id:fake:payload +22451 89/<- %edi 4/r32/esp +22452 $test-add-mem-to-reg:initialize-stmt: +22453 # var stmt/esi: (addr statement) +22454 68/push 0/imm32/next +22455 68/push 0/imm32/next +22456 57/push-edi/outputs +22457 68/push 0x11/imm32/alloc-id:fake +22458 56/push-esi/inouts 22459 68/push 0x11/imm32/alloc-id:fake -22460 68/push 0x11/imm32/alloc-id:fake:payload -22461 89/<- %ebx 4/r32/esp -22462 $test-emit-subx-function-call:initialize-stmt: -22463 # var stmt/esi: (addr statement) -22464 68/push 0/imm32/no-outputs -22465 68/push 0/imm32/no-outputs -22466 53/push-ebx/inouts -22467 68/push 0x11/imm32/alloc-id:fake -22468 68/push 0/imm32/operation -22469 68/push 0/imm32/operation -22470 68/push 1/imm32/tag -22471 89/<- %esi 4/r32/esp -22472 $test-emit-subx-function-call:initialize-stmt-operation: -22473 # stmt->operation = "f" -22474 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -22475 (copy-array Heap "f" %eax) -22476 # convert -22477 c7 0/subop/copy *Curr-block-depth 0/imm32 -22478 (emit-subx-stmt _test-output-buffered-file %esi 0 Stderr 0) -22479 (flush _test-output-buffered-file) -22480 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -22486 # check output -22487 (check-next-stream-line-equal _test-output-stream "(f *(ebp+0xfffffff8))" "F - test-emit-subx-stmt-function-call") -22488 # . epilogue -22489 89/<- %esp 5/r32/ebp -22490 5d/pop-to-ebp -22491 c3/return -22492 -22493 test-emit-subx-stmt-function-call-with-literal-arg: -22494 # Call a function on a literal. -22495 # f 0x34 -22496 # => -22497 # (f2 0x34) -22498 # -22499 # . prologue -22500 55/push-ebp -22501 89/<- %ebp 4/r32/esp -22502 # setup -22503 (clear-stream _test-output-stream) -22504 (clear-stream $_test-output-buffered-file->buffer) -22505 $test-emit-subx-function-call-with-literal-arg:initialize-type: -22506 # var type/ecx: (payload type-tree) = int -22507 68/push 0/imm32/right:null -22508 68/push 0/imm32/right:null -22509 68/push 0/imm32/left:unused -22510 68/push 0/imm32/value:literal -22511 68/push 1/imm32/is-atom?:true -22512 68/push 0x11/imm32/alloc-id:fake:payload -22513 89/<- %ecx 4/r32/esp -22514 $test-emit-subx-function-call-with-literal-arg:initialize-var: -22515 # var var-foo/ecx: (payload var) = var(lit) -22516 68/push 0/imm32/no-register -22517 68/push 0/imm32/no-register -22518 68/push 0/imm32/no-stack-offset -22519 68/push 1/imm32/block-depth -22520 51/push-ecx/type -22521 68/push 0x11/imm32/alloc-id:fake -22522 68/push 0/imm32/name -22523 68/push 0/imm32/name -22524 68/push 0x11/imm32/alloc-id:fake:payload -22525 89/<- %ecx 4/r32/esp -22526 $test-emit-subx-function-call-with-literal-arg:initialize-var-name: -22527 # var-foo->name = "0x34" -22528 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -22529 (copy-array Heap "0x34" %eax) -22530 $test-emit-subx-function-call-with-literal-arg:initialize-stmt-var: -22531 # var operand/ebx: (payload stmt-var) = stmt-var(var-foo) -22532 68/push 0/imm32/is-deref:false -22533 68/push 0/imm32/next -22534 68/push 0/imm32/next -22535 51/push-ecx/var-foo -22536 68/push 0x11/imm32/alloc-id:fake -22537 68/push 0x11/imm32/alloc-id:fake:payload -22538 89/<- %ebx 4/r32/esp -22539 $test-emit-subx-function-call-with-literal-arg:initialize-stmt: -22540 # var stmt/esi: (addr statement) -22541 68/push 0/imm32/no-outputs -22542 68/push 0/imm32/no-outputs -22543 53/push-ebx/inouts -22544 68/push 0x11/imm32/alloc-id:fake -22545 68/push 0/imm32/operation -22546 68/push 0/imm32/operation -22547 68/push 1/imm32/tag -22548 89/<- %esi 4/r32/esp -22549 $test-emit-subx-function-call-with-literal-arg:initialize-stmt-operation: -22550 # stmt->operation = "f" -22551 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -22552 (copy-array Heap "f" %eax) -22553 # convert -22554 c7 0/subop/copy *Curr-block-depth 0/imm32 -22555 (emit-subx-stmt _test-output-buffered-file %esi 0 %ebx Stderr 0) -22556 (flush _test-output-buffered-file) -22557 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -22563 # check output -22564 (check-next-stream-line-equal _test-output-stream "(f 0x34)" "F - test-emit-subx-stmt-function-call-with-literal-arg") -22565 # . epilogue -22566 89/<- %esp 5/r32/ebp -22567 5d/pop-to-ebp -22568 c3/return -22569 -22570 emit-indent: # out: (addr buffered-file), n: int -22571 # . prologue -22572 55/push-ebp -22573 89/<- %ebp 4/r32/esp -22574 # . save registers -22575 50/push-eax -22576 # var i/eax: int = n -22577 8b/-> *(ebp+0xc) 0/r32/eax -22578 { -22579 # if (i <= 0) break -22580 3d/compare-eax-with 0/imm32 -22581 7e/jump-if-<= break/disp8 -22582 (write-buffered *(ebp+8) " ") -22583 48/decrement-eax -22584 eb/jump loop/disp8 -22585 } -22586 $emit-indent:end: -22587 # . restore registers -22588 58/pop-to-eax -22589 # . epilogue -22590 89/<- %esp 5/r32/ebp -22591 5d/pop-to-ebp -22592 c3/return -22593 -22594 emit-subx-prologue: # out: (addr buffered-file) -22595 # . prologue -22596 55/push-ebp -22597 89/<- %ebp 4/r32/esp -22598 # -22599 (write-buffered *(ebp+8) " # . prologue\n") -22600 (write-buffered *(ebp+8) " 55/push-ebp\n") -22601 (write-buffered *(ebp+8) " 89/<- %ebp 4/r32/esp\n") -22602 $emit-subx-prologue:end: -22603 # . epilogue -22604 89/<- %esp 5/r32/ebp -22605 5d/pop-to-ebp -22606 c3/return -22607 -22608 emit-subx-epilogue: # out: (addr buffered-file) -22609 # . prologue -22610 55/push-ebp -22611 89/<- %ebp 4/r32/esp -22612 # -22613 (write-buffered *(ebp+8) " # . epilogue\n") -22614 (write-buffered *(ebp+8) " 89/<- %esp 5/r32/ebp\n") -22615 (write-buffered *(ebp+8) " 5d/pop-to-ebp\n") -22616 (write-buffered *(ebp+8) " c3/return\n") -22617 $emit-subx-epilogue:end: -22618 # . epilogue -22619 89/<- %esp 5/r32/ebp -22620 5d/pop-to-ebp -22621 c3/return +22460 68/push 0/imm32/operation +22461 68/push 0/imm32/operation +22462 68/push 1/imm32/tag:stmt1 +22463 89/<- %esi 4/r32/esp +22464 $test-add-mem-to-reg:initialize-stmt-operation: +22465 # stmt->operation = "add" +22466 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +22467 (copy-array Heap "add" %eax) +22468 # convert +22469 c7 0/subop/copy *Curr-block-depth 0/imm32 +22470 (emit-subx-stmt _test-output-buffered-file %esi Primitives Stderr 0) +22471 (flush _test-output-buffered-file) +22472 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +22478 # check output +22479 (check-next-stream-line-equal _test-output-stream "03/add *(ebp+0x00000008) 0x00000000/r32" "F - test-add-mem-to-reg") +22480 # . epilogue +22481 89/<- %esp 5/r32/ebp +22482 5d/pop-to-ebp +22483 c3/return +22484 +22485 test-add-literal-to-eax: +22486 # var1/eax <- add 0x34 +22487 # => +22488 # 05/add-to-eax 0x34/imm32 +22489 # +22490 # . prologue +22491 55/push-ebp +22492 89/<- %ebp 4/r32/esp +22493 # setup +22494 (clear-stream _test-output-stream) +22495 (clear-stream $_test-output-buffered-file->buffer) +22496 $test-add-literal-to-eax:initialize-var-type: +22497 # var type/ecx: (payload type-tree) = int +22498 68/push 0/imm32/right:null +22499 68/push 0/imm32/right:null +22500 68/push 0/imm32/left:unused +22501 68/push 1/imm32/value:int +22502 68/push 1/imm32/is-atom?:true +22503 68/push 0x11/imm32/alloc-id:fake:payload +22504 89/<- %ecx 4/r32/esp +22505 $test-add-literal-to-eax:initialize-var: +22506 # var v/ecx: (payload var) +22507 68/push 0/imm32/register +22508 68/push 0/imm32/register +22509 68/push 0/imm32/no-stack-offset +22510 68/push 1/imm32/block-depth +22511 51/push-ecx +22512 68/push 0x11/imm32/alloc-id:fake +22513 68/push 0/imm32/name +22514 68/push 0/imm32/name +22515 68/push 0x11/imm32/alloc-id:fake:payload +22516 89/<- %ecx 4/r32/esp +22517 $test-add-literal-to-eax:initialize-var-name: +22518 # v->name = "v" +22519 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +22520 (copy-array Heap "v" %eax) +22521 $test-add-literal-to-eax:initialize-var-register: +22522 # v->register = "eax" +22523 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 +22524 (copy-array Heap "eax" %eax) +22525 $test-add-literal-to-eax:initialize-literal-type: +22526 # var type/edx: (payload type-tree) = literal +22527 68/push 0/imm32/right:null +22528 68/push 0/imm32/right:null +22529 68/push 0/imm32/left:unused +22530 68/push 0/imm32/value:literal +22531 68/push 1/imm32/is-atom?:true +22532 68/push 0x11/imm32/alloc-id:fake:payload +22533 89/<- %edx 4/r32/esp +22534 $test-add-literal-to-eax:initialize-literal: +22535 # var l/edx: (payload var) +22536 68/push 0/imm32/register +22537 68/push 0/imm32/register +22538 68/push 0/imm32/no-stack-offset +22539 68/push 1/imm32/block-depth +22540 52/push-edx +22541 68/push 0x11/imm32/alloc-id:fake +22542 68/push 0/imm32/name +22543 68/push 0/imm32/name +22544 68/push 0x11/imm32/alloc-id:fake:payload +22545 89/<- %edx 4/r32/esp +22546 $test-add-literal-to-eax:initialize-literal-value: +22547 # l->name = "0x34" +22548 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 +22549 (copy-array Heap "0x34" %eax) +22550 $test-add-literal-to-eax:initialize-inouts: +22551 # var inouts/esi: (payload stmt-var) = [l] +22552 68/push 0/imm32/is-deref:false +22553 68/push 0/imm32/next +22554 68/push 0/imm32/next +22555 52/push-edx/l +22556 68/push 0x11/imm32/alloc-id:fake +22557 68/push 0x11/imm32/alloc-id:fake:payload +22558 89/<- %esi 4/r32/esp +22559 $test-add-literal-to-eax:initialize-outputs: +22560 # var outputs/edi: (payload stmt-var) = [v] +22561 68/push 0/imm32/is-deref:false +22562 68/push 0/imm32/next +22563 68/push 0/imm32/next +22564 51/push-ecx/v +22565 68/push 0x11/imm32/alloc-id:fake +22566 68/push 0x11/imm32/alloc-id:fake:payload +22567 89/<- %edi 4/r32/esp +22568 $test-add-literal-to-eax:initialize-stmt: +22569 # var stmt/esi: (addr statement) +22570 68/push 0/imm32/next +22571 68/push 0/imm32/next +22572 57/push-edi/outputs +22573 68/push 0x11/imm32/alloc-id:fake +22574 56/push-esi/inouts +22575 68/push 0x11/imm32/alloc-id:fake +22576 68/push 0/imm32/operation +22577 68/push 0/imm32/operation +22578 68/push 1/imm32/tag:stmt1 +22579 89/<- %esi 4/r32/esp +22580 $test-add-literal-to-eax:initialize-stmt-operation: +22581 # stmt->operation = "add" +22582 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +22583 (copy-array Heap "add" %eax) +22584 # convert +22585 c7 0/subop/copy *Curr-block-depth 0/imm32 +22586 (emit-subx-stmt _test-output-buffered-file %esi Primitives Stderr 0) +22587 (flush _test-output-buffered-file) +22588 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +22594 # check output +22595 (check-next-stream-line-equal _test-output-stream "05/add-to-eax 0x34/imm32" "F - test-add-literal-to-eax") +22596 # . epilogue +22597 89/<- %esp 5/r32/ebp +22598 5d/pop-to-ebp +22599 c3/return +22600 +22601 test-add-literal-to-reg: +22602 # var1/ecx <- add 0x34 +22603 # => +22604 # 81 0/subop/add %ecx 0x34/imm32 +22605 # +22606 # . prologue +22607 55/push-ebp +22608 89/<- %ebp 4/r32/esp +22609 # setup +22610 (clear-stream _test-output-stream) +22611 (clear-stream $_test-output-buffered-file->buffer) +22612 $test-add-literal-to-reg:initialize-var-type: +22613 # var type/ecx: (payload type-tree) = int +22614 68/push 0/imm32/right:null +22615 68/push 0/imm32/right:null +22616 68/push 0/imm32/left:unused +22617 68/push 1/imm32/value:int +22618 68/push 1/imm32/is-atom?:true +22619 68/push 0x11/imm32/alloc-id:fake:payload +22620 89/<- %ecx 4/r32/esp +22621 $test-add-literal-to-reg:initialize-var: +22622 # var v/ecx: (payload var) +22623 68/push 0/imm32/register +22624 68/push 0/imm32/register +22625 68/push 0/imm32/no-stack-offset +22626 68/push 1/imm32/block-depth +22627 51/push-ecx +22628 68/push 0x11/imm32/alloc-id:fake +22629 68/push 0/imm32/name +22630 68/push 0/imm32/name +22631 68/push 0x11/imm32/alloc-id:fake:payload +22632 89/<- %ecx 4/r32/esp +22633 $test-add-literal-to-reg:initialize-var-name: +22634 # v->name = "v" +22635 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +22636 (copy-array Heap "v" %eax) +22637 $test-add-literal-to-reg:initialize-var-register: +22638 # v->register = "ecx" +22639 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 +22640 (copy-array Heap "ecx" %eax) +22641 $test-add-literal-to-reg:initialize-literal-type: +22642 # var type/edx: (payload type-tree) = literal +22643 68/push 0/imm32/right:null +22644 68/push 0/imm32/right:null +22645 68/push 0/imm32/left:unused +22646 68/push 0/imm32/value:literal +22647 68/push 1/imm32/is-atom?:true +22648 68/push 0x11/imm32/alloc-id:fake:payload +22649 89/<- %edx 4/r32/esp +22650 $test-add-literal-to-reg:initialize-literal: +22651 # var l/edx: (payload var) +22652 68/push 0/imm32/register +22653 68/push 0/imm32/register +22654 68/push 0/imm32/no-stack-offset +22655 68/push 1/imm32/block-depth +22656 52/push-edx +22657 68/push 0x11/imm32/alloc-id:fake +22658 68/push 0/imm32/name +22659 68/push 0/imm32/name +22660 68/push 0x11/imm32/alloc-id:fake:payload +22661 89/<- %edx 4/r32/esp +22662 $test-add-literal-to-reg:initialize-literal-value: +22663 # l->name = "0x34" +22664 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 +22665 (copy-array Heap "0x34" %eax) +22666 $test-add-literal-to-reg:initialize-inouts: +22667 # var inouts/esi: (payload stmt-var) = [l] +22668 68/push 0/imm32/is-deref:false +22669 68/push 0/imm32/next +22670 68/push 0/imm32/next +22671 52/push-edx/l +22672 68/push 0x11/imm32/alloc-id:fake +22673 68/push 0x11/imm32/alloc-id:fake:payload +22674 89/<- %esi 4/r32/esp +22675 $test-add-literal-to-reg:initialize-outputs: +22676 # var outputs/edi: (payload stmt-var) = [v] +22677 68/push 0/imm32/is-deref:false +22678 68/push 0/imm32/next +22679 68/push 0/imm32/next +22680 51/push-ecx/v +22681 68/push 0x11/imm32/alloc-id:fake +22682 68/push 0x11/imm32/alloc-id:fake:payload +22683 89/<- %edi 4/r32/esp +22684 $test-add-literal-to-reg:initialize-stmt: +22685 # var stmt/esi: (addr statement) +22686 68/push 0/imm32/next +22687 68/push 0/imm32/next +22688 57/push-edi/outputs +22689 68/push 0x11/imm32/alloc-id:fake +22690 56/push-esi/inouts +22691 68/push 0x11/imm32/alloc-id:fake +22692 68/push 0/imm32/operation +22693 68/push 0/imm32/operation +22694 68/push 1/imm32/tag:stmt1 +22695 89/<- %esi 4/r32/esp +22696 $test-add-literal-to-reg:initialize-stmt-operation: +22697 # stmt->operation = "add" +22698 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +22699 (copy-array Heap "add" %eax) +22700 # convert +22701 c7 0/subop/copy *Curr-block-depth 0/imm32 +22702 (emit-subx-stmt _test-output-buffered-file %esi Primitives Stderr 0) +22703 (flush _test-output-buffered-file) +22704 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +22710 # check output +22711 (check-next-stream-line-equal _test-output-stream "81 0/subop/add %ecx 0x34/imm32" "F - test-add-literal-to-reg") +22712 # . epilogue +22713 89/<- %esp 5/r32/ebp +22714 5d/pop-to-ebp +22715 c3/return +22716 +22717 test-add-literal-to-mem: +22718 # add-to var1, 0x34 +22719 # => +22720 # 81 0/subop/add %eax 0x34/imm32 +22721 # +22722 # . prologue +22723 55/push-ebp +22724 89/<- %ebp 4/r32/esp +22725 # setup +22726 (clear-stream _test-output-stream) +22727 (clear-stream $_test-output-buffered-file->buffer) +22728 $test-add-literal-to-mem:initialize-type: +22729 # var type/ecx: (payload type-tree) = int +22730 68/push 0/imm32/right:null +22731 68/push 0/imm32/right:null +22732 68/push 0/imm32/left:unused +22733 68/push 1/imm32/value:int +22734 68/push 1/imm32/is-atom?:true +22735 68/push 0x11/imm32/alloc-id:fake:payload +22736 89/<- %ecx 4/r32/esp +22737 $test-add-literal-to-mem:initialize-var1: +22738 # var var1/ecx: (payload var) +22739 68/push 0/imm32/register +22740 68/push 0/imm32/register +22741 68/push 8/imm32/stack-offset +22742 68/push 1/imm32/block-depth +22743 51/push-ecx +22744 68/push 0x11/imm32/alloc-id:fake +22745 68/push 0/imm32/name +22746 68/push 0/imm32/name +22747 68/push 0x11/imm32/alloc-id:fake:payload +22748 89/<- %ecx 4/r32/esp +22749 $test-add-literal-to-mem:initialize-var1-name: +22750 # var1->name = "var1" +22751 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +22752 (copy-array Heap "var1" %eax) +22753 $test-add-literal-to-mem:initialize-literal-type: +22754 # var type/edx: (payload type-tree) = literal +22755 68/push 0/imm32/right:null +22756 68/push 0/imm32/right:null +22757 68/push 0/imm32/left:unused +22758 68/push 0/imm32/value:literal +22759 68/push 1/imm32/is-atom?:true +22760 68/push 0x11/imm32/alloc-id:fake:payload +22761 89/<- %edx 4/r32/esp +22762 $test-add-literal-to-mem:initialize-literal: +22763 # var l/edx: (payload var) +22764 68/push 0/imm32/register +22765 68/push 0/imm32/register +22766 68/push 0/imm32/no-stack-offset +22767 68/push 1/imm32/block-depth +22768 52/push-edx +22769 68/push 0x11/imm32/alloc-id:fake +22770 68/push 0/imm32/name +22771 68/push 0/imm32/name +22772 68/push 0x11/imm32/alloc-id:fake:payload +22773 89/<- %edx 4/r32/esp +22774 $test-add-literal-to-mem:initialize-literal-value: +22775 # l->name = "0x34" +22776 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 +22777 (copy-array Heap "0x34" %eax) +22778 $test-add-literal-to-mem:initialize-inouts: +22779 # var inouts/esi: (payload stmt-var) = [l] +22780 68/push 0/imm32/is-deref:false +22781 68/push 0/imm32/next +22782 68/push 0/imm32/next +22783 52/push-edx/l +22784 68/push 0x11/imm32/alloc-id:fake +22785 68/push 0x11/imm32/alloc-id:fake:payload +22786 89/<- %esi 4/r32/esp +22787 # var inouts = (handle stmt-var) = [var1, var2] +22788 68/push 0/imm32/is-deref:false +22789 56/push-esi/next +22790 68/push 0x11/imm32/alloc-id:fake +22791 51/push-ecx/var1 +22792 68/push 0x11/imm32/alloc-id:fake +22793 68/push 0x11/imm32/alloc-id:fake:payload +22794 89/<- %esi 4/r32/esp +22795 $test-add-literal-to-mem:initialize-stmt: +22796 # var stmt/esi: (addr statement) +22797 68/push 0/imm32/next +22798 68/push 0/imm32/next +22799 68/push 0/imm32/outputs +22800 68/push 0/imm32/outputs +22801 56/push-esi/inouts +22802 68/push 0x11/imm32/alloc-id:fake +22803 68/push 0/imm32/operation +22804 68/push 0/imm32/operation +22805 68/push 1/imm32/tag:stmt1 +22806 89/<- %esi 4/r32/esp +22807 $test-add-literal-to-mem:initialize-stmt-operation: +22808 # stmt->operation = "add-to" +22809 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +22810 (copy-array Heap "add-to" %eax) +22811 # convert +22812 c7 0/subop/copy *Curr-block-depth 0/imm32 +22813 (emit-subx-stmt _test-output-buffered-file %esi Primitives Stderr 0) +22814 (flush _test-output-buffered-file) +22815 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +22821 # check output +22822 (check-next-stream-line-equal _test-output-stream "81 0/subop/add *(ebp+0x00000008) 0x34/imm32" "F - test-add-literal-to-mem") +22823 # . epilogue +22824 89/<- %esp 5/r32/ebp +22825 5d/pop-to-ebp +22826 c3/return +22827 +22828 test-shift-reg-by-literal: +22829 # var1/ecx <- shift-left 2 +22830 # => +22831 # c1/shift 4/subop/left %ecx 2/imm8 +22832 # +22833 # . prologue +22834 55/push-ebp +22835 89/<- %ebp 4/r32/esp +22836 # setup +22837 (clear-stream _test-output-stream) +22838 (clear-stream $_test-output-buffered-file->buffer) +22839 $test-shift-reg-by-literal:initialize-var-type: +22840 # var type/ecx: (payload type-tree) = int +22841 68/push 0/imm32/right:null +22842 68/push 0/imm32/right:null +22843 68/push 0/imm32/left:unused +22844 68/push 1/imm32/value:int +22845 68/push 1/imm32/is-atom?:true +22846 68/push 0x11/imm32/alloc-id:fake:payload +22847 89/<- %ecx 4/r32/esp +22848 $test-shift-reg-by-literal:initialize-var: +22849 # var v/ecx: (payload var) +22850 68/push 0/imm32/register +22851 68/push 0/imm32/register +22852 68/push 0/imm32/no-stack-offset +22853 68/push 1/imm32/block-depth +22854 51/push-ecx +22855 68/push 0x11/imm32/alloc-id:fake +22856 68/push 0/imm32/name +22857 68/push 0/imm32/name +22858 68/push 0x11/imm32/alloc-id:fake:payload +22859 89/<- %ecx 4/r32/esp +22860 $test-shift-reg-by-literal:initialize-var-name: +22861 # v->name = "v" +22862 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +22863 (copy-array Heap "v" %eax) +22864 $test-shift-reg-by-literal:initialize-var-register: +22865 # v->register = "ecx" +22866 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 +22867 (copy-array Heap "ecx" %eax) +22868 $test-shift-reg-by-literal:initialize-literal-type: +22869 # var type/edx: (payload type-tree) = literal +22870 68/push 0/imm32/right:null +22871 68/push 0/imm32/right:null +22872 68/push 0/imm32/left:unused +22873 68/push 0/imm32/value:literal +22874 68/push 1/imm32/is-atom?:true +22875 68/push 0x11/imm32/alloc-id:fake:payload +22876 89/<- %edx 4/r32/esp +22877 $test-shift-reg-by-literal:initialize-literal: +22878 # var l/edx: (payload var) +22879 68/push 0/imm32/register +22880 68/push 0/imm32/register +22881 68/push 0/imm32/no-stack-offset +22882 68/push 1/imm32/block-depth +22883 52/push-edx +22884 68/push 0x11/imm32/alloc-id:fake +22885 68/push 0/imm32/name +22886 68/push 0/imm32/name +22887 68/push 0x11/imm32/alloc-id:fake:payload +22888 89/<- %edx 4/r32/esp +22889 $test-shift-reg-by-literal:initialize-literal-value: +22890 # l->name = "2" +22891 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 +22892 (copy-array Heap "2" %eax) +22893 $test-shift-reg-by-literal:initialize-inouts: +22894 # var inouts/esi: (payload stmt-var) = [l] +22895 68/push 0/imm32/is-deref:false +22896 68/push 0/imm32/next +22897 68/push 0/imm32/next +22898 52/push-edx/l +22899 68/push 0x11/imm32/alloc-id:fake +22900 68/push 0x11/imm32/alloc-id:fake:payload +22901 89/<- %esi 4/r32/esp +22902 $test-shift-reg-by-literal:initialize-outputs: +22903 # var outputs/edi: (payload stmt-var) = [v] +22904 68/push 0/imm32/is-deref:false +22905 68/push 0/imm32/next +22906 68/push 0/imm32/next +22907 51/push-ecx/v +22908 68/push 0x11/imm32/alloc-id:fake +22909 68/push 0x11/imm32/alloc-id:fake:payload +22910 89/<- %edi 4/r32/esp +22911 $test-shift-reg-by-literal:initialize-stmt: +22912 # var stmt/esi: (addr statement) +22913 68/push 0/imm32/next +22914 68/push 0/imm32/next +22915 57/push-edi/outputs +22916 68/push 0x11/imm32/alloc-id:fake +22917 56/push-esi/inouts +22918 68/push 0x11/imm32/alloc-id:fake +22919 68/push 0/imm32/operation +22920 68/push 0/imm32/operation +22921 68/push 1/imm32/tag:stmt1 +22922 89/<- %esi 4/r32/esp +22923 $test-shift-reg-by-literal:initialize-stmt-operation: +22924 # stmt->operation = "shift-left" +22925 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +22926 (copy-array Heap "shift-left" %eax) +22927 # convert +22928 c7 0/subop/copy *Curr-block-depth 0/imm32 +22929 (emit-subx-stmt _test-output-buffered-file %esi Primitives Stderr 0) +22930 (flush _test-output-buffered-file) +22931 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +22937 # check output +22938 (check-next-stream-line-equal _test-output-stream "c1/shift 4/subop/left %ecx 2/imm8" "F - test-shift-reg-by-literal") +22939 # . epilogue +22940 89/<- %esp 5/r32/ebp +22941 5d/pop-to-ebp +22942 c3/return +22943 +22944 test-shift-mem-by-literal: +22945 # shift-left var 3 +22946 # => +22947 # c1/shift 4/subop/left *(ebp+8) 3/imm8 +22948 # +22949 # . prologue +22950 55/push-ebp +22951 89/<- %ebp 4/r32/esp +22952 # setup +22953 (clear-stream _test-output-stream) +22954 (clear-stream $_test-output-buffered-file->buffer) +22955 $test-shift-mem-by-literal:initialize-type: +22956 # var type/ecx: (payload type-tree) = int +22957 68/push 0/imm32/right:null +22958 68/push 0/imm32/right:null +22959 68/push 0/imm32/left:unused +22960 68/push 1/imm32/value:int +22961 68/push 1/imm32/is-atom?:true +22962 68/push 0x11/imm32/alloc-id:fake:payload +22963 89/<- %ecx 4/r32/esp +22964 $test-shift-mem-by-literal:initialize-var1: +22965 # var var1/ecx: (payload var) +22966 68/push 0/imm32/register +22967 68/push 0/imm32/register +22968 68/push 8/imm32/stack-offset +22969 68/push 1/imm32/block-depth +22970 51/push-ecx +22971 68/push 0x11/imm32/alloc-id:fake +22972 68/push 0/imm32/name +22973 68/push 0/imm32/name +22974 68/push 0x11/imm32/alloc-id:fake:payload +22975 89/<- %ecx 4/r32/esp +22976 $test-shift-mem-by-literal:initialize-var1-name: +22977 # var1->name = "var1" +22978 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +22979 (copy-array Heap "var1" %eax) +22980 $test-shift-mem-by-literal:initialize-literal-type: +22981 # var type/edx: (payload type-tree) = literal +22982 68/push 0/imm32/right:null +22983 68/push 0/imm32/right:null +22984 68/push 0/imm32/left:unused +22985 68/push 0/imm32/value:literal +22986 68/push 1/imm32/is-atom?:true +22987 68/push 0x11/imm32/alloc-id:fake:payload +22988 89/<- %edx 4/r32/esp +22989 $test-shift-mem-by-literal:initialize-literal: +22990 # var l/edx: (payload var) +22991 68/push 0/imm32/register +22992 68/push 0/imm32/register +22993 68/push 0/imm32/no-stack-offset +22994 68/push 1/imm32/block-depth +22995 52/push-edx +22996 68/push 0x11/imm32/alloc-id:fake +22997 68/push 0/imm32/name +22998 68/push 0/imm32/name +22999 68/push 0x11/imm32/alloc-id:fake:payload +23000 89/<- %edx 4/r32/esp +23001 $test-shift-mem-by-literal:initialize-literal-value: +23002 # l->name = "3" +23003 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 +23004 (copy-array Heap "3" %eax) +23005 $test-shift-mem-by-literal:initialize-inouts: +23006 # var inouts/esi: (payload stmt-var) = [l] +23007 68/push 0/imm32/is-deref:false +23008 68/push 0/imm32/next +23009 68/push 0/imm32/next +23010 52/push-edx/l +23011 68/push 0x11/imm32/alloc-id:fake +23012 68/push 0x11/imm32/alloc-id:fake:payload +23013 89/<- %esi 4/r32/esp +23014 # var inouts = (handle stmt-var) = [var1, var2] +23015 68/push 0/imm32/is-deref:false +23016 56/push-esi/next +23017 68/push 0x11/imm32/alloc-id:fake +23018 51/push-ecx/var1 +23019 68/push 0x11/imm32/alloc-id:fake +23020 68/push 0x11/imm32/alloc-id:fake:payload +23021 89/<- %esi 4/r32/esp +23022 $test-shift-mem-by-literal:initialize-stmt: +23023 # var stmt/esi: (addr statement) +23024 68/push 0/imm32/next +23025 68/push 0/imm32/next +23026 68/push 0/imm32/outputs +23027 68/push 0/imm32/outputs +23028 56/push-esi/inouts +23029 68/push 0x11/imm32/alloc-id:fake +23030 68/push 0/imm32/operation +23031 68/push 0/imm32/operation +23032 68/push 1/imm32/tag:stmt1 +23033 89/<- %esi 4/r32/esp +23034 $test-shift-mem-by-literal:initialize-stmt-operation: +23035 # stmt->operation = "shift-left" +23036 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +23037 (copy-array Heap "shift-left" %eax) +23038 # convert +23039 c7 0/subop/copy *Curr-block-depth 0/imm32 +23040 (emit-subx-stmt _test-output-buffered-file %esi Primitives Stderr 0) +23041 (flush _test-output-buffered-file) +23042 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +23048 # check output +23049 (check-next-stream-line-equal _test-output-stream "c1/shift 4/subop/left *(ebp+0x00000008) 3/imm8" "F - test-shift-mem-by-literal") +23050 # . epilogue +23051 89/<- %esp 5/r32/ebp +23052 5d/pop-to-ebp +23053 c3/return +23054 +23055 test-compare-reg-with-reg: +23056 # compare var1/ecx, var2/eax +23057 # => +23058 # 39/compare %ecx 0/r32/eax +23059 # +23060 # . prologue +23061 55/push-ebp +23062 89/<- %ebp 4/r32/esp +23063 # setup +23064 (clear-stream _test-output-stream) +23065 (clear-stream $_test-output-buffered-file->buffer) +23066 $test-compare-reg-with-reg:initialize-type: +23067 # var type/ecx: (payload type-tree) = int +23068 68/push 0/imm32/right:null +23069 68/push 0/imm32/right:null +23070 68/push 0/imm32/left:unused +23071 68/push 1/imm32/value:int +23072 68/push 1/imm32/is-atom?:true +23073 68/push 0x11/imm32/alloc-id:fake:payload +23074 89/<- %ecx 4/r32/esp +23075 $test-compare-reg-with-reg:initialize-var1: +23076 # var var1/ecx: (payload var) +23077 68/push 0/imm32/register +23078 68/push 0/imm32/register +23079 68/push 0/imm32/no-stack-offset +23080 68/push 1/imm32/block-depth +23081 51/push-ecx +23082 68/push 0x11/imm32/alloc-id:fake +23083 68/push 0/imm32/name +23084 68/push 0/imm32/name +23085 68/push 0x11/imm32/alloc-id:fake:payload +23086 89/<- %ecx 4/r32/esp +23087 $test-compare-reg-with-reg:initialize-var1-name: +23088 # var1->name = "var1" +23089 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +23090 (copy-array Heap "var1" %eax) +23091 $test-compare-reg-with-reg:initialize-var1-register: +23092 # var1->register = "ecx" +23093 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 +23094 (copy-array Heap "ecx" %eax) +23095 $test-compare-reg-with-reg:initialize-var2: +23096 # var var2/edx: (payload var) +23097 68/push 0/imm32/register +23098 68/push 0/imm32/register +23099 68/push 0/imm32/no-stack-offset +23100 68/push 1/imm32/block-depth +23101 ff 6/subop/push *(ecx+0x10) +23102 68/push 0x11/imm32/alloc-id:fake +23103 68/push 0/imm32/name +23104 68/push 0/imm32/name +23105 68/push 0x11/imm32/alloc-id:fake:payload +23106 89/<- %edx 4/r32/esp +23107 $test-compare-reg-with-reg:initialize-var2-name: +23108 # var2->name = "var2" +23109 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 +23110 (copy-array Heap "var2" %eax) +23111 $test-compare-reg-with-reg:initialize-var2-register: +23112 # var2->register = "eax" +23113 8d/copy-address *(edx+0x1c) 0/r32/eax # Var-register + 4 +23114 (copy-array Heap "eax" %eax) +23115 $test-compare-reg-with-reg:initialize-inouts: +23116 # var inouts/esi: (payload stmt-var) = [var2] +23117 68/push 0/imm32/is-deref:false +23118 68/push 0/imm32/next +23119 68/push 0/imm32/next +23120 52/push-edx/var2 +23121 68/push 0x11/imm32/alloc-id:fake +23122 68/push 0x11/imm32/alloc-id:fake:payload +23123 89/<- %esi 4/r32/esp +23124 # inouts = [var1, var2] +23125 68/push 0/imm32/is-deref:false +23126 56/push-esi/next +23127 68/push 0x11/imm32/alloc-id:fake +23128 51/push-ecx/var1 +23129 68/push 0x11/imm32/alloc-id:fake +23130 68/push 0x11/imm32/alloc-id:fake:payload +23131 89/<- %esi 4/r32/esp +23132 $test-compare-reg-with-reg:initialize-stmt: +23133 # var stmt/esi: (addr statement) +23134 68/push 0/imm32/next +23135 68/push 0/imm32/next +23136 68/push 0/imm32/outputs +23137 68/push 0/imm32/outputs +23138 56/push-esi/inouts +23139 68/push 0x11/imm32/alloc-id:fake +23140 68/push 0/imm32/operation +23141 68/push 0/imm32/operation +23142 68/push 1/imm32/tag:stmt1 +23143 89/<- %esi 4/r32/esp +23144 $test-compare-reg-with-reg:initialize-stmt-operation: +23145 # stmt->operation = "compare" +23146 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +23147 (copy-array Heap "compare" %eax) +23148 # convert +23149 c7 0/subop/copy *Curr-block-depth 0/imm32 +23150 (emit-subx-stmt _test-output-buffered-file %esi Primitives Stderr 0) +23151 (flush _test-output-buffered-file) +23152 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +23158 # check output +23159 (check-next-stream-line-equal _test-output-stream "39/compare-> %ecx 0x00000000/r32" "F - test-compare-reg-with-reg") +23160 # . epilogue +23161 89/<- %esp 5/r32/ebp +23162 5d/pop-to-ebp +23163 c3/return +23164 +23165 test-compare-mem-with-reg: +23166 # compare var1, var2/eax +23167 # => +23168 # 39/compare *(ebp+___) 0/r32/eax +23169 # +23170 # . prologue +23171 55/push-ebp +23172 89/<- %ebp 4/r32/esp +23173 # setup +23174 (clear-stream _test-output-stream) +23175 (clear-stream $_test-output-buffered-file->buffer) +23176 $test-compare-mem-with-reg:initialize-type: +23177 # var type/ecx: (payload type-tree) = int +23178 68/push 0/imm32/right:null +23179 68/push 0/imm32/right:null +23180 68/push 0/imm32/left:unused +23181 68/push 1/imm32/value:int +23182 68/push 1/imm32/is-atom?:true +23183 68/push 0x11/imm32/alloc-id:fake:payload +23184 89/<- %ecx 4/r32/esp +23185 $test-compare-mem-with-reg:initialize-var1: +23186 # var var1/ecx: (payload var) +23187 68/push 0/imm32/register +23188 68/push 0/imm32/register +23189 68/push 8/imm32/stack-offset +23190 68/push 1/imm32/block-depth +23191 51/push-ecx +23192 68/push 0x11/imm32/alloc-id:fake +23193 68/push 0/imm32/name +23194 68/push 0/imm32/name +23195 68/push 0x11/imm32/alloc-id:fake:payload +23196 89/<- %ecx 4/r32/esp +23197 $test-compare-mem-with-reg:initialize-var1-name: +23198 # var1->name = "var1" +23199 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +23200 (copy-array Heap "var1" %eax) +23201 $test-compare-mem-with-reg:initialize-var2: +23202 # var var2/edx: (payload var) +23203 68/push 0/imm32/register +23204 68/push 0/imm32/register +23205 68/push 0/imm32/no-stack-offset +23206 68/push 1/imm32/block-depth +23207 ff 6/subop/push *(ecx+0x10) +23208 68/push 0x11/imm32/alloc-id:fake +23209 68/push 0/imm32/name +23210 68/push 0/imm32/name +23211 68/push 0x11/imm32/alloc-id:fake:payload +23212 89/<- %edx 4/r32/esp +23213 $test-compare-mem-with-reg:initialize-var2-name: +23214 # var2->name = "var2" +23215 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 +23216 (copy-array Heap "var2" %eax) +23217 $test-compare-mem-with-reg:initialize-var2-register: +23218 # var2->register = "eax" +23219 8d/copy-address *(edx+0x1c) 0/r32/eax # Var-register + 4 +23220 (copy-array Heap "eax" %eax) +23221 $test-compare-mem-with-reg:initialize-inouts: +23222 # var inouts/esi: (payload stmt-var) = [var2] +23223 68/push 0/imm32/is-deref:false +23224 68/push 0/imm32/next +23225 68/push 0/imm32/next +23226 52/push-edx/var2 +23227 68/push 0x11/imm32/alloc-id:fake +23228 68/push 0x11/imm32/alloc-id:fake:payload +23229 89/<- %esi 4/r32/esp +23230 # inouts = [var1, var2] +23231 68/push 0/imm32/is-deref:false +23232 56/push-esi/next +23233 68/push 0x11/imm32/alloc-id:fake +23234 51/push-ecx/var1 +23235 68/push 0x11/imm32/alloc-id:fake +23236 68/push 0x11/imm32/alloc-id:fake:payload +23237 89/<- %esi 4/r32/esp +23238 $test-compare-mem-with-reg:initialize-stmt: +23239 # var stmt/esi: (addr statement) +23240 68/push 0/imm32/next +23241 68/push 0/imm32/next +23242 68/push 0/imm32/outputs +23243 68/push 0/imm32/outputs +23244 56/push-esi/inouts +23245 68/push 0x11/imm32/alloc-id:fake +23246 68/push 0/imm32/operation +23247 68/push 0/imm32/operation +23248 68/push 1/imm32/tag:stmt1 +23249 89/<- %esi 4/r32/esp +23250 $test-compare-mem-with-reg:initialize-stmt-operation: +23251 # stmt->operation = "compare" +23252 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +23253 (copy-array Heap "compare" %eax) +23254 # convert +23255 c7 0/subop/copy *Curr-block-depth 0/imm32 +23256 (emit-subx-stmt _test-output-buffered-file %esi Primitives Stderr 0) +23257 (flush _test-output-buffered-file) +23258 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +23264 # check output +23265 (check-next-stream-line-equal _test-output-stream "39/compare-> *(ebp+0x00000008) 0x00000000/r32" "F - test-compare-mem-with-reg") +23266 # . epilogue +23267 89/<- %esp 5/r32/ebp +23268 5d/pop-to-ebp +23269 c3/return +23270 +23271 test-compare-reg-with-mem: +23272 # compare var1/eax, var2 +23273 # => +23274 # 3b/compare<- *(ebp+___) 0/r32/eax +23275 # +23276 # . prologue +23277 55/push-ebp +23278 89/<- %ebp 4/r32/esp +23279 # setup +23280 (clear-stream _test-output-stream) +23281 (clear-stream $_test-output-buffered-file->buffer) +23282 $test-compare-reg-with-mem:initialize-type: +23283 # var type/ecx: (payload type-tree) = int +23284 68/push 0/imm32/right:null +23285 68/push 0/imm32/right:null +23286 68/push 0/imm32/left:unused +23287 68/push 1/imm32/value:int +23288 68/push 1/imm32/is-atom?:true +23289 68/push 0x11/imm32/alloc-id:fake:payload +23290 89/<- %ecx 4/r32/esp +23291 $test-compare-reg-with-mem:initialize-var1: +23292 # var var1/ecx: (payload var) +23293 68/push 0/imm32/register +23294 68/push 0/imm32/register +23295 68/push 0/imm32/no-stack-offset +23296 68/push 1/imm32/block-depth +23297 51/push-ecx +23298 68/push 0x11/imm32/alloc-id:fake +23299 68/push 0/imm32/name +23300 68/push 0/imm32/name +23301 68/push 0x11/imm32/alloc-id:fake:payload +23302 89/<- %ecx 4/r32/esp +23303 $test-compare-reg-with-mem:initialize-var1-name: +23304 # var1->name = "var1" +23305 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +23306 (copy-array Heap "var1" %eax) +23307 $test-compare-reg-with-mem:initialize-var1-register: +23308 # var1->register = "eax" +23309 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 +23310 (copy-array Heap "eax" %eax) +23311 $test-compare-reg-with-mem:initialize-var2: +23312 # var var2/edx: (payload var) +23313 68/push 0/imm32/register +23314 68/push 0/imm32/register +23315 68/push 8/imm32/stack-offset +23316 68/push 1/imm32/block-depth +23317 ff 6/subop/push *(ecx+0x10) +23318 68/push 0x11/imm32/alloc-id:fake +23319 68/push 0/imm32/name +23320 68/push 0/imm32/name +23321 68/push 0x11/imm32/alloc-id:fake:payload +23322 89/<- %edx 4/r32/esp +23323 $test-compare-reg-with-mem:initialize-var2-name: +23324 # var2->name = "var2" +23325 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 +23326 (copy-array Heap "var2" %eax) +23327 $test-compare-reg-with-mem:initialize-inouts: +23328 # var inouts/esi: (payload stmt-var) = [var2] +23329 68/push 0/imm32/is-deref:false +23330 68/push 0/imm32/next +23331 68/push 0/imm32/next +23332 52/push-edx/var2 +23333 68/push 0x11/imm32/alloc-id:fake +23334 68/push 0x11/imm32/alloc-id:fake:payload +23335 89/<- %esi 4/r32/esp +23336 # inouts = [var1, var2] +23337 68/push 0/imm32/is-deref:false +23338 56/push-esi/next +23339 68/push 0x11/imm32/alloc-id:fake +23340 51/push-ecx/var1 +23341 68/push 0x11/imm32/alloc-id:fake +23342 68/push 0x11/imm32/alloc-id:fake:payload +23343 89/<- %esi 4/r32/esp +23344 $test-compare-reg-with-mem:initialize-stmt: +23345 # var stmt/esi: (addr statement) +23346 68/push 0/imm32/next +23347 68/push 0/imm32/next +23348 68/push 0/imm32/outputs +23349 68/push 0/imm32/outputs +23350 56/push-esi/inouts +23351 68/push 0x11/imm32/alloc-id:fake +23352 68/push 0/imm32/operation +23353 68/push 0/imm32/operation +23354 68/push 1/imm32/tag:stmt1 +23355 89/<- %esi 4/r32/esp +23356 $test-compare-reg-with-mem:initialize-stmt-operation: +23357 # stmt->operation = "compare" +23358 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +23359 (copy-array Heap "compare" %eax) +23360 # convert +23361 c7 0/subop/copy *Curr-block-depth 0/imm32 +23362 (emit-subx-stmt _test-output-buffered-file %esi Primitives Stderr 0) +23363 (flush _test-output-buffered-file) +23364 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +23370 # check output +23371 (check-next-stream-line-equal _test-output-stream "3b/compare<- *(ebp+0x00000008) 0x00000000/r32" "F - test-compare-reg-with-mem") +23372 # . epilogue +23373 89/<- %esp 5/r32/ebp +23374 5d/pop-to-ebp +23375 c3/return +23376 +23377 test-compare-mem-with-literal: +23378 # compare var1, 0x34 +23379 # => +23380 # 81 7/subop/compare *(ebp+___) 0x34/imm32 +23381 # +23382 # . prologue +23383 55/push-ebp +23384 89/<- %ebp 4/r32/esp +23385 # setup +23386 (clear-stream _test-output-stream) +23387 (clear-stream $_test-output-buffered-file->buffer) +23388 $test-compare-mem-with-literal:initialize-type: +23389 # var type/ecx: (payload type-tree) = int +23390 68/push 0/imm32/right:null +23391 68/push 0/imm32/right:null +23392 68/push 0/imm32/left:unused +23393 68/push 1/imm32/value:int +23394 68/push 1/imm32/is-atom?:true +23395 68/push 0x11/imm32/alloc-id:fake:payload +23396 89/<- %ecx 4/r32/esp +23397 $test-compare-mem-with-literal:initialize-var1: +23398 # var var1/ecx: (payload var) +23399 68/push 0/imm32/register +23400 68/push 0/imm32/register +23401 68/push 8/imm32/stack-offset +23402 68/push 1/imm32/block-depth +23403 51/push-ecx +23404 68/push 0x11/imm32/alloc-id:fake +23405 68/push 0/imm32/name +23406 68/push 0/imm32/name +23407 68/push 0x11/imm32/alloc-id:fake:payload +23408 89/<- %ecx 4/r32/esp +23409 $test-compare-mem-with-literal:initialize-var1-name: +23410 # var1->name = "var1" +23411 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +23412 (copy-array Heap "var1" %eax) +23413 $test-compare-mem-with-literal:initialize-literal-type: +23414 # var type/edx: (payload type-tree) = literal +23415 68/push 0/imm32/right:null +23416 68/push 0/imm32/right:null +23417 68/push 0/imm32/left:unused +23418 68/push 0/imm32/value:literal +23419 68/push 1/imm32/is-atom?:true +23420 68/push 0x11/imm32/alloc-id:fake:payload +23421 89/<- %edx 4/r32/esp +23422 $test-compare-mem-with-literal:initialize-literal: +23423 # var l/edx: (payload var) +23424 68/push 0/imm32/register +23425 68/push 0/imm32/register +23426 68/push 0/imm32/no-stack-offset +23427 68/push 1/imm32/block-depth +23428 52/push-edx +23429 68/push 0x11/imm32/alloc-id:fake +23430 68/push 0/imm32/name +23431 68/push 0/imm32/name +23432 68/push 0x11/imm32/alloc-id:fake:payload +23433 89/<- %edx 4/r32/esp +23434 $test-compare-mem-with-literal:initialize-literal-value: +23435 # l->name = "0x34" +23436 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 +23437 (copy-array Heap "0x34" %eax) +23438 $test-compare-mem-with-literal:initialize-inouts: +23439 # var inouts/esi: (payload stmt-var) = [l] +23440 68/push 0/imm32/is-deref:false +23441 68/push 0/imm32/next +23442 68/push 0/imm32/next +23443 52/push-edx/l +23444 68/push 0x11/imm32/alloc-id:fake +23445 68/push 0x11/imm32/alloc-id:fake:payload +23446 89/<- %esi 4/r32/esp +23447 # var inouts = (handle stmt-var) = [var1, var2] +23448 68/push 0/imm32/is-deref:false +23449 56/push-esi/next +23450 68/push 0x11/imm32/alloc-id:fake +23451 51/push-ecx/var1 +23452 68/push 0x11/imm32/alloc-id:fake +23453 68/push 0x11/imm32/alloc-id:fake:payload +23454 89/<- %esi 4/r32/esp +23455 $test-compare-mem-with-literal:initialize-stmt: +23456 # var stmt/esi: (addr statement) +23457 68/push 0/imm32/next +23458 68/push 0/imm32/next +23459 68/push 0/imm32/outputs +23460 68/push 0/imm32/outputs +23461 56/push-esi/inouts +23462 68/push 0x11/imm32/alloc-id:fake +23463 68/push 0/imm32/operation +23464 68/push 0/imm32/operation +23465 68/push 1/imm32/tag:stmt1 +23466 89/<- %esi 4/r32/esp +23467 $test-compare-mem-with-literal:initialize-stmt-operation: +23468 # stmt->operation = "compare" +23469 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +23470 (copy-array Heap "compare" %eax) +23471 # convert +23472 c7 0/subop/copy *Curr-block-depth 0/imm32 +23473 (emit-subx-stmt _test-output-buffered-file %esi Primitives Stderr 0) +23474 (flush _test-output-buffered-file) +23475 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +23481 # check output +23482 (check-next-stream-line-equal _test-output-stream "81 7/subop/compare *(ebp+0x00000008) 0x34/imm32" "F - test-compare-mem-with-literal") +23483 # . epilogue +23484 89/<- %esp 5/r32/ebp +23485 5d/pop-to-ebp +23486 c3/return +23487 +23488 test-compare-eax-with-literal: +23489 # compare var1/eax 0x34 +23490 # => +23491 # 3d/compare-eax-with 0x34/imm32 +23492 # +23493 # . prologue +23494 55/push-ebp +23495 89/<- %ebp 4/r32/esp +23496 # setup +23497 (clear-stream _test-output-stream) +23498 (clear-stream $_test-output-buffered-file->buffer) +23499 $test-compare-eax-with-literal:initialize-type: +23500 # var type/ecx: (payload type-tree) = int +23501 68/push 0/imm32/right:null +23502 68/push 0/imm32/right:null +23503 68/push 0/imm32/left:unused +23504 68/push 1/imm32/value:int +23505 68/push 1/imm32/is-atom?:true +23506 68/push 0x11/imm32/alloc-id:fake:payload +23507 89/<- %ecx 4/r32/esp +23508 $test-compare-eax-with-literal:initialize-var1: +23509 # var var1/ecx: (payload var) +23510 68/push 0/imm32/register +23511 68/push 0/imm32/register +23512 68/push 0/imm32/no-stack-offset +23513 68/push 1/imm32/block-depth +23514 51/push-ecx +23515 68/push 0x11/imm32/alloc-id:fake +23516 68/push 0/imm32/name +23517 68/push 0/imm32/name +23518 68/push 0x11/imm32/alloc-id:fake:payload +23519 89/<- %ecx 4/r32/esp +23520 $test-compare-eax-with-literal:initialize-var1-name: +23521 # var1->name = "var1" +23522 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +23523 (copy-array Heap "var1" %eax) +23524 $test-compare-eax-with-literal:initialize-var1-register: +23525 # v->register = "eax" +23526 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 +23527 (copy-array Heap "eax" %eax) +23528 $test-compare-eax-with-literal:initialize-literal-type: +23529 # var type/edx: (payload type-tree) = literal +23530 68/push 0/imm32/right:null +23531 68/push 0/imm32/right:null +23532 68/push 0/imm32/left:unused +23533 68/push 0/imm32/value:literal +23534 68/push 1/imm32/is-atom?:true +23535 68/push 0x11/imm32/alloc-id:fake:payload +23536 89/<- %edx 4/r32/esp +23537 $test-compare-eax-with-literal:initialize-literal: +23538 # var l/edx: (payload var) +23539 68/push 0/imm32/register +23540 68/push 0/imm32/register +23541 68/push 0/imm32/no-stack-offset +23542 68/push 1/imm32/block-depth +23543 52/push-edx +23544 68/push 0x11/imm32/alloc-id:fake +23545 68/push 0/imm32/name +23546 68/push 0/imm32/name +23547 68/push 0x11/imm32/alloc-id:fake:payload +23548 89/<- %edx 4/r32/esp +23549 $test-compare-eax-with-literal:initialize-literal-value: +23550 # l->name = "0x34" +23551 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 +23552 (copy-array Heap "0x34" %eax) +23553 $test-compare-eax-with-literal:initialize-inouts: +23554 # var inouts/esi: (payload stmt-var) = [l] +23555 68/push 0/imm32/is-deref:false +23556 68/push 0/imm32/next +23557 68/push 0/imm32/next +23558 52/push-edx/l +23559 68/push 0x11/imm32/alloc-id:fake +23560 68/push 0x11/imm32/alloc-id:fake:payload +23561 89/<- %esi 4/r32/esp +23562 # var inouts = (handle stmt-var) = [var1, var2] +23563 68/push 0/imm32/is-deref:false +23564 56/push-esi/next +23565 68/push 0x11/imm32/alloc-id:fake +23566 51/push-ecx/var1 +23567 68/push 0x11/imm32/alloc-id:fake +23568 68/push 0x11/imm32/alloc-id:fake:payload +23569 89/<- %esi 4/r32/esp +23570 $test-compare-eax-with-literal:initialize-stmt: +23571 # var stmt/esi: (addr statement) +23572 68/push 0/imm32/next +23573 68/push 0/imm32/next +23574 68/push 0/imm32/outputs +23575 68/push 0/imm32/outputs +23576 56/push-esi/inouts +23577 68/push 0x11/imm32/alloc-id:fake +23578 68/push 0/imm32/operation +23579 68/push 0/imm32/operation +23580 68/push 1/imm32/tag:stmt1 +23581 89/<- %esi 4/r32/esp +23582 $test-compare-eax-with-literal:initialize-stmt-operation: +23583 # stmt->operation = "compare" +23584 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +23585 (copy-array Heap "compare" %eax) +23586 # convert +23587 c7 0/subop/copy *Curr-block-depth 0/imm32 +23588 (emit-subx-stmt _test-output-buffered-file %esi Primitives Stderr 0) +23589 (flush _test-output-buffered-file) +23590 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +23596 # check output +23597 (check-next-stream-line-equal _test-output-stream "3d/compare-eax-with 0x34/imm32" "F - test-compare-eax-with-literal") +23598 # . epilogue +23599 89/<- %esp 5/r32/ebp +23600 5d/pop-to-ebp +23601 c3/return +23602 +23603 test-compare-reg-with-literal: +23604 # compare var1/ecx 0x34 +23605 # => +23606 # 81 7/subop/compare %ecx 0x34/imm32 +23607 # +23608 # . prologue +23609 55/push-ebp +23610 89/<- %ebp 4/r32/esp +23611 # setup +23612 (clear-stream _test-output-stream) +23613 (clear-stream $_test-output-buffered-file->buffer) +23614 $test-compare-reg-with-literal:initialize-type: +23615 # var type/ecx: (payload type-tree) = int +23616 68/push 0/imm32/right:null +23617 68/push 0/imm32/right:null +23618 68/push 0/imm32/left:unused +23619 68/push 1/imm32/value:int +23620 68/push 1/imm32/is-atom?:true +23621 68/push 0x11/imm32/alloc-id:fake:payload +23622 89/<- %ecx 4/r32/esp +23623 $test-compare-reg-with-literal:initialize-var1: +23624 # var var1/ecx: (payload var) +23625 68/push 0/imm32/register +23626 68/push 0/imm32/register +23627 68/push 0/imm32/no-stack-offset +23628 68/push 1/imm32/block-depth +23629 51/push-ecx +23630 68/push 0x11/imm32/alloc-id:fake +23631 68/push 0/imm32/name +23632 68/push 0/imm32/name +23633 68/push 0x11/imm32/alloc-id:fake:payload +23634 89/<- %ecx 4/r32/esp +23635 $test-compare-reg-with-literal:initialize-var1-name: +23636 # var1->name = "var1" +23637 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +23638 (copy-array Heap "var1" %eax) +23639 $test-compare-reg-with-literal:initialize-var1-register: +23640 # v->register = "ecx" +23641 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 +23642 (copy-array Heap "ecx" %eax) +23643 $test-compare-reg-with-literal:initialize-literal-type: +23644 # var type/edx: (payload type-tree) = literal +23645 68/push 0/imm32/right:null +23646 68/push 0/imm32/right:null +23647 68/push 0/imm32/left:unused +23648 68/push 0/imm32/value:literal +23649 68/push 1/imm32/is-atom?:true +23650 68/push 0x11/imm32/alloc-id:fake:payload +23651 89/<- %edx 4/r32/esp +23652 $test-compare-reg-with-literal:initialize-literal: +23653 # var l/edx: (payload var) +23654 68/push 0/imm32/register +23655 68/push 0/imm32/register +23656 68/push 0/imm32/no-stack-offset +23657 68/push 1/imm32/block-depth +23658 52/push-edx +23659 68/push 0x11/imm32/alloc-id:fake +23660 68/push 0/imm32/name +23661 68/push 0/imm32/name +23662 68/push 0x11/imm32/alloc-id:fake:payload +23663 89/<- %edx 4/r32/esp +23664 $test-compare-reg-with-literal:initialize-literal-value: +23665 # l->name = "0x34" +23666 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 +23667 (copy-array Heap "0x34" %eax) +23668 $test-compare-reg-with-literal:initialize-inouts: +23669 # var inouts/esi: (payload stmt-var) = [l] +23670 68/push 0/imm32/is-deref:false +23671 68/push 0/imm32/next +23672 68/push 0/imm32/next +23673 52/push-edx/l +23674 68/push 0x11/imm32/alloc-id:fake +23675 68/push 0x11/imm32/alloc-id:fake:payload +23676 89/<- %esi 4/r32/esp +23677 # var inouts = (handle stmt-var) = [var1, var2] +23678 68/push 0/imm32/is-deref:false +23679 56/push-esi/next +23680 68/push 0x11/imm32/alloc-id:fake +23681 51/push-ecx/var1 +23682 68/push 0x11/imm32/alloc-id:fake +23683 68/push 0x11/imm32/alloc-id:fake:payload +23684 89/<- %esi 4/r32/esp +23685 $test-compare-reg-with-literal:initialize-stmt: +23686 # var stmt/esi: (addr statement) +23687 68/push 0/imm32/next +23688 68/push 0/imm32/next +23689 68/push 0/imm32/outputs +23690 68/push 0/imm32/outputs +23691 56/push-esi/inouts +23692 68/push 0x11/imm32/alloc-id:fake +23693 68/push 0/imm32/operation +23694 68/push 0/imm32/operation +23695 68/push 1/imm32/tag:stmt1 +23696 89/<- %esi 4/r32/esp +23697 $test-compare-reg-with-literal:initialize-stmt-operation: +23698 # stmt->operation = "compare" +23699 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +23700 (copy-array Heap "compare" %eax) +23701 # convert +23702 c7 0/subop/copy *Curr-block-depth 0/imm32 +23703 (emit-subx-stmt _test-output-buffered-file %esi Primitives Stderr 0) +23704 (flush _test-output-buffered-file) +23705 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +23711 # check output +23712 (check-next-stream-line-equal _test-output-stream "81 7/subop/compare %ecx 0x34/imm32" "F - test-compare-reg-with-literal") +23713 # . epilogue +23714 89/<- %esp 5/r32/ebp +23715 5d/pop-to-ebp +23716 c3/return +23717 +23718 test-emit-subx-stmt-function-call: +23719 # Call a function on a variable on the stack. +23720 # f foo +23721 # => +23722 # (f *(ebp-8)) +23723 # (Changing the function name supports overloading in general, but here it +23724 # just serves to help disambiguate things.) +23725 # +23726 # There's a variable on the var stack as follows: +23727 # name: 'foo' +23728 # type: int +23729 # stack-offset: -8 +23730 # +23731 # There's nothing in primitives. +23732 # +23733 # We don't perform any checking here on the type of 'f'. +23734 # +23735 # . prologue +23736 55/push-ebp +23737 89/<- %ebp 4/r32/esp +23738 # setup +23739 (clear-stream _test-output-stream) +23740 (clear-stream $_test-output-buffered-file->buffer) +23741 $test-emit-subx-function-call:initialize-type: +23742 # var type/ecx: (payload type-tree) = int +23743 68/push 0/imm32/right:null +23744 68/push 0/imm32/right:null +23745 68/push 0/imm32/left:unused +23746 68/push 1/imm32/value:int +23747 68/push 1/imm32/is-atom?:true +23748 68/push 0x11/imm32/alloc-id:fake:payload +23749 89/<- %ecx 4/r32/esp +23750 $test-emit-subx-function-call:initialize-var: +23751 # var var-foo/ecx: (payload var) = var(type) +23752 68/push 0/imm32/no-register +23753 68/push 0/imm32/no-register +23754 68/push -8/imm32/stack-offset +23755 68/push 1/imm32/block-depth +23756 51/push-ecx/type +23757 68/push 0x11/imm32/alloc-id:fake +23758 68/push 0/imm32/name +23759 68/push 0/imm32/name +23760 68/push 0x11/imm32/alloc-id:fake:payload +23761 89/<- %ecx 4/r32/esp +23762 $test-emit-subx-function-call:initialize-var-name: +23763 # var-foo->name = "foo" +23764 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +23765 (copy-array Heap "foo" %eax) +23766 $test-emit-subx-function-call:initialize-stmt-var: +23767 # var operand/ebx: (payload stmt-var) = stmt-var(var-foo) +23768 68/push 0/imm32/is-deref:false +23769 68/push 0/imm32/next +23770 68/push 0/imm32/next +23771 51/push-ecx/var-foo +23772 68/push 0x11/imm32/alloc-id:fake +23773 68/push 0x11/imm32/alloc-id:fake:payload +23774 89/<- %ebx 4/r32/esp +23775 $test-emit-subx-function-call:initialize-stmt: +23776 # var stmt/esi: (addr statement) +23777 68/push 0/imm32/no-outputs +23778 68/push 0/imm32/no-outputs +23779 53/push-ebx/inouts +23780 68/push 0x11/imm32/alloc-id:fake +23781 68/push 0/imm32/operation +23782 68/push 0/imm32/operation +23783 68/push 1/imm32/tag +23784 89/<- %esi 4/r32/esp +23785 $test-emit-subx-function-call:initialize-stmt-operation: +23786 # stmt->operation = "f" +23787 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +23788 (copy-array Heap "f" %eax) +23789 # convert +23790 c7 0/subop/copy *Curr-block-depth 0/imm32 +23791 (emit-subx-stmt _test-output-buffered-file %esi 0 Stderr 0) +23792 (flush _test-output-buffered-file) +23793 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +23799 # check output +23800 (check-next-stream-line-equal _test-output-stream "(f *(ebp+0xfffffff8))" "F - test-emit-subx-stmt-function-call") +23801 # . epilogue +23802 89/<- %esp 5/r32/ebp +23803 5d/pop-to-ebp +23804 c3/return +23805 +23806 test-emit-subx-stmt-function-call-with-literal-arg: +23807 # Call a function on a literal. +23808 # f 0x34 +23809 # => +23810 # (f2 0x34) +23811 # +23812 # . prologue +23813 55/push-ebp +23814 89/<- %ebp 4/r32/esp +23815 # setup +23816 (clear-stream _test-output-stream) +23817 (clear-stream $_test-output-buffered-file->buffer) +23818 $test-emit-subx-function-call-with-literal-arg:initialize-type: +23819 # var type/ecx: (payload type-tree) = int +23820 68/push 0/imm32/right:null +23821 68/push 0/imm32/right:null +23822 68/push 0/imm32/left:unused +23823 68/push 0/imm32/value:literal +23824 68/push 1/imm32/is-atom?:true +23825 68/push 0x11/imm32/alloc-id:fake:payload +23826 89/<- %ecx 4/r32/esp +23827 $test-emit-subx-function-call-with-literal-arg:initialize-var: +23828 # var var-foo/ecx: (payload var) = var(lit) +23829 68/push 0/imm32/no-register +23830 68/push 0/imm32/no-register +23831 68/push 0/imm32/no-stack-offset +23832 68/push 1/imm32/block-depth +23833 51/push-ecx/type +23834 68/push 0x11/imm32/alloc-id:fake +23835 68/push 0/imm32/name +23836 68/push 0/imm32/name +23837 68/push 0x11/imm32/alloc-id:fake:payload +23838 89/<- %ecx 4/r32/esp +23839 $test-emit-subx-function-call-with-literal-arg:initialize-var-name: +23840 # var-foo->name = "0x34" +23841 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +23842 (copy-array Heap "0x34" %eax) +23843 $test-emit-subx-function-call-with-literal-arg:initialize-stmt-var: +23844 # var operand/ebx: (payload stmt-var) = stmt-var(var-foo) +23845 68/push 0/imm32/is-deref:false +23846 68/push 0/imm32/next +23847 68/push 0/imm32/next +23848 51/push-ecx/var-foo +23849 68/push 0x11/imm32/alloc-id:fake +23850 68/push 0x11/imm32/alloc-id:fake:payload +23851 89/<- %ebx 4/r32/esp +23852 $test-emit-subx-function-call-with-literal-arg:initialize-stmt: +23853 # var stmt/esi: (addr statement) +23854 68/push 0/imm32/no-outputs +23855 68/push 0/imm32/no-outputs +23856 53/push-ebx/inouts +23857 68/push 0x11/imm32/alloc-id:fake +23858 68/push 0/imm32/operation +23859 68/push 0/imm32/operation +23860 68/push 1/imm32/tag +23861 89/<- %esi 4/r32/esp +23862 $test-emit-subx-function-call-with-literal-arg:initialize-stmt-operation: +23863 # stmt->operation = "f" +23864 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +23865 (copy-array Heap "f" %eax) +23866 # convert +23867 c7 0/subop/copy *Curr-block-depth 0/imm32 +23868 (emit-subx-stmt _test-output-buffered-file %esi 0 %ebx Stderr 0) +23869 (flush _test-output-buffered-file) +23870 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +23876 # check output +23877 (check-next-stream-line-equal _test-output-stream "(f 0x34)" "F - test-emit-subx-stmt-function-call-with-literal-arg") +23878 # . epilogue +23879 89/<- %esp 5/r32/ebp +23880 5d/pop-to-ebp +23881 c3/return +23882 +23883 emit-indent: # out: (addr buffered-file), n: int +23884 # . prologue +23885 55/push-ebp +23886 89/<- %ebp 4/r32/esp +23887 # . save registers +23888 50/push-eax +23889 # var i/eax: int = n +23890 8b/-> *(ebp+0xc) 0/r32/eax +23891 { +23892 # if (i <= 0) break +23893 3d/compare-eax-with 0/imm32 +23894 7e/jump-if-<= break/disp8 +23895 (write-buffered *(ebp+8) " ") +23896 48/decrement-eax +23897 eb/jump loop/disp8 +23898 } +23899 $emit-indent:end: +23900 # . restore registers +23901 58/pop-to-eax +23902 # . epilogue +23903 89/<- %esp 5/r32/ebp +23904 5d/pop-to-ebp +23905 c3/return +23906 +23907 emit-subx-prologue: # out: (addr buffered-file) +23908 # . prologue +23909 55/push-ebp +23910 89/<- %ebp 4/r32/esp +23911 # +23912 (write-buffered *(ebp+8) " # . prologue\n") +23913 (write-buffered *(ebp+8) " 55/push-ebp\n") +23914 (write-buffered *(ebp+8) " 89/<- %ebp 4/r32/esp\n") +23915 $emit-subx-prologue:end: +23916 # . epilogue +23917 89/<- %esp 5/r32/ebp +23918 5d/pop-to-ebp +23919 c3/return +23920 +23921 emit-subx-epilogue: # out: (addr buffered-file) +23922 # . prologue +23923 55/push-ebp +23924 89/<- %ebp 4/r32/esp +23925 # +23926 (write-buffered *(ebp+8) " # . epilogue\n") +23927 (write-buffered *(ebp+8) " 89/<- %esp 5/r32/ebp\n") +23928 (write-buffered *(ebp+8) " 5d/pop-to-ebp\n") +23929 (write-buffered *(ebp+8) " c3/return\n") +23930 $emit-subx-epilogue:end: +23931 # . epilogue +23932 89/<- %esp 5/r32/ebp +23933 5d/pop-to-ebp +23934 c3/return diff --git a/html/apps/parse-int.mu.html b/html/apps/parse-int.mu.html index 040b0d1e..be99f967 100644 --- a/html/apps/parse-int.mu.html +++ b/html/apps/parse-int.mu.html @@ -64,10 +64,10 @@ if ('onhashchange' in window) { 6 # $ echo $? 7 # 123 8 - 9 fn main _args: (addr array (addr array byte)) -> exit-status/ebx: int { + 9 fn main _args: (addr array addr array byte) -> exit-status/ebx: int { 10 $main-body: { 11 # if no args, print a message and exit -12 var args/esi: (addr array (addr array byte)) <- copy _args +12 var args/esi: (addr array addr array byte) <- copy _args 13 var n/ecx: int <- length args 14 compare n, 1 15 { diff --git a/html/apps/print-file.mu.html b/html/apps/print-file.mu.html index 0995e3c1..fe3e9676 100644 --- a/html/apps/print-file.mu.html +++ b/html/apps/print-file.mu.html @@ -65,8 +65,8 @@ if ('onhashchange' in window) { 7 # $ ./a.elf x 8 # abc 9 -10 fn main _args: (addr array (addr array byte)) -> exit-status/ebx: int { -11 var args/eax: (addr array (addr array byte)) <- copy _args +10 fn main _args: (addr array addr array byte) -> exit-status/ebx: int { +11 var args/eax: (addr array addr array byte) <- copy _args 12 $main-body: { 13 var n/ecx: int <- length args 14 compare n, 1 @@ -89,13 +89,14 @@ if ('onhashchange' in window) { 31 var c/eax: byte <- read-byte-buffered in-addr 32 compare c, 0xffffffff # EOF marker 33 break-if-= -34 print-grapheme 0, c -35 loop -36 } -37 } -38 } -39 exit-status <- copy 0 -40 } +34 var g/eax: grapheme <- copy c +35 print-grapheme 0, g +36 loop +37 } +38 } +39 } +40 exit-status <- copy 0 +41 } diff --git a/html/apps/subx-params.subx.html b/html/apps/subx-params.subx.html index 2667f8db..3153ba29 100644 --- a/html/apps/subx-params.subx.html +++ b/html/apps/subx-params.subx.html @@ -66,7 +66,7 @@ if ('onhashchange' in window) { 12 13 # number of labels we can translate to addresses 14 Max-labels: -15 0x30000/imm32/24K-labels/192KB +15 0x60000/imm32/24K-labels/192KB 16 17 # capacity of trace-stream 18 Trace-size: diff --git a/html/mu-init.subx.html b/html/mu-init.subx.html index 231ff08d..dc0c5ec7 100644 --- a/html/mu-init.subx.html +++ b/html/mu-init.subx.html @@ -59,7 +59,7 @@ if ('onhashchange' in window) { 3 # See translate_mu for how this file is used. 4 # 5 # Mu programs start at a function called 'main' with this signature: - 6 # fn main args: (addr array (addr array byte)) -> exit-status/ebx: int + 6 # fn main args: (addr array addr array byte) -> exit-status/ebx: int 7 # If your program doesn't need commandline arguments you can drop it: 8 # fn main -> exit-status/ebx: int 9 #