Print this page
6648 illumos build should be explicit about C standards
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/common/io/audio/drv/audioemu10k/dsp/asm10k.c
+++ new/usr/src/uts/common/io/audio/drv/audioemu10k/dsp/asm10k.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21
22 22 /*
23 23 * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
24 24 */
25 25
26 26 /*
27 27 * Assembler for Emu10k1
28 28 */
29 29 /*
30 30 * Copyright (C) 4Front Technologies 1996-2008.
31 31 */
32 32
33 33 #include <stdio.h>
34 34 #include <stdlib.h>
35 35 #include <unistd.h>
36 36 #include <fcntl.h>
37 37 #include <string.h>
38 38 #include <stdarg.h>
39 39 #include <ctype.h>
40 40 #include <sys/param.h>
41 41
42 42 #define MAX_GPR 256
43 43 #define MAX_GPR_PARMS 60
44 44 #define MAX_CONST_PARMS 128
45 45 #define GPR_NAME_SIZE 32
46 46
47 47 typedef struct {
48 48 char name[GPR_NAME_SIZE];
49 49 unsigned int num;
50 50 int type;
51 51 int def;
52 52 } gpr_t;
53 53
54 54 typedef struct {
55 55 unsigned int gpr;
56 56 unsigned int value;
57 57 } const_t;
58 58
59 59 typedef struct {
60 60 unsigned int ngpr;
61 61
62 62 gpr_t gpr[MAX_GPR_PARMS];
63 63 } gpr_info;
64 64
65 65 typedef struct {
66 66 unsigned int nconst;
67 67
68 68 const_t consts[MAX_CONST_PARMS];
69 69 } const_info;
70 70
71 71 typedef struct {
72 72 unsigned int code[1024];
73 73 gpr_info parms;
74 74 const_info consts;
75 75 int ninit;
76 76 struct {
77 77 uint32_t gpr;
78 78 uint32_t value;
79 79 char name[GPR_NAME_SIZE];
80 80 } init[MAX_GPR];
81 81 } emu10k1_file;
82 82
83 83 #define MAX_NAME 64
84 84 #define MAX_SYMBOLS 1024
85 85
86 86 static int parms_only = 0;
87 87 static int is_audigy = 0;
88 88 static int verbose = 0;
89 89
90 90 static int gpr_base = 0x100;
91 91 static int input_base = 0x10;
92 92 static int output_base = 0x20;
93 93
94 94 static char *progname;
95 95
96 96 typedef struct {
97 97 char name[MAX_NAME];
98 98 int type;
99 99 #define SY_DUMMY 0
100 100 #define SY_GPR 1
101 101 #define SY_INPUT 2
102 102 #define SY_OUTPUT 3
103 103 #define SY_CONST 4
104 104 #define SY_FX 5
105 105 #define SY_ACCUM 6
106 106 #define SY_PARM 7
107 107 int arg;
108 108 } sym_t;
109 109
110 110 typedef struct {
111 111 char *name;
112 112 int opcode;
113 113 } instruction_t;
114 114
115 115 static char remarks[2048] = "";
116 116 static char *banner =
117 117 "/*\n"
118 118 " * Note: This file was automatically generated by %s\n"
119 119 " * on %s.\n"
120 120 " */\n";
121 121
122 122 /*
123 123 * Instructions. Each instruction takes 4 arguments, R, A, X, and Y.
124 124 */
125 125 static instruction_t instructions[] = {
126 126 { "MACS", 0x0}, /* R = A + (X * Y >> 31); saturation */
127 127 { "MACS1", 0x1}, /* R = A + (-X * Y >> 31); saturation */
128 128 { "MACW", 0x2}, /* R = A + (X * Y >> 31); wraparound */
129 129 { "MACW1", 0x3}, /* R = A + (-X * Y >> 31); wraparound */
130 130 { "MACINTS", 0x4}, /* R = A + (X * Y); saturation */
131 131 { "MACINTW", 0x5}, /* R = A + (X * Y); wraparound */
132 132 { "SUM", 0x6}, /* R = A + X + Y; saturation */
133 133 { "ACC3", 0x6}, /* R = A + X + Y; saturation */
134 134 { "MACMV", 0x7}, /* R = A, acc += X * Y >> 31 */
135 135 { "ANDXOR", 0x8}, /* R = (A & X) ^ Y */
136 136 { "TSTNEG", 0x9}, /* R = (A >= Y) ? X : ~X */
137 137 { "LIMIT", 0xa}, /* R = (A >= Y) ? X : Y */
138 138 { "LIMIT1", 0xb}, /* R = (A < Y) ? X : Y */
139 139 { "LOG", 0xc}, /* R = ... (log?) */
140 140 { "EXP", 0xd}, /* R = ... (exp?) */
141 141 { "INTERP", 0xe}, /* R = A + (X * (Y - A) >> 31) */
142 142 { "SKIP", 0xf}, /* R, CCR, CC_TEST, COUNT */
143 143 { NULL, 0}
144 144 };
145 145
146 146 #define CHECK_COUNT(tokens, cnt, mincnt, maxcnt) \
147 147 if (cnt < mincnt) { \
148 148 error("Too few parameters for '%s' (have %d, min %d)", \
149 149 tokens[0], cnt - 1, mincnt - 1); \
150 150 return; \
151 151 } \
152 152 if (cnt > maxcnt) { \
153 153 error("Too many parameters for '%s' (have %d, max %d)", \
154 154 tokens[0], cnt - 1, maxcnt - 1); \
155 155 return; \
156 156 }
157 157
158 158 static sym_t symtab[MAX_SYMBOLS];
159 159 static int nsyms = 0;
160 160
161 161 static int lineno = 0, errors = 0;
162 162 static emu10k1_file fle;
163 163 static int pc;
164 164
165 165 static int ngpr = 0;
166 166 static char *infile;
167 167
168 168 static int
169 169 getaline(FILE *input, char **tokens)
170 170 {
171 171 char *s, *ls;
172 172 static char *stmt = NULL, *lasts = NULL;
173 173 static char line[4096];
174 174 int cnt, tokcnt;
175 175
176 176 for (;;) {
177 177
178 178 if (stmt == NULL) {
179 179 if (fgets(line, sizeof (line), input) == NULL)
180 180 return (-1);
181 181 lineno++;
182 182
183 183 /*
184 184 * Special handling for .' comments. We use
185 185 * .' as a keyword to ensure that entire
186 186 * comment makes it through the C preprocessor
187 187 * unmolested. We also need to make sure *we*
188 188 * don't molest it either. The comment will
189 189 * be exported to any resulting header,
190 190 * allowing us to pass through copyright and
191 191 * other information from the source file to
192 192 * the resulting header.
193 193 */
194 194 s = line;
195 195 s += strspn(s, " \t");
196 196 if ((strncmp(s, ".'", 2) == 0) &&
197 197 (strchr(" \t\n", s[2]) != NULL)) {
198 198 /* chop off trailing new line */
199 199 (void) strtok(line, "\n");
200 200 tokens[0] = s;
201 201 s += 2;
202 202 s += strspn(s, " \t");
203 203 if ((s[0] == '\'') &&
204 204 (s[strlen(s) - 1] == '\'')) {
205 205 s[strlen(s) - 1] = 0;
206 206 s++;
207 207 }
208 208 tokens[1] = s;
209 209 tokens[0][2] = 0;
210 210 tokens[2] = NULL;
211 211 stmt = NULL;
212 212 return (strlen(tokens[1]) ? 2 : 1);
213 213 }
214 214
215 215 /* strip off any C++ style comments that CPP missed */
216 216 if ((s = strstr(line, "//")) != NULL) {
217 217 *s = '\0';
218 218 }
219 219 stmt = strtok_r(line, ";\n", &lasts);
220 220 } else {
221 221 stmt = strtok_r(NULL, ";\n", &lasts);
222 222 }
223 223
224 224 if (stmt != NULL) {
225 225 break;
226 226 }
227 227 }
228 228
229 229 /*
230 230 * Ok, we have a statement, lets tokenize it. For
231 231 * simplicities sake we convert "OPCODE(arg1, arg2)" into
232 232 * "OPCODE arg1 arg2". This means that commas and parens are
233 233 * treated as whitespace. This can lead to some really messed
234 234 * up syntaxes that get assembled properly (such as nested
235 235 * calls, empty arguments, etc.) Hopefully people don't abuse
236 236 * this.
237 237 */
238 238 ls = NULL;
239 239 s = strtok_r(stmt, " \t\n(),", &ls);
240 240 cnt = 0;
241 241 tokcnt = 0;
242 242 while (cnt < 10) {
243 243 tokens[cnt++] = s;
244 244 if (s != NULL) {
245 245 tokcnt++;
246 246 s = strtok_r(NULL, " \t\n(),", &ls);
247 247 }
248 248 }
249 249 return (tokcnt);
250 250 }
251 251
252 252 static void
253 253 error(char *msg, ...)
254 254 {
255 255 va_list va;
256 256 char msgbuf[1024];
257 257
258 258 va_start(va, msg);
259 259 (void) vsnprintf(msgbuf, sizeof (msgbuf), msg, va);
260 260 va_end(va);
261 261
262 262 (void) fprintf(stderr, "Error: %s on line %d of %s\n", msgbuf, lineno,
263 263 infile);
264 264 errors++;
265 265 }
266 266
267 267 static sym_t *
268 268 find_symbol(char *name)
269 269 {
270 270 int i;
271 271
272 272 for (i = 0; i < nsyms; i++)
273 273 if (strcmp(symtab[i].name, name) == 0) {
274 274 return (&symtab[i]);
275 275 }
276 276
277 277 return (NULL);
278 278 }
279 279
280 280 static void
281 281 add_symbol(char *name, int type, int arg)
282 282 {
283 283 sym_t *sym;
284 284
285 285 if (nsyms >= MAX_SYMBOLS) {
286 286 error("Symbol table full");
287 287 exit(-1);
288 288 }
289 289
290 290 if (find_symbol(name) != NULL) {
291 291 error("Dublicate symbol '%s'", name);
292 292 return;
293 293 }
294 294
295 295 if (strlen(name) >= MAX_NAME) {
296 296 error("Symbol name '%s' too long", name);
297 297 exit(-1);
298 298 }
299 299
300 300 sym = &symtab[nsyms++];
301 301
302 302 (void) strcpy(sym->name, name);
303 303 sym->type = type;
304 304 sym->arg = arg;
305 305 }
306 306
307 307 static void
308 308 add_init(uint32_t gpr, uint32_t val, const char *name)
309 309 {
310 310 int n;
311 311
312 312 n = fle.ninit;
313 313 if (n >= MAX_GPR) {
314 314 error("Too many GPRs");
315 315 return;
316 316 }
317 317 fle.init[n].gpr = gpr;
318 318 fle.init[n].value = val;
319 319 if (name)
320 320 (void) strlcpy(fle.init[n].name, name,
321 321 sizeof (fle.init[n].name));
322 322 fle.ninit++;
323 323 }
324 324
325 325 static void
326 326 compile_gpr(char **tokens, int cnt)
327 327 {
328 328 CHECK_COUNT(tokens, cnt, 2, 2);
329 329
330 330 if (ngpr >= MAX_GPR)
331 331 error("Too many GPR variables");
332 332
333 333 add_symbol(tokens[1], SY_GPR, gpr_base + ngpr++);
334 334 }
335 335
336 336 static void
337 337 compile_rem(char **tokens, int cnt)
338 338 {
339 339 int i;
340 340
341 341 (void) strlcat(remarks, " *", sizeof (remarks));
342 342 for (i = 1; i < cnt; i++) {
343 343 (void) strlcat(remarks, " ", sizeof (remarks));
344 344 (void) strlcat(remarks, tokens[i], sizeof (remarks));
345 345 }
346 346 (void) strlcat(remarks, "\n", sizeof (remarks));
347 347 }
348 348
349 349 static void
350 350 declare_const(unsigned int gpr, char *value)
351 351 {
352 352 int n, intv;
353 353 float v;
354 354
355 355 n = fle.consts.nconst;
356 356
357 357 if (n >= MAX_CONST_PARMS) {
358 358 error("Too many constant parameters");
359 359 return;
360 360 }
361 361
362 362 if (*value == 'I') {
363 363 if (sscanf(&value[1], "%g", &v) != 1) {
364 364 error("Bad floating point value (%s)", value);
365 365 return;
366 366 }
367 367 intv = (int)v;
368 368 } else if (*value == '0' && value[1] == 'x') {
369 369 if (sscanf(&value[2], "%x", (unsigned *)&intv) != 1) {
370 370 error("Bad hexadecimal value (%s)", value);
371 371 return;
372 372 }
373 373 } else {
374 374 if (sscanf(value, "%g", &v) != 1) {
375 375 error("Bad floating point value (%s)", value);
376 376 return;
377 377 }
378 378 intv = (int)(v * 0x7fffffff);
379 379 }
380 380
381 381 fle.consts.consts[n].gpr = gpr;
382 382 fle.consts.consts[n].value = intv;
383 383 fle.consts.nconst = n + 1;
384 384
385 385 add_init(gpr, intv, NULL);
386 386 }
387 387
388 388 static void
389 389 compile_const(char **tokens, int cnt)
390 390 {
391 391 CHECK_COUNT(tokens, cnt, 2, 3);
392 392 char *name = tokens[1];
393 393 char *value = tokens[2] ? tokens[2] : tokens[1];
394 394
395 395 if (ngpr >= MAX_GPR)
396 396 error("Too many GPR variables");
397 397
398 398 declare_const(ngpr, value);
399 399
400 400 add_symbol(name, SY_GPR, gpr_base + ngpr++);
401 401 }
402 402
403 403 static void
404 404 compile_bool(char **tokens, int cnt)
405 405 {
406 406 char *parm, *def;
407 407 int n, num;
408 408
409 409 CHECK_COUNT(tokens, cnt, 3, 3);
410 410
411 411 parm = tokens[1];
412 412 def = tokens[2];
413 413
414 414 n = fle.parms.ngpr;
415 415 if (n >= MAX_GPR_PARMS) {
416 416 error("Too many GPR parameters");
417 417 return;
418 418 }
419 419
420 420 if (sscanf(def, "%d", &num) != 1) {
421 421 error("Bad integer value near '%s'", def);
422 422 return;
423 423 }
424 424
425 425 (void) strcpy(fle.parms.gpr[n].name, parm);
426 426 fle.parms.gpr[n].num = ngpr;
427 427 fle.parms.gpr[n].def = num;
428 428 fle.parms.ngpr = n + 1;
429 429
↓ open down ↓ |
429 lines elided |
↑ open up ↑ |
430 430 add_init(ngpr, num, parm);
431 431
432 432 add_symbol(parm, SY_PARM, gpr_base + ngpr++);
433 433 }
434 434
435 435 static void
436 436 compile_mono(char **tokens, int cnt)
437 437 {
438 438 char *parm, *def;
439 439 int n, num;
440 - char tmp[128];
441 440
442 441 CHECK_COUNT(tokens, cnt, 3, 3);
443 442
444 443 parm = tokens[1];
445 444 def = tokens[2];
446 445
447 446 n = fle.parms.ngpr;
448 447 if (n >= MAX_GPR_PARMS) {
449 448 error("Too many GPR parameters");
450 449 return;
451 450 }
452 451
453 452 if (sscanf(def, "%d", &num) != 1) {
454 453 error("Bad integer value near '%s'", def);
455 454 return;
456 455 }
457 456
458 457 (void) strcpy(fle.parms.gpr[n].name, parm);
459 458 fle.parms.gpr[n].num = ngpr;
460 459 fle.parms.gpr[n].def = num;
461 460 fle.parms.ngpr = n + 1;
462 461
463 462 add_init(ngpr, num, parm);
464 463
465 464 add_symbol(parm, SY_PARM, gpr_base + ngpr++);
466 465 }
467 466
468 467 static void
469 468 compile_stereo(char **tokens, int cnt)
470 469 {
471 470 char *parm, *def;
472 471 int n, num;
473 472 char tmp[128];
474 473
475 474 CHECK_COUNT(tokens, cnt, 3, 3);
476 475
477 476 parm = tokens[1];
478 477 def = tokens[2];
479 478
480 479 n = fle.parms.ngpr;
481 480 if (n >= MAX_GPR_PARMS) {
482 481 error("Too many GPR parameters");
483 482 return;
484 483 }
485 484
486 485 if (sscanf(def, "%d", &num) != 1) {
487 486 error("Bad integer value near '%s'", def);
488 487 return;
489 488 }
490 489
491 490 (void) strcpy(fle.parms.gpr[n].name, parm);
492 491 fle.parms.gpr[n].num = ngpr;
493 492 fle.parms.gpr[n].def = num | (num << 8);
494 493 fle.parms.ngpr = n + 1;
495 494
496 495 add_init(ngpr, num, parm);
497 496 add_init(ngpr + 1, num, NULL);
498 497
499 498 (void) sprintf(tmp, "%s_L", parm);
500 499 add_symbol(tmp, SY_PARM, gpr_base + ngpr++);
501 500 (void) sprintf(tmp, "%s_R", parm);
502 501 add_symbol(tmp, SY_PARM, gpr_base + ngpr++);
503 502 }
504 503
505 504 static void
506 505 compile_input(char **tokens, int cnt)
507 506 {
508 507 int num;
509 508
510 509 CHECK_COUNT(tokens, cnt, 3, 3);
511 510
512 511 if (sscanf(tokens[2], "%d", &num) != 1) {
513 512 error("Bad integer value near '%s'", tokens[2]);
514 513 return;
515 514 }
516 515
517 516 add_symbol(tokens[1], SY_INPUT, input_base + num);
518 517 }
519 518
520 519 static void
521 520 compile_send(char **tokens, int cnt)
522 521 {
523 522 int num;
524 523
525 524 CHECK_COUNT(tokens, cnt, 3, 3);
526 525
527 526 if (sscanf(tokens[2], "%d", &num) != 1) {
528 527 error("Bad integer near '%s'", tokens[2]);
529 528 return;
530 529 }
531 530
532 531 add_symbol(tokens[1], SY_FX, num);
533 532 }
534 533
535 534 static void
536 535 compile_output(char **tokens, int cnt)
537 536 {
538 537 int num;
539 538
540 539 CHECK_COUNT(tokens, cnt, 3, 3);
541 540
542 541 if (sscanf(tokens[2], "%d", &num) != 1) {
543 542 error("Bad integer value near '%s'", tokens[2]);
544 543 return;
545 544 }
546 545
547 546 add_symbol(tokens[1], SY_OUTPUT, output_base + num);
548 547 }
549 548
550 549 static void
551 550 compile_directive(char **tokens, int cnt)
552 551 {
553 552 if (strcmp(tokens[0], ".gpr") == 0) {
554 553 compile_gpr(tokens, cnt);
555 554 return;
556 555 }
557 556
558 557 if (strcmp(tokens[0], ".const") == 0) {
559 558 compile_const(tokens, cnt);
560 559 return;
561 560 }
562 561
563 562 if (strcmp(tokens[0], ".stereo") == 0) {
564 563 compile_stereo(tokens, cnt);
565 564 return;
566 565 }
567 566
568 567 if (strcmp(tokens[0], ".mono") == 0) {
569 568 compile_mono(tokens, cnt);
570 569 return;
571 570 }
572 571
573 572 if (strcmp(tokens[0], ".bool") == 0) {
574 573 compile_bool(tokens, cnt);
575 574 return;
576 575 }
577 576
578 577 if (strcmp(tokens[0], ".input") == 0) {
579 578 compile_input(tokens, cnt);
580 579 return;
581 580 }
582 581
583 582 if (strcmp(tokens[0], ".send") == 0) {
584 583 compile_send(tokens, cnt);
585 584 return;
586 585 }
587 586
588 587 if (strcmp(tokens[0], ".output") == 0) {
589 588 compile_output(tokens, cnt);
590 589 return;
591 590 }
592 591
593 592 if (strcmp(tokens[0], ".rem") == 0) {
594 593 compile_rem(tokens, cnt);
595 594 return;
596 595 }
597 596 if (strcmp(tokens[0], ".'") == 0) {
↓ open down ↓ |
147 lines elided |
↑ open up ↑ |
598 597 compile_rem(tokens, cnt);
599 598 return;
600 599 }
601 600
602 601 error("Unknown directive '%s'", tokens[0]);
603 602 }
604 603
605 604 static void
606 605 compile_asm(char **tokens, int cnt)
607 606 {
608 - char *parms[4];
609 607 sym_t *symbols[4];
610 608 #define EMIT(o, r, a, x, y) \
611 609 fle.code[pc*2] = ((x) << 10) | (y); \
612 610 fle.code[pc*2+1] = ((o) << 20) | ((r) << 10) | a; pc++
613 611 #define EMIT_AUDIGY(o, r, a, x, y) \
614 612 fle.code[pc*2] = ((x) << 12) | (y); \
615 613 fle.code[pc*2+1] = ((o) << 24) | ((r) << 12) | a; pc++
616 614
617 - int i, n = 0, nerr = 0;
615 + int i, nerr = 0;
618 616 int ninputs = 0;
619 617
620 618 CHECK_COUNT(tokens, cnt, 5, 5);
621 619
622 620 for (i = 0; i < 4; i++) {
623 621 if ((symbols[i] = find_symbol(tokens[i+1])) == NULL) {
624 622 (void) fprintf(stderr, "%s\n", tokens[i+1]);
625 623 nerr++;
626 624 error("Undefined symbol '%s'", tokens[i + 1]);
627 625 continue;
628 626 }
629 627
630 628 if (symbols[i]->type == SY_INPUT)
631 629 ninputs++;
632 630
633 631 if (symbols[i]->type == SY_ACCUM && i != 1)
634 632 error("Bad usage of 'accum' operand.");
635 633 }
636 634
637 635 if (nerr > 0)
638 636 return;
639 637
640 638 if (ninputs > 1) {
641 639 error("Attempt to access more than one input "
642 640 "GPRs by the same instruction");
643 641 }
644 642
645 643 for (i = 0; instructions[i].name != NULL; i++)
646 644 if (strcasecmp(tokens[0], instructions[i].name) == 0) {
647 645
648 646 if (is_audigy) {
649 647 EMIT_AUDIGY(instructions[i].opcode,
650 648 symbols[0]->arg,
651 649 symbols[1]->arg,
652 650 symbols[2]->arg,
653 651 symbols[3]->arg);
654 652 } else {
655 653 EMIT(instructions[i].opcode,
656 654 symbols[0]->arg,
657 655 symbols[1]->arg,
658 656 symbols[2]->arg,
659 657 symbols[3]->arg);
660 658 }
661 659
662 660 return;
663 661 }
664 662
665 663 error("Unrecognized instruction '%s'", tokens[0]);
666 664 }
667 665
668 666 static void
669 667 init_compiler(void)
670 668 {
671 669 char tmp[100];
672 670 int i;
673 671
674 672 (void) memset(&fle, 0, sizeof (fle));
675 673 /*
676 674 * Initialize few predefined GPR parameter registers. These
677 675 * definitions have to be in sync with the GPR_* macros in
678 676 * <sblive.h>.
679 677 */
680 678
681 679 /*
682 680 * Make sure we start at gpr id 2 for now; 0 and 1 may be used
683 681 * differently.
684 682 */
685 683 add_symbol("NULL", SY_DUMMY, gpr_base + ngpr++);
686 684 add_symbol("NULL_", SY_DUMMY, gpr_base + ngpr++);
687 685
688 686 pc = 0;
689 687
690 688 if (is_audigy) {
691 689 /* Initialize the code array with NOPs (AUDIGY) */
692 690 for (i = 0; i < 512; i++) {
693 691 fle.code[i * 2 + 0] = (0xc0 << 12) | 0xc0;
694 692 fle.code[i * 2 + 1] =
695 693 (0x06 << 24) | (0xc0 << 12) | 0xc0;
696 694 }
697 695
698 696 for (i = 0; i < 32; i++) {
699 697 (void) sprintf(tmp, "fx%d", i);
700 698 add_symbol(tmp, SY_FX, i);
701 699 }
702 700 } else {
703 701 /* Initialize the code array with NOPs (LIVE) */
704 702 for (i = 0; i < 512; i++) {
705 703 fle.code[i * 2 + 0] = 0x10040;
706 704 fle.code[i * 2 + 1] = 0x610040;
707 705 }
708 706
709 707 for (i = 0; i < 16; i++) {
710 708 (void) sprintf(tmp, "fx%d", i);
711 709 add_symbol(tmp, SY_FX, i);
712 710 }
713 711 }
714 712
715 713 /*
716 714 * Constants
717 715 */
718 716
719 717 if (is_audigy) {
720 718 /* Audigy symbols */
721 719 add_symbol("0", SY_CONST, 0x0c0);
722 720 add_symbol("1", SY_CONST, 0x0c1);
723 721 add_symbol("2", SY_CONST, 0x0c2);
724 722 add_symbol("3", SY_CONST, 0x0c3);
725 723 add_symbol("4", SY_CONST, 0x0c4);
726 724 add_symbol("8", SY_CONST, 0x0c5);
727 725 add_symbol("16", SY_CONST, 0x0c6);
728 726 add_symbol("32", SY_CONST, 0x0c7);
729 727 add_symbol("256", SY_CONST, 0x0c8);
730 728 add_symbol("65536", SY_CONST, 0x0c9);
731 729
732 730 add_symbol("2048", SY_CONST, 0x0ca);
733 731 add_symbol("0x800", SY_CONST, 0x0ca);
734 732
735 733 add_symbol("2^28", SY_CONST, 0x0cb);
736 734 add_symbol("0x10000000", SY_CONST, 0x0cb);
737 735
738 736 add_symbol("2^29", SY_CONST, 0x0cc);
739 737 add_symbol("0x20000000", SY_CONST, 0x0cc);
740 738
741 739 add_symbol("2^30", SY_CONST, 0x0cd);
742 740 add_symbol("0x40000000", SY_CONST, 0x0cd);
743 741
744 742 add_symbol("2^31", SY_CONST, 0x0ce);
745 743 add_symbol("0x80000000", SY_CONST, 0x0ce);
746 744
747 745 add_symbol("0x7fffffff", SY_CONST, 0x0cf);
748 746
749 747 add_symbol("0xffffffff", SY_CONST, 0x0d0);
750 748 add_symbol("-1", SY_CONST, 0x0d0);
751 749
752 750 add_symbol("0xfffffffe", SY_CONST, 0x0d1);
753 751 add_symbol("-2", SY_CONST, 0x0d1);
754 752
755 753 add_symbol("0xc0000000", SY_CONST, 0x0d2);
756 754
757 755 add_symbol("0x4f1bbcdc", SY_CONST, 0x0d3);
758 756
759 757 add_symbol("0x5a7ef9db", SY_CONST, 0x0d4);
760 758
761 759 add_symbol("0x100000", SY_CONST, 0x0d5);
762 760 add_symbol("accum", SY_ACCUM, 0x0d6);
763 761 add_symbol("CCR", SY_CONST, 0x0d7);
764 762
765 763 add_symbol("noise_L", SY_CONST, 0x0d8);
766 764 add_symbol("noise_R", SY_CONST, 0x0d9);
767 765 add_symbol("IRQREQ", SY_CONST, 0x0da);
768 766 } else {
769 767 /* SB Live symbols */
770 768 add_symbol("0", SY_CONST, 0x040);
771 769 add_symbol("1", SY_CONST, 0x041);
772 770 add_symbol("2", SY_CONST, 0x042);
773 771 add_symbol("3", SY_CONST, 0x043);
774 772 add_symbol("4", SY_CONST, 0x044);
775 773 add_symbol("8", SY_CONST, 0x045);
776 774 add_symbol("16", SY_CONST, 0x046);
777 775 add_symbol("32", SY_CONST, 0x047);
778 776 add_symbol("256", SY_CONST, 0x048);
779 777 add_symbol("65536", SY_CONST, 0x049);
780 778
781 779 add_symbol("2^23", SY_CONST, 0x04a);
782 780 add_symbol("0x80000", SY_CONST, 0x04a);
783 781
784 782 add_symbol("2^28", SY_CONST, 0x04b);
785 783 add_symbol("0x10000000", SY_CONST, 0x04b);
786 784
787 785 add_symbol("2^29", SY_CONST, 0x04c);
788 786 add_symbol("0x20000000", SY_CONST, 0x04c);
789 787
790 788 add_symbol("2^30", SY_CONST, 0x04d);
791 789 add_symbol("0x40000000", SY_CONST, 0x04d);
792 790
793 791 add_symbol("2^31", SY_CONST, 0x04e);
794 792 add_symbol("0x80000000", SY_CONST, 0x04e);
795 793
796 794 add_symbol("0x7fffffff", SY_CONST, 0x04f);
797 795
798 796 add_symbol("0xffffffff", SY_CONST, 0x050);
799 797 add_symbol("-1", SY_CONST, 0x050);
800 798
801 799 add_symbol("0xfffffffe", SY_CONST, 0x051);
802 800 add_symbol("-2", SY_CONST, 0x051);
803 801
804 802 add_symbol("accum", SY_ACCUM, 0x056);
805 803 add_symbol("CCR", SY_CONST, 0x057);
↓ open down ↓ |
178 lines elided |
↑ open up ↑ |
806 804
807 805 add_symbol("noise_L", SY_CONST, 0x058);
808 806 add_symbol("noise_R", SY_CONST, 0x059);
809 807 add_symbol("IRQREQ", SY_CONST, 0x05a);
810 808 }
811 809 }
812 810
813 811 static void
814 812 produce_map(char *name)
815 813 {
816 - char fname[1024];
817 814 int i;
818 815 FILE *f;
819 816
820 817 if ((f = fopen(name, "w")) == NULL) {
821 818 perror(name);
822 819 return;
823 820 }
824 821
825 822 (void) fprintf(f, "%d\n", pc);
826 823
827 824 for (i = 0; i < nsyms; i++) {
828 825 (void) fprintf(f, "%04x %x %s\n",
829 826 symtab[i].arg, symtab[i].type, symtab[i].name);
830 827 }
831 828
832 829 (void) fclose(f);
833 830 if (verbose) {
834 831 (void) fprintf(stderr,
835 832 "No errors detected - Map written to %s\n", name);
836 833 }
837 834 }
838 835
839 836 static void
840 837 produce_output(char *fname)
841 838 {
842 839 int fd;
843 840
844 841 if ((fd = creat(fname, 0644)) == -1) {
845 842 perror(fname);
846 843 exit(-1);
847 844 }
848 845
849 846 if (write(fd, &fle, sizeof (fle)) != sizeof (fle)) {
850 847 perror(fname);
851 848 exit(-1);
852 849 }
853 850
854 851 if (verbose) {
855 852 (void) fprintf(stderr,
856 853 "No errors detected - Binary written to %s\n",
857 854 fname);
858 855 }
859 856
860 857 (void) close(fd);
861 858 }
862 859
863 860 static void
864 861 produce_header(char *fname, char *prefix)
865 862 {
866 863 FILE *f;
867 864 char *s;
868 865 char sname[MAXPATHLEN + 1];
869 866 char dname[MAXPATHLEN + 1];
870 867 int i;
871 868 clock_t now;
872 869 char when[128];
873 870
874 871 /* get basename */
875 872 if (prefix == NULL) {
876 873 s = strrchr(fname, '/');
877 874 s = (s == NULL) ? fname : s + 1;
878 875 } else {
879 876 s = prefix;
880 877 }
881 878 (void) strlcpy(sname, s, sizeof (sname));
882 879
883 880 /* strip off any extension */
884 881 s = strchr(sname, '.');
885 882 if (s != NULL) {
886 883 *s = 0;
887 884 }
888 885 if ((f = fopen(fname, "w")) == NULL) {
889 886 perror(fname);
890 887 return;
891 888 }
892 889
893 890 if (remarks[0] != 0) {
894 891 (void) fprintf(f, "/*\n%s */\n", remarks);
895 892 }
896 893 now = time(NULL);
897 894 strftime(when, sizeof (when), "%c", localtime(&now));
898 895 (void) fprintf(f, banner, progname, when);
899 896
900 897 (void) strlcpy(dname, prefix ? prefix : sname, sizeof (dname));
901 898 for (i = 0; dname[i]; i++) {
902 899 dname[i] = toupper(dname[i]);
903 900 if (!isalnum(dname[i])) {
904 901 dname[i] = '_';
905 902 }
906 903 }
907 904
908 905 for (i = 0; i < fle.parms.ngpr; i++) {
909 906 (void) fprintf(f, "#define\t%s_%s\t\t%d\n",
910 907 dname, fle.parms.gpr[i].name, fle.parms.gpr[i].num);
911 908 }
912 909
913 910 (void) fprintf(f, "\n");
914 911
915 912 if (parms_only)
916 913 goto done;
917 914
918 915 (void) fprintf(f, "uint32_t %s_code[] = {\n", sname);
919 916
920 917 for (i = 0; i < pc * 2; i++) {
921 918 if (i == 0) {
922 919 (void) fprintf(f, "\t0x%08xU", fle.code[i]);
923 920 } else if ((i % 4) == 0) {
924 921 (void) fprintf(f, ",\n\t0x%08xU", fle.code[i]);
925 922 } else {
926 923 (void) fprintf(f, ", 0x%08xU", fle.code[i]);
927 924 }
928 925 }
929 926 (void) fprintf(f, "\n};\n");
930 927
931 928 (void) fprintf(f, "uint32_t %s_ninit = %d;\n", sname, fle.ninit);
932 929 (void) fprintf(f, "uint32_t %s_init[] = {\n", sname);
933 930
934 931 for (i = 0; i < fle.ninit; i++) {
935 932 if (fle.init[i].name[0]) {
936 933 (void) fprintf(f, "\t%u, 0x%x%s,\t/* %s */\n",
937 934 fle.init[i].gpr, fle.init[i].value,
938 935 fle.init[i].value >= 0x80000000U ? "U" : "",
939 936 fle.init[i].name);
940 937 } else {
941 938 (void) fprintf(f, "\t%u, 0x%x%s,\n",
942 939 fle.init[i].gpr, fle.init[i].value,
943 940 fle.init[i].value >= 0x80000000U ? "U" : "");
944 941 }
945 942 }
946 943 (void) fprintf(f, "};\n");
947 944
948 945 done:
949 946 (void) fclose(f);
↓ open down ↓ |
123 lines elided |
↑ open up ↑ |
950 947 if (verbose) {
951 948 (void) fprintf(stderr,
952 949 "No errors detected - Header written to %s\n",
953 950 fname);
954 951 }
955 952 }
956 953
957 954 int
958 955 main(int argc, char *argv[])
959 956 {
960 - char line[4096], *p, *s, *outfile;
961 - char *iline;
957 + char *outfile;
962 958 int i;
963 959 FILE *input;
964 960 char *tokens[10];
965 961 int tokcnt;
966 962 char *mapfile = NULL;
967 963 char *header = NULL;
968 964 char *prefix = NULL;
969 965
970 966 outfile = NULL;
971 967 infile = NULL;
972 968 input = NULL;
973 969 progname = argv[0];
974 970
975 971 while ((i = getopt(argc, argv, "m:h:o:i:P:021v")) != EOF) {
976 972 switch (i) {
977 973 case 'o':
978 974 outfile = optarg;
979 975 break;
980 976 case 'i':
981 977 infile = strdup(optarg);
982 978 break;
983 979 case 'm':
984 980 mapfile = optarg;
985 981 break;
986 982 case 'P':
987 983 prefix = optarg;
988 984 break;
989 985 case 'h':
990 986 header = optarg;
991 987 break;
992 988 case '0':
993 989 parms_only = 1;
994 990 break;
995 991 case '2':
996 992 is_audigy = 1;
997 993 break;
998 994 case '1':
999 995 is_audigy = 0;
1000 996 break;
1001 997 case 'v':
1002 998 verbose++;
1003 999 break;
1004 1000 default:
1005 1001 (void) fprintf(stderr,
1006 1002 "usage: %s [-m <map>] [-h <header>] "
1007 1003 "[-o <binary>] [-i <source>] [-2|-1]",
1008 1004 progname);
1009 1005 exit(-1);
1010 1006 break;
1011 1007 }
1012 1008 }
1013 1009
1014 1010 if ((outfile == NULL) && (mapfile == NULL) && (header == NULL)) {
1015 1011 outfile = "dsp.bin";
1016 1012 }
1017 1013
1018 1014 if (infile) {
1019 1015 input = fopen(infile, "r");
1020 1016 if (input == NULL) {
1021 1017 perror(infile);
1022 1018 exit(-1);
1023 1019 }
1024 1020 } else {
1025 1021 infile = strdup("<stdin>");
1026 1022 input = stdin;
1027 1023 }
1028 1024
1029 1025 if (is_audigy) {
1030 1026 gpr_base = 0x400;
1031 1027 input_base = 0x40;
1032 1028 output_base = 0x60;
1033 1029 if (verbose)
1034 1030 (void) fprintf(stderr, "Compiling for SB Audigy\n");
1035 1031 } else {
1036 1032 if (verbose)
1037 1033 (void) fprintf(stderr, "Compiling for SB Live\n");
1038 1034 }
1039 1035
1040 1036 init_compiler();
1041 1037
1042 1038 while ((tokcnt = getaline(input, tokens)) != -1) {
1043 1039 /* skip empty lines */
1044 1040 if (tokcnt == 0) {
1045 1041 continue;
1046 1042 }
1047 1043
1048 1044 if (strcmp(tokens[0], "#") == 0) {
1049 1045 int num;
1050 1046 if ((tokcnt >= 3) &&
1051 1047 (sscanf(tokens[1], "%d", &num) == 1)) {
1052 1048 lineno = num;
1053 1049 free(infile);
1054 1050 infile = strdup(tokens[2]);
1055 1051 /* we don't want to count the # directive */
1056 1052 lineno--;
1057 1053 }
1058 1054
1059 1055 /* unknown # directive? muddle on... */
1060 1056 continue;
1061 1057 }
1062 1058 if (*tokens[0] == '.') {
1063 1059 compile_directive(tokens, tokcnt);
1064 1060 } else {
1065 1061 compile_asm(tokens, tokcnt);
1066 1062 }
1067 1063 }
1068 1064
1069 1065 if (lineno < 1) {
1070 1066 error("Empty input");
1071 1067 }
1072 1068
1073 1069 if (errors == 0) {
1074 1070 if (verbose) {
1075 1071 (void) fprintf(stderr,
1076 1072 "%d instructions out of 512 assembled\n", pc);
1077 1073 }
1078 1074
1079 1075 if (outfile)
1080 1076 produce_output(outfile);
1081 1077 if (mapfile)
1082 1078 produce_map(mapfile);
1083 1079 if (header)
1084 1080 produce_header(header, prefix);
1085 1081 }
1086 1082
1087 1083 if (errors > 0) {
1088 1084 (void) fprintf(stderr, "%d errors - compile failed\n", errors);
1089 1085 exit(-1);
1090 1086 }
1091 1087
1092 1088 return (0);
1093 1089 }
↓ open down ↓ |
122 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX