| 1 | .data 32 |
| 2 | str: |
| 3 | .c "%lu\n" |
| 4 | .code |
| 5 | jmpi main |
| 6 | /* |
| 7 | * unsigned long collatz(unsigned long n) { |
| 8 | * unsigned long r = n; |
| 9 | * if (!(r & 1)) { |
| 10 | * r = r / 2; |
| 11 | * return r; |
| 12 | * } |
| 13 | * r = r * 3; |
| 14 | * r = r + 1; |
| 15 | * return r; |
| 16 | * } |
| 17 | */ |
| 18 | collatz: |
| 19 | prolog |
| 20 | arg $n |
| 21 | getarg %r0 $n |
| 22 | bmsi odd %r0 1 |
| 23 | //divi_u %r0 %r0 2 |
| 24 | rshi_u %r0 %r0 1 |
| 25 | retr %r0 |
| 26 | odd: |
| 27 | muli %r0 %r0 3 |
| 28 | addi %r0 %r0 1 |
| 29 | retr %r0 |
| 30 | epilog |
| 31 | |
| 32 | /* |
| 33 | * int main(int argc, char *argv[]) { |
| 34 | * unsigned long v; |
| 35 | * if (argc == 2) |
| 36 | * v = strtoul(argv[1], NULL, 0); |
| 37 | * else |
| 38 | * v = (1L << __WORDSIZE / 2) - 1; |
| 39 | * while (1) { |
| 40 | * printf("%ld\n", v); |
| 41 | * if (v <= 1) |
| 42 | * break; |
| 43 | * v = collatz(v); |
| 44 | * } |
| 45 | * return 0; |
| 46 | * } |
| 47 | */ |
| 48 | main: |
| 49 | prolog |
| 50 | arg $argc |
| 51 | arg $argv |
| 52 | getarg %r0 $argc |
| 53 | bnei default %r0 2 |
| 54 | getarg %v0 $argv |
| 55 | ldxi %r0 %v0 $(__WORDSIZE >> 3) |
| 56 | prepare |
| 57 | pushargr %r0 |
| 58 | pushargi 0 |
| 59 | pushargi 0 |
| 60 | finishi @strtoul |
| 61 | retval %v0 |
| 62 | jmpi loop |
| 63 | default: |
| 64 | movi %v0 $((1 << __WORDSIZE / 2) - 1) |
| 65 | loop: |
| 66 | prepare |
| 67 | pushargi str |
| 68 | ellipsis |
| 69 | pushargr %v0 |
| 70 | finishi @printf |
| 71 | blei_u done %v0 1 |
| 72 | prepare |
| 73 | pushargr %v0 |
| 74 | finishi collatz |
| 75 | retval %v0 |
| 76 | jmpi loop |
| 77 | done: |
| 78 | reti 0 |
| 79 | epilog |