Created
May 27, 2016 10:28
-
-
Save osa1/6961501a76a4fd44538a1720b224b820 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| [section ""data" . $wsum_closure" { | |
| $wsum_closure: | |
| const $wsum_info; | |
| }, | |
| $wsum_entry() // [R2] | |
| { info_tbl: [(cMo, | |
| label: block_cMo_info | |
| rep:StackRep []), | |
| (cMv, | |
| label: $wsum_info | |
| rep:HeapRep static { Fun {arity: 1 fun_type: ArgSpec 5} }), | |
| (cMD, | |
| label: block_cMD_info | |
| rep:StackRep [False]), | |
| (cMI, | |
| label: block_cMI_info | |
| rep:StackRep [True])] | |
| stack_info: arg_space: 8 updfr_space: Just 8 | |
| } | |
| {offset | |
| // make sure we have enough stack space | |
| cMv: | |
| if ((Sp + -16) < SpLim) goto cMw; else goto cMx; | |
| // not enough stack space, run GC | |
| cMw: | |
| R2 = R2; | |
| R1 = $wsum_closure; | |
| call (stg_gc_fun)(R2, R1) args: 8, res: 0, upd: 8; | |
| // have enough stack space | |
| cMx: | |
| I64[Sp - 8] = cMo; // cMo is pushed to the stack for cMp | |
| R1 = R2; // what is R2? (probably the argument) | |
| Sp = Sp - 8; // why is stack pointer not adjusted right after the push? | |
| if (R1 & 7 != 0) goto cMo; else goto cMp; | |
| // evaluate the argument, stack has cMo on top | |
| cMp: | |
| call (I64[R1])(R1) returns to cMo, args: 8, res: 8, upd: 8; | |
| // the argument is evaluated at this point, so this must be a tag check | |
| // the problem though, we pushed cMo to the stack even if (R1 & 7 != 0). | |
| // isn't that a redundant operation? why not push cMo to the stack in | |
| // cMp? | |
| cMo: | |
| if (R1 & 7 != 1) goto cMt; else goto cMs; | |
| cMt: // it's a Cons | |
| I64[Sp - 8] = cMD; // push cMD eagerly, just like how we pushed cMo | |
| // eagerly | |
| _sKX::P64 = P64[R1 + 14]; // tail, 14 instead of 16 because we know (R1 & 7 == 2) | |
| R1 = P64[R1 + 6]; // head, 6 instead of 8 because we know (R1 & 7 == 2) | |
| P64[Sp] = _sKX::P64; // push tail to the stack | |
| Sp = Sp - 8; // first push overwrite cMo, so only after second push | |
| // we decrement sp | |
| if (R1 & 7 != 0) goto cMD; else goto cME; // check whether int is evaluated | |
| // (of course it is! it has a bang in its definition!) | |
| cME: // evaluate the !Int | |
| call (I64[R1])(R1) returns to cMD, args: 8, res: 8, upd: 8; | |
| cMD: | |
| // at this point tail is on the stack, even if we didn't run cME! | |
| I64[Sp] = cMI; | |
| R2 = P64[Sp + 8]; // load tail to R2 | |
| I64[Sp + 8] = I64[R1 + 7]; // R1 has Int. because of pointer tagging, | |
| // we know that the last bit should be 1, | |
| // so we add 7 instead of 8 to get the | |
| // first field | |
| // recursively sum the tail | |
| call $wsum_info(R2) returns to cMI, args: 8, res: 8, upd: 8; | |
| cMI: | |
| R1 = I64[Sp + 8] + R1; // sum return value + our int | |
| Sp = Sp + 16; // restore stack, used two slots one for saving our | |
| // int, one for | |
| call (P64[Sp])(R1) args: 8, res: 0, upd: 8; | |
| cMs: // it's a Nil | |
| R1 = 0; // put return value to its reg | |
| Sp = Sp + 8; // restore stack pointer | |
| call (P64[Sp])(R1) args: 8, res: 0, upd: 8; // jump to the continuation | |
| } | |
| }] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| $wsum = | |
| \r srt:SRT:[] [w_sKU] | |
| case w_sKU of _ { | |
| Nil -> 0#; | |
| Cons x_sKW xs_sKX -> | |
| case x_sKW of _ { | |
| I# x1_sKZ -> | |
| case $wsum xs_sKX of ww_sL0 { __DEFAULT -> +# [x1_sKZ ww_sL0]; }; | |
| }; | |
| }; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment