1#define szof_c 1 2#define szof_uc szof_c 3#define szof_s 2 4#define szof_us szof_s 5#define szof_i 4 6#if __WORDSIZE == 64 7# define szof_ui szof_i 8# define szof_l 8 9#endif 10#define szof_f 4 11#define szof_d 8 12 13#define FILL(T) \ 14 name fill##T \ 15fill##T: \ 16 prolog \ 17 arg $argp \ 18 getarg %v0 $argp \ 19 arg $argi \ 20 getarg %r0 $argi \ 21 muli %r0 %r0 szof##T \ 22 addr %v1 %v0 %r0 \ 23 movi %r0 0 \ 24fill##T##loop: \ 25 bger fill##T##done %v0 %v1 \ 26 str##T %v0 %r0 \ 27 addi %r0 %r0 1 \ 28 addi %v0 %v0 szof##T \ 29 jmpi fill##T##loop \ 30fill##T##done: \ 31 ret \ 32 epilog 33#define FILLF(T) \ 34 name fill##T \ 35fill##T: \ 36 prolog \ 37 arg $argp \ 38 getarg %v0 $argp \ 39 arg $argi \ 40 getarg %r0 $argi \ 41 muli %r0 %r0 szof##T \ 42 addr %v1 %v0 %r0 \ 43 movi##T %f0 0.0 \ 44fill##T##loop: \ 45 bger fill##T##done %v0 %v1 \ 46 str##T %v0 %f0 \ 47 addi##T %f0 %f0 1.0 \ 48 addi %v0 %v0 szof##T \ 49 jmpi fill##T##loop \ 50fill##T##done: \ 51 ret \ 52 epilog 53 54#define fill_uc fill_c 55#define fill_us fill_s 56#define fill_ui fill_i 57 58#define ARG( T, N) arg $arg##T##N 59#define ARGF( T, N) arg##T $arg##T##N 60#define ARG1( K, T) ARG##K(T, 0) 61#define ARG2( K, T) ARG1( K, T) ARG##K(T, 1) 62#define ARG3( K, T) ARG2( K, T) ARG##K(T, 2) 63#define ARG4( K, T) ARG3( K, T) ARG##K(T, 3) 64#define ARG5( K, T) ARG4( K, T) ARG##K(T, 4) 65#define ARG6( K, T) ARG5( K, T) ARG##K(T, 5) 66#define ARG7( K, T) ARG6( K, T) ARG##K(T, 6) 67#define ARG8( K, T) ARG7( K, T) ARG##K(T, 7) 68#define ARG9( K, T) ARG8( K, T) ARG##K(T, 8) 69#define ARG10(K, T) ARG9( K, T) ARG##K(T, 9) 70#define ARG11(K, T) ARG10(K, T) ARG##K(T, 10) 71#define ARG12(K, T) ARG11(K, T) ARG##K(T, 11) 72#define ARG13(K, T) ARG12(K, T) ARG##K(T, 12) 73#define ARG14(K, T) ARG13(K, T) ARG##K(T, 13) 74#define ARG15(K, T) ARG14(K, T) ARG##K(T, 14) 75#define ARG16(K, T) ARG15(K, T) ARG##K(T, 15) 76#define ARG_c(N) ARG##N( , _c) 77#define ARG_uc(N) ARG##N( , _uc) 78#define ARG_s(N) ARG##N( , _s) 79#define ARG_us(N) ARG##N( , _us) 80#define ARG_i(N) ARG##N( , _i) 81#define ARG_ui(N) ARG##N( , _ui) 82#define ARG_l(N) ARG##N( , _l) 83#define ARG_f(N) ARG##N(F, _f) 84#define ARG_d(N) ARG##N(F, _d) 85 86#define CHK(N, T, V) \ 87 getarg %r0 $arg##T##V \ 88 ldxi##T %r1 %v0 $(V * szof##T) \ 89 beqr N##T##V %r0 %r1 \ 90 calli @abort \ 91N##T##V: 92#define CHKF(N, T, V) \ 93 getarg##T %f0 $arg##T##V \ 94 ldxi##T %f1 %v0 $(V * szof##T) \ 95 beqr##T N##T##V %f0 %f1 \ 96 calli @abort \ 97N##T##V: 98 99#define GET1( K, N, T, V) CHK##K(N, T, 0) 100#define GET2( K, N, T, V) GET1( K, N, T, V) CHK##K(N, T, 1) 101#define GET3( K, N, T, V) GET2( K, N, T, V) CHK##K(N, T, 2) 102#define GET4( K, N, T, V) GET3( K, N, T, V) CHK##K(N, T, 3) 103#define GET5( K, N, T, V) GET4( K, N, T, V) CHK##K(N, T, 4) 104#define GET6( K, N, T, V) GET5( K, N, T, V) CHK##K(N, T, 5) 105#define GET7( K, N, T, V) GET6( K, N, T, V) CHK##K(N, T, 6) 106#define GET8( K, N, T, V) GET7( K, N, T, V) CHK##K(N, T, 7) 107#define GET9( K, N, T, V) GET8( K, N, T, V) CHK##K(N, T, 8) 108#define GET10(K, N, T, V) GET9( K, N, T, V) CHK##K(N, T, 9) 109#define GET11(K, N, T, V) GET10(K, N, T, V) CHK##K(N, T, 10) 110#define GET12(K, N, T, V) GET11(K, N, T, V) CHK##K(N, T, 11) 111#define GET13(K, N, T, V) GET12(K, N, T, V) CHK##K(N, T, 12) 112#define GET14(K, N, T, V) GET13(K, N, T, V) CHK##K(N, T, 13) 113#define GET15(K, N, T, V) GET14(K, N, T, V) CHK##K(N, T, 14) 114#define GET16(K, N, T, V) GET15(K, N, T, V) CHK##K(N, T, 15) 115 116#define GET_c(N, M) GET##N( , c##N, _c, M) 117#define GET_uc(N, M) GET##N( , uc##N, _uc, M) 118#define GET_s(N, M) GET##N( , s##N, _s, M) 119#define GET_us(N, M) GET##N( , us##N, _us, M) 120#define GET_i(N, M) GET##N( , i##N, _i, M) 121#define GET_ui(N, M) GET##N( , ui##N, _ui, M) 122#define GET_l(N, M) GET##N( , l##N, _l, M) 123#define GET_f(N, M) GET##N(F, f##N, _f, M) 124#define GET_d(N, M) GET##N(F, d##N, _d, M) 125 126#define PUSH( T, V) pushargi V 127#define PUSHF( T, V) pushargi##T V 128#define PUSH0( K, T) /**/ 129#define PUSH1( K, T) PUSH##K(T, 0) 130#define PUSH2( K, T) PUSH1( K, T) PUSH##K(T, 1) 131#define PUSH3( K, T) PUSH2( K, T) PUSH##K(T, 2) 132#define PUSH4( K, T) PUSH3( K, T) PUSH##K(T, 3) 133#define PUSH5( K, T) PUSH4( K, T) PUSH##K(T, 4) 134#define PUSH6( K, T) PUSH5( K, T) PUSH##K(T, 5) 135#define PUSH7( K, T) PUSH6( K, T) PUSH##K(T, 6) 136#define PUSH8( K, T) PUSH7( K, T) PUSH##K(T, 7) 137#define PUSH9( K, T) PUSH8( K, T) PUSH##K(T, 8) 138#define PUSH10(K, T) PUSH9( K, T) PUSH##K(T, 9) 139#define PUSH11(K, T) PUSH10(K, T) PUSH##K(T, 10) 140#define PUSH12(K, T) PUSH11(K, T) PUSH##K(T, 11) 141#define PUSH13(K, T) PUSH12(K, T) PUSH##K(T, 12) 142#define PUSH14(K, T) PUSH13(K, T) PUSH##K(T, 13) 143#define PUSH15(K, T) PUSH14(K, T) PUSH##K(T, 14) 144#define PUSH16(K, T) PUSH15(K, T) PUSH##K(T, 15) 145 146#define PUSH_c( N) PUSH##N( , _c) 147#define PUSH_uc(N) PUSH##N( , _uc) 148#define PUSH_s( N) PUSH##N( , _s) 149#define PUSH_us(N) PUSH##N( , _us) 150#define PUSH_i( N) PUSH##N( , _i) 151#define PUSH_ui(N) PUSH##N( , _ui) 152#define PUSH_l( N) PUSH##N( , _l) 153#define PUSH_f( N) PUSH##N(F, _f) 154#define PUSH_d( N) PUSH##N(F, _d) 155 156/* bottom function */ 157#define DEF0(T) \ 158 name test##T##_0 \ 159test##T##_0: \ 160 prolog \ 161 ret \ 162 epilog 163 164#define DEFN(N, M, T) \ 165 name test##T##_##N \ 166test##T##_##N: \ 167 prolog \ 168 arg $argp \ 169 /* stack buffer in %v0 */ \ 170 getarg %v0 $argp \ 171 ARG##T(N) \ 172 /* validate arguments */ \ 173 GET##T(N, M) \ 174 /* heap buffer in %v1 */ \ 175 prepare \ 176 pushargi $(N * szof##T) \ 177 finishi @malloc \ 178 retval %v1 \ 179 /* copy stack bufer to heap buffer */ \ 180 prepare \ 181 pushargr %v1 \ 182 pushargr %v0 \ 183 pushargi $(N * szof##T) \ 184 finishi MEMCPY \ 185 /* stack buffer for next function in %v2 */ \ 186 movi %r0 $(M * szof##T) \ 187 allocar %v2 %r0 \ 188 addr %v2 %v2 %fp \ 189 /* fill stack buffer for next function */ \ 190 prepare \ 191 pushargr %v2 \ 192 pushargi M \ 193 finishi fill##T \ 194 /* call next function */ \ 195 prepare \ 196 pushargr %v2 \ 197 PUSH##T(M) \ 198 finishi test##T##_##M \ 199 /* validate stack buffer */ \ 200 prepare \ 201 pushargr %v1 \ 202 pushargr %v0 \ 203 pushargi $(N * szof##T) \ 204 finishi @memcmp \ 205 retval %r0 \ 206 beqi test##T##_##N##_done %r0 0 \ 207 calli @abort \ 208test##T##_##N##_done: \ 209 /* release heap bufer */ \ 210 prepare \ 211 pushargr %v1 \ 212 finishi @free \ 213 ret \ 214 epilog 215 216/* top function */ 217#define DEFX(T) \ 218 name test##T##_17 \ 219test##T##_17: \ 220 prolog \ 221 /* heap buffer in %v1 */ \ 222 prepare \ 223 pushargi $(16 * szof##T) \ 224 finishi @malloc \ 225 retval %v1 \ 226 /* stack buffer for next function in %v2 */ \ 227 movi %r0 $(16 * szof##T) \ 228 allocar %v2 %r0 \ 229 addr %v2 %v2 %fp \ 230 /* fill stack buffer for next function */ \ 231 prepare \ 232 pushargr %v2 \ 233 pushargi 16 \ 234 finishi fill##T \ 235 /* copy stack buffer to heap buffer */ \ 236 prepare \ 237 pushargr %v1 \ 238 pushargr %v2 \ 239 pushargi $(16 * szof##T) \ 240 finishi MEMCPY \ 241 /* call next function */ \ 242 prepare \ 243 pushargr %v2 \ 244 PUSH##T(16) \ 245 finishi test##T##_16 \ 246 /* validate stack buffer */ \ 247 prepare \ 248 pushargr %v1 \ 249 pushargr %v2 \ 250 pushargi $(16 * szof##T) \ 251 finishi @memcmp \ 252 retval %r0 \ 253 beqi test##T##_17_done %r0 0 \ 254 calli @abort \ 255test##T##_17_done: \ 256 /* release heap bufer */ \ 257 prepare \ 258 pushargr %v1 \ 259 finishi @free \ 260 ret \ 261 epilog 262 263#define DEF( T) \ 264 DEF0( T) \ 265 DEFN( 1, 0, T) \ 266 DEFN( 2, 1, T) \ 267 DEFN( 3, 2, T) \ 268 DEFN( 4, 3, T) \ 269 DEFN( 5, 4, T) \ 270 DEFN( 6, 5, T) \ 271 DEFN( 7, 6, T) \ 272 DEFN( 8, 7, T) \ 273 DEFN( 9, 8, T) \ 274 DEFN(10, 9, T) \ 275 DEFN(11, 10, T) \ 276 DEFN(12, 11, T) \ 277 DEFN(13, 12, T) \ 278 DEFN(14, 13, T) \ 279 DEFN(15, 14, T) \ 280 DEFN(16, 15, T) \ 281 DEFX(T) 282 283#define CALL(T) calli test##T##_17 284 285.data 16 286fmt: 287.c "%d %d %d\n" 288.code 289 jmpi main 290 291#if _AIX 292# define MEMCPY memcpy 293/* error: Function not implemented (memcpy) */ 294 name memcpy 295memcpy: 296 prolog 297 arg $dst 298 arg $src 299 arg $len 300 getarg %r0 $dst 301 getarg %r1 $src 302 getarg %r2 $len 303 movr %v1 %r0 304 blti memcpy_done %r2 1 305memcpy_loop: 306 subi %r2 %r2 1 307 ldxr_c %v0 %r1 %r2 308 stxr_c %r2 %r0 %v0 309 bgti memcpy_loop %r2 0 310memcpy_done: 311 retr %v1 312 epilog 313#else 314# define MEMCPY @memcpy 315#endif 316 317 FILL(_c) 318 FILL(_s) 319 FILL(_i) 320#if __WORDSIZE == 64 321 FILL(_l) 322#endif 323 FILLF(_f) 324 FILLF(_d) 325 326 DEF(_c) 327 DEF(_uc) 328 DEF(_s) 329 DEF(_us) 330 DEF(_i) 331#if __WORDSIZE == 64 332 DEF(_ui) 333 DEF(_l) 334#endif 335 DEF(_f) 336 DEF(_d) 337 338 name main 339main: 340 prolog 341 342 CALL(_c) 343 CALL(_uc) 344 CALL(_s) 345 CALL(_us) 346 CALL(_i) 347#if __WORDSIZE == 64 348 CALL(_ui) 349 CALL(_l) 350#endif 351 CALL(_f) 352 CALL(_d) 353 354 // loop control 355 movi %v2 1 356 357 // loop a few times calling allocar 358loop: 359 // allocate 12 bytes 360 movi %r0 12 361 allocar %v0 %r0 362 363 // offset 364 movr %v1 %v0 365 366 // 1 367 stxr_i %v1 %fp %v2 368 369 // 2 370 addi %v2 %v2 1 371 addi %v1 %v1 4 372 stxr_i %v1 %fp %v2 373 374 // 3 375 addi %v2 %v2 1 376 addi %v1 %v1 4 377 stxr_i %v1 %fp %v2 378 379 // reload 380 movr %v1 %v0 381 382 // 1 383 ldxr_i %r0 %fp %v1 384 385 // 2 386 addi %v1 %v1 4 387 ldxr_i %r1 %fp %v1 388 389 // 3 390 addi %v1 %v1 4 391 ldxr_i %r2 %fp %v1 392 393 prepare 394 pushargi fmt 395 ellipsis 396 pushargr %r0 397 pushargr %r1 398 pushargr %r2 399 finishi @printf 400 blti loop %v2 9 401 402 ret 403 epilog 404