000 // memlib - simple memory allocator for ILOC 001 // 002 // This library maintains a single-linked list (of monotonically increasing addresses) of free 003 // slots in memory and a reference count for occupied slots. Each slot contains a tuple `(next 004 // free slot address,size)` followed by `size` free bytes. The memory is initiliased with a 005 // pointer to the first free slot at `#fst_ptr` and one free slot at `#slot1` of size 006 // `brk-slot1-header`. When a piece of memory is requested for allocation, a tuple 007 // `(reference count, size)` followed by `size` bytes for the object is formed. The calling 008 // convention of the functions in this library consists of pushing the return address followed by 009 // any arguments (in order) to the stack. Any return values will be pushed to the stack likewise. 010 // 011 // Requires a register `brk` for the highest address available for heap allocation. 012 // Requires an instruction `halt` when memory runs out 013 // 014 // @author Frank Wibbelink 015 // initialise 016 memlib_: loadI 0 => m_0 017 loadI @slot1 => m_1 018 subI brk,@slot1 => m_2 019 subI m_2,@header => m_2 020 storeAI m_1 => m_0,@fst_ptr // pointer to first slot 021 storeAI m_0 => m_1,@off_next // next slot is null 022 storeAI m_2 => m_1,@off_size // first slot size 023 jumpI -> ememlib_ 024 // allocate memory 025 // searches through the free slots for either a slot size of ~~exactly #4+8 or a size of~~ at 026 // least #4+16 027 // stack: [return address, object size] -> [object address] 028 memalloc: loadI 0 => m_0 029 pop => m_s // load size 030 loadI @fst_ptr => m_p // load previous address (base pointer) 031 loadAI m_p,@off_next => m_c // load current address (first slot) 032 ma_loop: cmp_EQ m_0,m_c => m_1 // check if address pointer is null 033 cbr m_1 -> ma_null,ma_cont // if null, go to end and return null pointer 034 ma_cont: loadAI m_c,@off_size => m_1 // load slot size 035 cmp_EQ m_1,m_s => m_2 // check if request fits exactly 036 cbr m_2 -> ma_yxct,ma_nxct 037 ma_nxct: subI m_1,@header => m_1 // subtract free slot size 038 cmp_GE m_1,m_s => m_1 // check if request fits 039 cbr m_1 -> ma_found,ma_next 040 ma_next: i2i m_c => m_p 041 loadAI m_p,@off_next => m_c 042 jumpI -> ma_loop 043 ma_yxct: loadAI m_c,@off_next => m_n // location of next free slot 044 jumpI -> ma_final 045 ma_found: addI m_s,@header => m_1 046 add m_1,m_c => m_n // location of new free slot 047 loadAI m_c,@off_size => m_1 048 subI m_1,@header => m_1 049 sub m_1,m_s => m_1 // size of new free slot 050 storeAI m_1 => m_n,@off_size 051 loadAI m_c,@off_next => m_1 // location of next free slot 052 storeAI m_1 => m_n,@off_next 053 ma_final: storeAI m_n => m_p,@off_next // link previous free slot to new 054 addI m_c,@header => m_c // move to object location 055 loadI 1 => m_1 056 storeAI m_1 => m_c,@off_oref // set reference count to 1 057 storeAI m_s => m_c,@off_osize // set object size 058 ma_null: pop => m_1 // load return address 059 push m_c // store object address 060 jump -> m_1 061 // increase reference count of object 062 // stack: [return address, object address] -> [] 063 memaddref: loadI 0 => m_0 064 pop => m_n // load object address 065 cmp_EQ m_0,m_n => m_1 066 cbr m_1 -> mr_ynul,mr_nnul // check if null pointer 067 mr_ynul: haltI 1865445997 068 mr_nnul: loadAI m_n,@off_oref => m_1 069 addI m_1,1 => m_1 070 storeAI m_1 => m_n,@off_oref 071 pop => m_1 // load return address 072 jump -> m_1 073 // decrease reference count of object 074 // frees memory if count goes to zero 075 // stack: [return address, object address] -> [] 076 memfree: loadI 0 => m_0 077 pop => m_n // load object address 078 cmp_EQ m_0,m_n => m_1 079 cbr m_1 -> mf_ynul,mf_nnul // check if null pointer 080 mf_ynul: haltI 1865442925 081 mf_nnul: loadAI m_n,@off_oref => m_1 082 subI m_1,1 => m_1 083 cmp_GT m_1,m_0 => m_2 084 cbr m_2 -> mf_exit,mf_free 085 mf_exit: storeAI m_1 => m_n,@off_oref 086 pop => m_1 // load return address 087 jump -> m_1 088 mf_free: subI m_n,@header => m_n 089 loadI @fst_ptr => m_p 090 loadAI m_p,@off_next => m_c 091 mf_loop: cmp_EQ m_0,m_c => m_1 // loop until the surrounding free blocks are found 092 cbr m_1 -> mf_halt,mf_cont // check if address pointer is null 093 mf_halt: haltI 1882220141 // halt program; object beyond last free slot (or memory corrupted) 094 mf_cont: cmp_EQ m_c,m_n => m_1 095 cbr m_1 -> mf_hal2,mf_con2 096 mf_hal2: haltI 1717855853 // halt program; object is free slot 097 mf_con2: cmp_LE m_c,m_n => m_1 098 cbr m_1 -> mf_next,mf_done 099 mf_next: i2i m_c => m_p 100 loadAI m_p,@off_next => m_c 101 jumpI -> mf_loop 102 mf_done: loadAI m_p,@off_size => m_1 103 addI m_1,@header => m_1 104 add m_1,m_p => m_2 105 cmp_EQ m_2,m_n => m_2 106 cbr m_2 -> mf_yprv,mf_nprv 107 mf_yprv: loadAI m_n,@off_size => m_2 // merge with previous free slot 108 add m_1,m_2 => m_1 // new size of previous free slot 109 storeAI m_1 => m_p,@off_size 110 i2i m_p => m_n 111 jumpI -> mf_dprv 112 mf_nprv: storeAI m_n => m_p,@off_next // link previous free slot with new 113 mf_dprv: loadAI m_n,@off_size => m_1 114 addI m_1,@header => m_1 115 add m_1,m_n => m_2 116 cmp_EQ m_2,m_c => m_2 117 cbr m_2 -> mf_ynxt,mf_nnxt 118 mf_ynxt: loadAI m_c,@off_size => m_2 // merge with next free slot 119 add m_1,m_2 => m_1 // new size of next free slot 120 storeAI m_1 => m_n,@off_size 121 loadAI m_c,@off_next => m_1 122 storeAI m_1 => m_n,@off_next // move link of next's next to new free slot 123 pop => m_1 // load return address 124 jump -> m_1 125 mf_nnxt: storeAI m_c => m_n,@off_next // link new free slot with next 126 pop => m_1 // load return address 127 jump -> m_1 128 // copy object to location 129 // stack: [return address, object address, destination] -> [] 130 memcopy: loadI 0 => m_0 131 haltI 1835626101 // unimplemented 132 pop => m_1 // load return address 133 jump -> m_1 134 ememlib_: nop 135 // end of memlib 136 // stdlib - generic subroutines for ILOC 137 // 138 // This library contains a few common subroutines for Boppi. 139 // 140 // @author Frank Wibbelink 141 // initialise 142 stdlib_: jumpI -> estdlib_ 143 // write a boolean to output 144 // stack: [return address, bool] -> [] 145 stdbout: pop => m_1 // get boolean 146 loadI 0 => m_2 // load zero-length string 147 push m_2 148 cbr m_1 -> sbout_t,sbout_f 149 sbout_t: cout "true" 150 jumpI -> sbout_e 151 sbout_f: cout "false" 152 sbout_e: pop => m_1 // load return address 153 jump -> m_1 154 // read a character from input 155 // stack: [return address] -> [char] 156 stdcin: cin "" // get line 157 pop => m_1 // get length 158 cbr m_1 -> scin_t,stdcin // repeat until at least one character 159 scin_t: cpop => m_2 // save character 160 scin_lc: subI m_1,1 => m_1 // decrement char count 161 cbr m_1 -> scin_ll,scin_le 162 scin_ll: cpop => m_0 // discard character 163 jumpI -> scin_lc // repeat 164 scin_le: loadI 0 => m_0 // reset zero register 165 pop => m_1 // get return address 166 cpush m_2 // push result character 167 jump -> m_1 168 estdlib_: nop 169 // end of stdlib 170 loadI 0 => r_nul // initialise zero register 171 loadI 176 => r_arp // malloc 172 push r_arp // malloc 173 loadI 28 => r_arp // malloc 174 push r_arp // malloc 175 jumpI -> memalloc // malloc 176 pop => r_arp // malloc 177 addI r_arp,16 => r_arp // construct main AR 178 jumpI -> s0 // define memoizedFib - jump over body 179 nop // define memoizedFib - entry point 180 loadI 50 => r_1 // 50 181 multI r_1,4 => r_1 // produce array size 182 cmp_GE r_1,r_nul => r_2 // check size non negative 183 cbr r_2 -> aszt1,aszf2 // 184 aszf2: haltI 1634628474 // invalid array size 185 aszt1: nop // valid array size 186 loadI 190 => r_2 // malloc 187 push r_2 // malloc 188 push r_1 // malloc 189 jumpI -> memalloc // malloc 190 pop => r_2 // malloc 191 addI r_arp,0 => r_1 // add offset 192 load r_1 => r_3 // load reference 193 cmp_EQ r_3,r_nul => r_4 // remove old reference 194 cbr r_4 -> ynul3,nnul4 // remove old reference 195 nnul4: nop // remove old reference 196 loadI 200 => r_4 // free 197 push r_4 // free 198 push r_3 // free 199 jumpI -> memfree // free 200 ynul3: nop // remove old reference 201 store r_2 => r_1 // to memo 202 load r_1 => r_3 // load reference 203 loadI 207 => r_5 // memaddref 204 push r_5 // memaddref 205 push r_3 // memaddref 206 jumpI -> memaddref // memaddref 207 cmp_EQ r_2,r_nul => r_3 // remove old reference 208 cbr r_3 -> ynul5,nnul6 // remove old reference 209 nnul6: nop // remove old reference 210 loadI 214 => r_3 // free 211 push r_3 // free 212 push r_2 // free 213 jumpI -> memfree // free 214 ynul5: nop // remove old reference 215 jumpI -> s7 // define fib - jump over body 216 nop // define fib - entry point 217 addI r_arp,0 => r_1 // add offset 218 load r_1 => r_1 // load address 219 loadI 1 => r_3 // 1 220 cmp_LT r_1,r_3 => r_1 // < 221 addI r_arp,0 => r_2 // add offset 222 load r_2 => r_2 // load address 223 loadI 46 => r_5 // 46 224 cmp_GT r_2,r_5 => r_2 // > 225 or r_1,r_2 => r_1 // || 226 cbr r_1 -> if_t8,if_f9 // 227 if_t8: nop // 228 loadI 0 => r_2 // 0 229 i2i r_2 => r_5 // result 230 jumpI -> if_e10 // 231 if_f9: nop // 232 addI r_arp,0 => r_1 // add offset 233 load r_1 => r_1 // load address 234 loadI 2 => r_3 // 2 235 cmp_LT r_1,r_3 => r_1 // < 236 cbr r_1 -> if_t11,if_f12 // 237 if_t11: nop // 238 loadI 1 => r_2 // 1 239 i2i r_2 => r_3 // result 240 jumpI -> if_e13 // 241 if_f12: nop // 242 i2i r_arp => ART // travelling ALs 243 loadAI ART,-16 => ART // \ 244 addI ART,0 => r_1 // add offset 245 load r_1 => r_1 // get array object 246 addI r_arp,0 => r_2 // add offset 247 load r_2 => r_2 // load address 248 loadAI r_1,-4 => r_6 // check array index 249 divI r_6,4 => r_6 // check array index 250 cmp_LT r_2,r_6 => r_6 // check array index 251 cmp_GE r_2,r_nul => r_4 // check array index 252 and r_6,r_4 => r_4 // check array index 253 cbr r_4 -> nob18,oob17 // check array index 254 oob17: haltI 1634692962 // array index out of bounds 255 nob18: multI r_2,4 => r_2 // multiply index by size 256 add r_1,r_2 => r_1 // get array index address 257 load r_1 => r_1 // load address 258 loadI 0 => r_4 // 0 259 cmp_GT r_1,r_4 => r_1 // > 260 cbr r_1 -> if_t14,if_f15 // 261 if_t14: nop // 262 i2i r_arp => ART // travelling ALs 263 loadAI ART,-16 => ART // \ 264 addI ART,0 => r_2 // add offset 265 load r_2 => r_2 // get array object 266 addI r_arp,0 => r_1 // add offset 267 load r_1 => r_1 // load address 268 loadAI r_2,-4 => r_7 // check array index 269 divI r_7,4 => r_7 // check array index 270 cmp_LT r_1,r_7 => r_7 // check array index 271 cmp_GE r_1,r_nul => r_6 // check array index 272 and r_7,r_6 => r_6 // check array index 273 cbr r_6 -> nob20,oob19 // check array index 274 oob19: haltI 1634692962 // array index out of bounds 275 nob20: multI r_1,4 => r_1 // multiply index by size 276 add r_2,r_1 => r_2 // get array index address 277 load r_2 => r_2 // load address 278 i2i r_2 => r_4 // result 279 jumpI -> if_e16 // 280 if_f15: nop // 281 i2i r_arp => ART // travelling ALs 282 loadAI ART,-16 => ART // \ 283 addI ART,4 => r_2 // add offset 284 load r_2 => r_6 // call fib - load function reference 285 loadAI r_6,8 => r_6 // call fib - load AR size 286 loadI 290 => r_1 // malloc 287 push r_1 // malloc 288 push r_6 // malloc 289 jumpI -> memalloc // malloc 290 pop => r_1 // malloc 291 addI r_1,16 => r_1 // call fib - shift AR 292 addI r_arp,0 => r_2 // add offset 293 load r_2 => r_2 // load address 294 loadI 1 => r_6 // 1 295 sub r_2,r_6 => r_2 // - 296 storeAI r_2 => r_1,0 // call fib - store param 0 297 push r_5 // call fib - register save r_5 298 push r_3 // call fib - register save r_3 299 push r_4 // call fib - register save r_4 300 i2i r_arp => ART // travelling ALs 301 loadAI ART,-16 => ART // \ 302 addI ART,4 => r_6 // add offset 303 load r_6 => r_7 // call fib - load function reference 304 storeAI r_arp => r_1,-4 // call fib - link caller ARP 305 loadAI r_7,4 => r_2 // call fib - load AL 306 storeAI r_2 => r_1,-16 // call fib - link AL 307 loadAI r_1,-16 => ART // add ref for callee's AL 308 i2i ART => ART // AR incRef 309 cmp_NE ART,r_nul => r_2 // AR incRef 310 cbr r_2 -> aril21,arid22 // AR incRef 311 aril21: loadI 316 => r_2 // AR incRef 312 push r_2 // AR incRef 313 subI ART,16 => r_2 // AR incRef 314 push r_2 // AR incRef 315 jumpI -> memaddref // AR incRef 316 loadAI ART,-16 => ART // AR incRef 317 cmp_NE ART,r_nul => r_2 // AR incRef 318 cbr r_2 -> aril21,arid22 // AR incRef 319 arid22: nop // AR incRef 320 loadI 325 => r_2 // call fib - load return address 321 storeAI r_2 => r_1,-8 // call fib - set return address 322 i2i r_1 => r_arp // call fib - move ARP 323 loadAI r_7,0 => r_2 // call fib - load target address 324 jump -> r_2 // call fib - execute 325 i2i r_arp => ART // AR decRef 326 cmp_NE ART,r_nul => r_7 // AR decRef 327 cbr r_7 -> ardl23,ardd24 // AR decRef 328 ardl23: loadI 333 => r_7 // AR decRef 329 push r_7 // AR decRef 330 subI ART,16 => r_7 // AR decRef 331 push r_7 // AR decRef 332 jumpI -> memfree // AR decRef 333 loadAI ART,-16 => ART // AR decRef 334 cmp_NE ART,r_nul => r_7 // AR decRef 335 cbr r_7 -> ardl23,ardd24 // AR decRef 336 ardd24: nop // AR decRef 337 pop => r_4 // call fib - register unsave r_4 338 pop => r_3 // call fib - register unsave r_3 339 pop => r_5 // call fib - register unsave r_5 340 loadAI r_arp,-12 => r_1 // call fib - load result 341 loadAI r_arp,-4 => r_arp // call fib - reset ARP 342 i2i r_arp => ART // travelling ALs 343 loadAI ART,-16 => ART // \ 344 addI ART,4 => r_6 // add offset 345 load r_6 => r_7 // call fib - load function reference 346 loadAI r_7,8 => r_7 // call fib - load AR size 347 loadI 351 => r_2 // malloc 348 push r_2 // malloc 349 push r_7 // malloc 350 jumpI -> memalloc // malloc 351 pop => r_2 // malloc 352 addI r_2,16 => r_2 // call fib - shift AR 353 addI r_arp,0 => r_7 // add offset 354 load r_7 => r_7 // load address 355 loadI 2 => r_6 // 2 356 sub r_7,r_6 => r_7 // - 357 storeAI r_7 => r_2,0 // call fib - store param 0 358 push r_5 // call fib - register save r_5 359 push r_3 // call fib - register save r_3 360 push r_4 // call fib - register save r_4 361 push r_1 // call fib - register save r_1 362 i2i r_arp => ART // travelling ALs 363 loadAI ART,-16 => ART // \ 364 addI ART,4 => r_8 // add offset 365 load r_8 => r_7 // call fib - load function reference 366 storeAI r_arp => r_2,-4 // call fib - link caller ARP 367 loadAI r_7,4 => r_6 // call fib - load AL 368 storeAI r_6 => r_2,-16 // call fib - link AL 369 loadAI r_2,-16 => ART // add ref for callee's AL 370 i2i ART => ART // AR incRef 371 cmp_NE ART,r_nul => r_6 // AR incRef 372 cbr r_6 -> aril25,arid26 // AR incRef 373 aril25: loadI 378 => r_6 // AR incRef 374 push r_6 // AR incRef 375 subI ART,16 => r_6 // AR incRef 376 push r_6 // AR incRef 377 jumpI -> memaddref // AR incRef 378 loadAI ART,-16 => ART // AR incRef 379 cmp_NE ART,r_nul => r_6 // AR incRef 380 cbr r_6 -> aril25,arid26 // AR incRef 381 arid26: nop // AR incRef 382 loadI 387 => r_6 // call fib - load return address 383 storeAI r_6 => r_2,-8 // call fib - set return address 384 i2i r_2 => r_arp // call fib - move ARP 385 loadAI r_7,0 => r_6 // call fib - load target address 386 jump -> r_6 // call fib - execute 387 i2i r_arp => ART // AR decRef 388 cmp_NE ART,r_nul => r_7 // AR decRef 389 cbr r_7 -> ardl27,ardd28 // AR decRef 390 ardl27: loadI 395 => r_7 // AR decRef 391 push r_7 // AR decRef 392 subI ART,16 => r_7 // AR decRef 393 push r_7 // AR decRef 394 jumpI -> memfree // AR decRef 395 loadAI ART,-16 => ART // AR decRef 396 cmp_NE ART,r_nul => r_7 // AR decRef 397 cbr r_7 -> ardl27,ardd28 // AR decRef 398 ardd28: nop // AR decRef 399 pop => r_1 // call fib - register unsave r_1 400 pop => r_4 // call fib - register unsave r_4 401 pop => r_3 // call fib - register unsave r_3 402 pop => r_5 // call fib - register unsave r_5 403 loadAI r_arp,-12 => r_2 // call fib - load result 404 loadAI r_arp,-4 => r_arp // call fib - reset ARP 405 add r_1,r_2 => r_1 // + 406 i2i r_arp => ART // travelling ALs 407 loadAI ART,-16 => ART // \ 408 addI ART,0 => r_7 // add offset 409 load r_7 => r_7 // get array object 410 addI r_arp,0 => r_6 // add offset 411 load r_6 => r_6 // load address 412 loadAI r_7,-4 => r_8 // check array index 413 divI r_8,4 => r_8 // check array index 414 cmp_LT r_6,r_8 => r_8 // check array index 415 cmp_GE r_6,r_nul => r_2 // check array index 416 and r_8,r_2 => r_2 // check array index 417 cbr r_2 -> nob30,oob29 // check array index 418 oob29: haltI 1634692962 // array index out of bounds 419 nob30: multI r_6,4 => r_6 // multiply index by size 420 add r_7,r_6 => r_7 // get array index address 421 store r_1 => r_7 // to memo[n] 422 i2i r_1 => r_4 // result 423 if_e16: nop // end target 424 i2i r_4 => r_3 // result 425 if_e13: nop // end target 426 i2i r_3 => r_5 // result 427 if_e10: nop // end target 428 storeAI r_5 => r_arp,-12 // define fib - move result 429 loadAI r_arp,-8 => r_1 // load ref count 430 loadI 1 => r_4 // one 431 cmp_LE r_1,r_4 => r_1 // check more than one ref 432 cbr r_1 -> ycl31,ncl32 // remove vars if last reference 433 ycl31: nop // cleanup target 434 ncl32: nop // no cleanup target 435 loadAI r_arp,-8 => r_4 // define fib - load return address 436 jump -> r_4 // define fib - go to return address 437 s7: nop // define fib - skip target 438 loadI 443 => r_3 // malloc 439 push r_3 // malloc 440 loadI 12 => r_3 // malloc 441 push r_3 // malloc 442 jumpI -> memalloc // malloc 443 pop => r_3 // malloc 444 loadI 216 => r_1 // define fib - load target address 445 storeAI r_1 => r_3,0 // define fib - set target address 446 storeAI r_arp => r_3,4 // define fib - copy ARP 447 loadI 20 => r_1 // define fib - load AR size 448 storeAI r_1 => r_3,8 // define fib - set AR size 449 storeAI r_3 => r_arp,4 // define fib - set function reference 450 i2i r_arp => ART // AR incRef 451 cmp_NE ART,r_nul => r_3 // AR incRef 452 cbr r_3 -> aril33,arid34 // AR incRef 453 aril33: loadI 458 => r_3 // AR incRef 454 push r_3 // AR incRef 455 subI ART,16 => r_3 // AR incRef 456 push r_3 // AR incRef 457 jumpI -> memaddref // AR incRef 458 loadAI ART,-16 => ART // AR incRef 459 cmp_NE ART,r_nul => r_3 // AR incRef 460 cbr r_3 -> aril33,arid34 // AR incRef 461 arid34: nop // AR incRef 462 addI r_arp,4 => r_4 // add offset 463 load r_4 => r_4 // load address 464 loadI 468 => r_7 // memaddref 465 push r_7 // memaddref 466 push r_4 // memaddref 467 jumpI -> memaddref // memaddref 468 loadAI r_4,4 => r_5 // add new reference 469 i2i r_5 => ART // AR incRef 470 cmp_NE ART,r_nul => r_7 // AR incRef 471 cbr r_7 -> aril35,arid36 // AR incRef 472 aril35: loadI 477 => r_7 // AR incRef 473 push r_7 // AR incRef 474 subI ART,16 => r_7 // AR incRef 475 push r_7 // AR incRef 476 jumpI -> memaddref // AR incRef 477 loadAI ART,-16 => ART // AR incRef 478 cmp_NE ART,r_nul => r_7 // AR incRef 479 cbr r_7 -> aril35,arid36 // AR incRef 480 arid36: nop // AR incRef 481 storeAI r_4 => r_arp,-12 // define memoizedFib - move result 482 loadAI r_arp,-8 => r_3 // load ref count 483 loadI 1 => r_7 // one 484 cmp_LE r_3,r_7 => r_3 // check more than one ref 485 cbr r_3 -> ycl37,ncl38 // remove vars if last reference 486 ycl37: nop // cleanup target 487 loadAI r_arp,0 => r_5 // remove reference get var 488 cmp_EQ r_5,r_nul => r_4 // remove reference 489 cbr r_4 -> ynul39,nnul40 // remove reference 490 nnul40: nop // remove reference 491 loadI 495 => r_4 // free 492 push r_4 // free 493 push r_5 // free 494 jumpI -> memfree // free 495 ynul39: nop // remove reference 496 loadAI r_arp,4 => r_5 // remove reference get var 497 cmp_EQ r_5,r_nul => r_4 // remove reference 498 cbr r_4 -> ynul41,nnul42 // remove reference 499 nnul42: nop // remove reference 500 loadI 504 => r_4 // free 501 push r_4 // free 502 push r_5 // free 503 jumpI -> memfree // free 504 loadAI r_5,4 => r_5 // remove reference 505 i2i r_5 => ART // AR decRef 506 cmp_NE ART,r_nul => r_4 // AR decRef 507 cbr r_4 -> ardl43,ardd44 // AR decRef 508 ardl43: loadI 513 => r_4 // AR decRef 509 push r_4 // AR decRef 510 subI ART,16 => r_4 // AR decRef 511 push r_4 // AR decRef 512 jumpI -> memfree // AR decRef 513 loadAI ART,-16 => ART // AR decRef 514 cmp_NE ART,r_nul => r_4 // AR decRef 515 cbr r_4 -> ardl43,ardd44 // AR decRef 516 ardd44: nop // AR decRef 517 ynul41: nop // remove reference 518 ncl38: nop // no cleanup target 519 loadAI r_arp,-8 => r_7 // define memoizedFib - load return address 520 jump -> r_7 // define memoizedFib - go to return address 521 s0: nop // define memoizedFib - skip target 522 loadI 527 => r_5 // malloc 523 push r_5 // malloc 524 loadI 12 => r_5 // malloc 525 push r_5 // malloc 526 jumpI -> memalloc // malloc 527 pop => r_5 // malloc 528 loadI 179 => r_3 // define memoizedFib - load target address 529 storeAI r_3 => r_5,0 // define memoizedFib - set target address 530 storeAI r_arp => r_5,4 // define memoizedFib - copy ARP 531 loadI 24 => r_3 // define memoizedFib - load AR size 532 storeAI r_3 => r_5,8 // define memoizedFib - set AR size 533 storeAI r_5 => r_arp,0 // define memoizedFib - set function reference 534 i2i r_arp => ART // AR incRef 535 cmp_NE ART,r_nul => r_5 // AR incRef 536 cbr r_5 -> aril45,arid46 // AR incRef 537 aril45: loadI 542 => r_5 // AR incRef 538 push r_5 // AR incRef 539 subI ART,16 => r_5 // AR incRef 540 push r_5 // AR incRef 541 jumpI -> memaddref // AR incRef 542 loadAI ART,-16 => ART // AR incRef 543 cmp_NE ART,r_nul => r_5 // AR incRef 544 cbr r_5 -> aril45,arid46 // AR incRef 545 arid46: nop // AR incRef 546 addI r_arp,0 => r_1 // add offset 547 load r_1 => r_4 // call memoizedFib - load function reference 548 loadAI r_4,8 => r_4 // call memoizedFib - load AR size 549 loadI 553 => r_7 // malloc 550 push r_7 // malloc 551 push r_4 // malloc 552 jumpI -> memalloc // malloc 553 pop => r_7 // malloc 554 addI r_7,16 => r_7 // call memoizedFib - shift AR 555 addI r_arp,0 => r_6 // add offset 556 load r_6 => r_5 // call memoizedFib - load function reference 557 storeAI r_arp => r_7,-4 // call memoizedFib - link caller ARP 558 loadAI r_5,4 => r_3 // call memoizedFib - load AL 559 storeAI r_3 => r_7,-16 // call memoizedFib - link AL 560 loadAI r_7,-16 => ART // add ref for callee's AL 561 i2i ART => ART // AR incRef 562 cmp_NE ART,r_nul => r_3 // AR incRef 563 cbr r_3 -> aril47,arid48 // AR incRef 564 aril47: loadI 569 => r_3 // AR incRef 565 push r_3 // AR incRef 566 subI ART,16 => r_3 // AR incRef 567 push r_3 // AR incRef 568 jumpI -> memaddref // AR incRef 569 loadAI ART,-16 => ART // AR incRef 570 cmp_NE ART,r_nul => r_3 // AR incRef 571 cbr r_3 -> aril47,arid48 // AR incRef 572 arid48: nop // AR incRef 573 loadI 578 => r_3 // call memoizedFib - load return address 574 storeAI r_3 => r_7,-8 // call memoizedFib - set return address 575 i2i r_7 => r_arp // call memoizedFib - move ARP 576 loadAI r_5,0 => r_3 // call memoizedFib - load target address 577 jump -> r_3 // call memoizedFib - execute 578 i2i r_arp => ART // AR decRef 579 cmp_NE ART,r_nul => r_3 // AR decRef 580 cbr r_3 -> ardl49,ardd50 // AR decRef 581 ardl49: loadI 586 => r_3 // AR decRef 582 push r_3 // AR decRef 583 subI ART,16 => r_3 // AR decRef 584 push r_3 // AR decRef 585 jumpI -> memfree // AR decRef 586 loadAI ART,-16 => ART // AR decRef 587 cmp_NE ART,r_nul => r_3 // AR decRef 588 cbr r_3 -> ardl49,ardd50 // AR decRef 589 ardd50: nop // AR decRef 590 loadAI r_arp,-12 => r_5 // call memoizedFib - load result 591 loadAI r_arp,-4 => r_arp // call memoizedFib - reset ARP 592 addI r_arp,4 => r_6 // add offset 593 load r_6 => r_4 // load reference 594 cmp_EQ r_4,r_nul => r_1 // remove old reference 595 cbr r_1 -> ynul51,nnul52 // remove old reference 596 nnul52: nop // remove old reference 597 loadI 601 => r_1 // free 598 push r_1 // free 599 push r_4 // free 600 jumpI -> memfree // free 601 loadAI r_4,4 => r_4 // remove old reference 602 i2i r_4 => ART // AR decRef 603 cmp_NE ART,r_nul => r_1 // AR decRef 604 cbr r_1 -> ardl53,ardd54 // AR decRef 605 ardl53: loadI 610 => r_1 // AR decRef 606 push r_1 // AR decRef 607 subI ART,16 => r_1 // AR decRef 608 push r_1 // AR decRef 609 jumpI -> memfree // AR decRef 610 loadAI ART,-16 => ART // AR decRef 611 cmp_NE ART,r_nul => r_1 // AR decRef 612 cbr r_1 -> ardl53,ardd54 // AR decRef 613 ardd54: nop // AR decRef 614 ynul51: nop // remove old reference 615 store r_5 => r_6 // to myFib 616 load r_6 => r_3 // load reference 617 loadI 621 => r_1 // memaddref 618 push r_1 // memaddref 619 push r_3 // memaddref 620 jumpI -> memaddref // memaddref 621 loadAI r_3,4 => r_7 // add new reference 622 i2i r_7 => ART // AR incRef 623 cmp_NE ART,r_nul => r_1 // AR incRef 624 cbr r_1 -> aril55,arid56 // AR incRef 625 aril55: loadI 630 => r_1 // AR incRef 626 push r_1 // AR incRef 627 subI ART,16 => r_1 // AR incRef 628 push r_1 // AR incRef 629 jumpI -> memaddref // AR incRef 630 loadAI ART,-16 => ART // AR incRef 631 cmp_NE ART,r_nul => r_1 // AR incRef 632 cbr r_1 -> aril55,arid56 // AR incRef 633 arid56: nop // AR incRef 634 cmp_EQ r_5,r_nul => r_7 // remove old reference 635 cbr r_7 -> ynul57,nnul58 // remove old reference 636 nnul58: nop // remove old reference 637 loadI 641 => r_7 // free 638 push r_7 // free 639 push r_5 // free 640 jumpI -> memfree // free 641 loadAI r_5,4 => r_5 // remove old reference 642 i2i r_5 => ART // AR decRef 643 cmp_NE ART,r_nul => r_7 // AR decRef 644 cbr r_7 -> ardl59,ardd60 // AR decRef 645 ardl59: loadI 650 => r_7 // AR decRef 646 push r_7 // AR decRef 647 subI ART,16 => r_7 // AR decRef 648 push r_7 // AR decRef 649 jumpI -> memfree // AR decRef 650 loadAI ART,-16 => ART // AR decRef 651 cmp_NE ART,r_nul => r_7 // AR decRef 652 cbr r_7 -> ardl59,ardd60 // AR decRef 653 ardd60: nop // AR decRef 654 ynul57: nop // remove old reference 655 jumpI -> while_f62 // to condition 656 while_t61: nop // loop target 657 addI r_arp,4 => r_1 // add offset 658 load r_1 => r_3 // call myFib - load function reference 659 loadAI r_3,8 => r_3 // call myFib - load AR size 660 loadI 664 => r_6 // malloc 661 push r_6 // malloc 662 push r_3 // malloc 663 jumpI -> memalloc // malloc 664 pop => r_6 // malloc 665 addI r_6,16 => r_6 // call myFib - shift AR 666 addI r_arp,8 => r_5 // add offset 667 load r_5 => r_5 // load address 668 storeAI r_5 => r_6,0 // call myFib - store param 0 669 addI r_arp,4 => r_4 // add offset 670 load r_4 => r_1 // call myFib - load function reference 671 storeAI r_arp => r_6,-4 // call myFib - link caller ARP 672 loadAI r_1,4 => r_7 // call myFib - load AL 673 storeAI r_7 => r_6,-16 // call myFib - link AL 674 loadAI r_6,-16 => ART // add ref for callee's AL 675 i2i ART => ART // AR incRef 676 cmp_NE ART,r_nul => r_7 // AR incRef 677 cbr r_7 -> aril64,arid65 // AR incRef 678 aril64: loadI 683 => r_7 // AR incRef 679 push r_7 // AR incRef 680 subI ART,16 => r_7 // AR incRef 681 push r_7 // AR incRef 682 jumpI -> memaddref // AR incRef 683 loadAI ART,-16 => ART // AR incRef 684 cmp_NE ART,r_nul => r_7 // AR incRef 685 cbr r_7 -> aril64,arid65 // AR incRef 686 arid65: nop // AR incRef 687 loadI 692 => r_7 // call myFib - load return address 688 storeAI r_7 => r_6,-8 // call myFib - set return address 689 i2i r_6 => r_arp // call myFib - move ARP 690 loadAI r_1,0 => r_7 // call myFib - load target address 691 jump -> r_7 // call myFib - execute 692 i2i r_arp => ART // AR decRef 693 cmp_NE ART,r_nul => r_7 // AR decRef 694 cbr r_7 -> ardl66,ardd67 // AR decRef 695 ardl66: loadI 700 => r_7 // AR decRef 696 push r_7 // AR decRef 697 subI ART,16 => r_7 // AR decRef 698 push r_7 // AR decRef 699 jumpI -> memfree // AR decRef 700 loadAI ART,-16 => ART // AR decRef 701 cmp_NE ART,r_nul => r_7 // AR decRef 702 cbr r_7 -> ardl66,ardd67 // AR decRef 703 ardd67: nop // AR decRef 704 loadAI r_arp,-12 => r_1 // call myFib - load result 705 loadAI r_arp,-4 => r_arp // call myFib - reset ARP 706 out "",r_1 // 707 while_f62: nop // condition target 708 addI r_arp,8 => r_6 // add offset 709 in "" => r_7 // 710 addI r_arp,8 => r_4 // add offset 711 store r_7 => r_4 // save to var n 712 loadI 0 => r_1 // 0 713 cmp_GT r_7,r_1 => r_7 // > 714 cbr r_7 -> while_t61,while_e63 // 715 while_e63: nop // end target 716 loadAI r_arp,0 => r_6 // remove reference get var 717 cmp_EQ r_6,r_nul => r_4 // remove reference 718 cbr r_4 -> ynul68,nnul69 // remove reference 719 nnul69: nop // remove reference 720 loadI 724 => r_4 // free 721 push r_4 // free 722 push r_6 // free 723 jumpI -> memfree // free 724 loadAI r_6,4 => r_6 // remove reference 725 i2i r_6 => ART // AR decRef 726 cmp_NE ART,r_nul => r_4 // AR decRef 727 cbr r_4 -> ardl70,ardd71 // AR decRef 728 ardl70: loadI 733 => r_4 // AR decRef 729 push r_4 // AR decRef 730 subI ART,16 => r_4 // AR decRef 731 push r_4 // AR decRef 732 jumpI -> memfree // AR decRef 733 loadAI ART,-16 => ART // AR decRef 734 cmp_NE ART,r_nul => r_4 // AR decRef 735 cbr r_4 -> ardl70,ardd71 // AR decRef 736 ardd71: nop // AR decRef 737 ynul68: nop // remove reference 738 loadAI r_arp,4 => r_6 // remove reference get var 739 cmp_EQ r_6,r_nul => r_4 // remove reference 740 cbr r_4 -> ynul72,nnul73 // remove reference 741 nnul73: nop // remove reference 742 loadI 746 => r_4 // free 743 push r_4 // free 744 push r_6 // free 745 jumpI -> memfree // free 746 loadAI r_6,4 => r_6 // remove reference 747 i2i r_6 => ART // AR decRef 748 cmp_NE ART,r_nul => r_4 // AR decRef 749 cbr r_4 -> ardl74,ardd75 // AR decRef 750 ardl74: loadI 755 => r_4 // AR decRef 751 push r_4 // AR decRef 752 subI ART,16 => r_4 // AR decRef 753 push r_4 // AR decRef 754 jumpI -> memfree // AR decRef 755 loadAI ART,-16 => ART // AR decRef 756 cmp_NE ART,r_nul => r_4 // AR decRef 757 cbr r_4 -> ardl74,ardd75 // AR decRef 758 ardd75: nop // AR decRef 759 ynul72: nop // remove reference 760 subI r_arp,16 => r_arp // deconstruct main AR 761 loadI 765 => r_7 // free 762 push r_7 // free 763 push r_arp // free 764 jumpI -> memfree // free