Commit | Line | Data |
---|---|---|
ba86ff93 PC |
1 | .data 4096 |
2 | pop_tab: | |
3 | .c 0 1 1 2 1 2 2 3 1 2 2 3 2 3 3 4 1 2 2 3 2 3 3 4 2 3 3 4 3 4 4 5 1 2 2 3 2 3 3 4 2 3 3 4 3 4 4 5 2 3 3 4 3 4 4 5 3 4 4 5 4 5 5 6 1 2 2 3 2 3 3 4 2 3 3 4 3 4 4 5 2 3 3 4 3 4 4 5 3 4 4 5 4 5 5 6 2 3 3 4 3 4 4 5 3 4 4 5 4 5 5 6 3 4 4 5 4 5 5 6 4 5 5 6 5 6 6 7 1 2 2 3 2 3 3 4 2 3 3 4 3 4 4 5 2 3 3 4 3 4 4 5 3 4 4 5 4 5 5 6 2 3 3 4 3 4 4 5 3 4 4 5 4 5 5 6 3 4 4 5 4 5 5 6 4 5 5 6 5 6 6 7 2 3 3 4 3 4 4 5 3 4 4 5 4 5 5 6 3 4 4 5 4 5 5 6 4 5 5 6 5 6 6 7 3 4 4 5 4 5 5 6 4 5 5 6 5 6 6 7 4 5 5 6 5 6 6 7 5 6 6 7 6 7 7 8 | |
4 | ok: | |
5 | .c "ok\n" | |
6 | fmt: | |
7 | #if __WORDSIZE == 32 | |
8 | .c "0x%08lx = %d\n" | |
9 | #else | |
10 | .c "0x%016lx = %d\n" | |
11 | #endif | |
12 | ||
13 | #define BIT2(OP, ARG, RES, R0, R1) \ | |
14 | movi %R1 ARG \ | |
15 | OP##r %R0 %R1 \ | |
16 | beqi OP##R0##R1##ARG %R0 RES \ | |
17 | calli @abort \ | |
18 | OP##R0##R1##ARG: | |
19 | ||
20 | #define BIT1(OP, ARG, RES, V0, V1, V2, R0, R1, R2) \ | |
21 | BIT2(OP, ARG, RES, V0, V0) \ | |
22 | BIT2(OP, ARG, RES, V0, V1) \ | |
23 | BIT2(OP, ARG, RES, V0, V2) \ | |
24 | BIT2(OP, ARG, RES, V0, R0) \ | |
25 | BIT2(OP, ARG, RES, V0, R1) \ | |
26 | BIT2(OP, ARG, RES, V0, R2) | |
27 | ||
28 | #define BIT(OP, ARG, RES, V0, V1, V2, R0, R1, R2) \ | |
29 | BIT1(OP, ARG, RES, V1, V2, R0, R1, R2, V0) \ | |
30 | BIT1(OP, ARG, RES, V2, R0, R1, R2, V0, V1) \ | |
31 | BIT1(OP, ARG, RES, R0, R1, R2, V0, V1, V2) \ | |
32 | BIT1(OP, ARG, RES, R1, R2, V0, V1, V2, R0) \ | |
33 | BIT1(OP, ARG, RES, R2, V0, V1, V2, R0, R1) | |
34 | ||
35 | #define POPCNT(ARG, RES) \ | |
36 | BIT(popcnt, ARG, RES, v0, v1, v2, r0, r1, r2) | |
37 | ||
38 | .code | |
39 | jmpi main | |
40 | name popcnt | |
41 | popcnt: | |
42 | prolog | |
43 | arg $in | |
44 | getarg %r1 $in | |
45 | extr_uc %r2 %r1 | |
46 | movi %v0 pop_tab | |
47 | ldxr_uc %r0 %v0 %r2 | |
48 | movi %v1 8 | |
49 | popcnt_loop: | |
50 | rshr %r2 %r1 %v1 | |
51 | extr_uc %r2 %r2 | |
52 | ldxr_uc %r2 %v0 %r2 | |
53 | addr %r0 %r0 %r2 | |
54 | addi %v1 %v1 8 | |
55 | blti popcnt_loop %v1 __WORDSIZE | |
56 | retr %r0 | |
57 | epilog | |
58 | ||
59 | #if 0 | |
60 | name main | |
61 | main: | |
62 | prolog | |
63 | arg $argc | |
64 | arg $argv | |
65 | getarg %r0 $argc | |
66 | bnei default %r0 2 | |
67 | getarg %v0 $argv | |
68 | ldxi %r0 %v0 $(__WORDSIZE >> 3) | |
69 | prepare | |
70 | pushargr %r0 | |
71 | pushargi 0 | |
72 | pushargi 0 | |
73 | finishi @strtoul | |
74 | retval %v0 | |
75 | jmpi main_do | |
76 | default: | |
77 | #if __WORDSIZE == 32 | |
78 | movi %v0 0x8a13c851 | |
79 | #else | |
80 | movi %v0 0x984a137ffec85219 | |
81 | #endif | |
82 | main_do: | |
83 | prepare | |
84 | pushargr %v0 | |
85 | finishi popcnt | |
86 | retval %r0 | |
87 | prepare | |
88 | pushargi fmt | |
89 | ellipsis | |
90 | pushargr %v0 | |
91 | pushargr %r0 | |
92 | finishi @printf | |
93 | ||
94 | popcntr %r0 %v0 | |
95 | prepare | |
96 | pushargi fmt | |
97 | ellipsis | |
98 | pushargr %v0 | |
99 | pushargr %r0 | |
100 | finishi @printf | |
101 | ||
102 | ret | |
103 | epilog | |
104 | #else | |
105 | ||
106 | name main | |
107 | main: | |
108 | prolog | |
109 | #if __WORDSIZE == 32 | |
110 | POPCNT(0x8a13c851, 12) | |
111 | POPCNT(0x12345678, 13) | |
112 | POPCNT(0x02468ace, 12) | |
113 | #else | |
114 | POPCNT(0x984a137ffec85219, 32) | |
115 | POPCNT(0x123456789abcdef0, 32) | |
116 | POPCNT(0x02468ace013579bd, 28) | |
117 | #endif | |
118 | prepare | |
119 | pushargi ok | |
120 | finishi @printf | |
121 | reti 0 | |
122 | epilog | |
123 | #endif |