110913Sgdamore@opensolaris.org /*
210913Sgdamore@opensolaris.org * CDDL HEADER START
310913Sgdamore@opensolaris.org *
410913Sgdamore@opensolaris.org * The contents of this file are subject to the terms of the
510913Sgdamore@opensolaris.org * Common Development and Distribution License (the "License").
610913Sgdamore@opensolaris.org * You may not use this file except in compliance with the License.
710913Sgdamore@opensolaris.org *
810913Sgdamore@opensolaris.org * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
910913Sgdamore@opensolaris.org * or http://www.opensolaris.org/os/licensing.
1010913Sgdamore@opensolaris.org * See the License for the specific language governing permissions
1110913Sgdamore@opensolaris.org * and limitations under the License.
1210913Sgdamore@opensolaris.org *
1310913Sgdamore@opensolaris.org * When distributing Covered Code, include this CDDL HEADER in each
1410913Sgdamore@opensolaris.org * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1510913Sgdamore@opensolaris.org * If applicable, add the following below this CDDL HEADER, with the
1610913Sgdamore@opensolaris.org * fields enclosed by brackets "[]" replaced with your own identifying
1710913Sgdamore@opensolaris.org * information: Portions Copyright [yyyy] [name of copyright owner]
1810913Sgdamore@opensolaris.org *
1910913Sgdamore@opensolaris.org * CDDL HEADER END
2010913Sgdamore@opensolaris.org */
2110913Sgdamore@opensolaris.org
2210913Sgdamore@opensolaris.org /*
23*13093SRoger.Faulkner@Oracle.COM * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
2410913Sgdamore@opensolaris.org */
2510913Sgdamore@opensolaris.org
2610913Sgdamore@opensolaris.org /*
2710913Sgdamore@opensolaris.org * Assembler for Emu10k1
2810913Sgdamore@opensolaris.org */
2910913Sgdamore@opensolaris.org /*
3010913Sgdamore@opensolaris.org * Copyright (C) 4Front Technologies 1996-2008.
3110913Sgdamore@opensolaris.org */
3210913Sgdamore@opensolaris.org
3310913Sgdamore@opensolaris.org #include <stdio.h>
3410913Sgdamore@opensolaris.org #include <stdlib.h>
3510913Sgdamore@opensolaris.org #include <unistd.h>
3610913Sgdamore@opensolaris.org #include <fcntl.h>
3710913Sgdamore@opensolaris.org #include <string.h>
3810913Sgdamore@opensolaris.org #include <stdarg.h>
3910913Sgdamore@opensolaris.org #include <ctype.h>
4010913Sgdamore@opensolaris.org #include <sys/param.h>
4110913Sgdamore@opensolaris.org
4210913Sgdamore@opensolaris.org #define MAX_GPR 256
4310913Sgdamore@opensolaris.org #define MAX_GPR_PARMS 60
4410913Sgdamore@opensolaris.org #define MAX_CONST_PARMS 128
4510913Sgdamore@opensolaris.org #define GPR_NAME_SIZE 32
4610913Sgdamore@opensolaris.org
4710913Sgdamore@opensolaris.org typedef struct {
4810913Sgdamore@opensolaris.org char name[GPR_NAME_SIZE];
4910913Sgdamore@opensolaris.org unsigned int num;
5010913Sgdamore@opensolaris.org int type;
5110913Sgdamore@opensolaris.org int def;
5210913Sgdamore@opensolaris.org } gpr_t;
5310913Sgdamore@opensolaris.org
5410913Sgdamore@opensolaris.org typedef struct {
5510913Sgdamore@opensolaris.org unsigned int gpr;
5610913Sgdamore@opensolaris.org unsigned int value;
5710913Sgdamore@opensolaris.org } const_t;
5810913Sgdamore@opensolaris.org
5910913Sgdamore@opensolaris.org typedef struct {
6010913Sgdamore@opensolaris.org unsigned int ngpr;
6110913Sgdamore@opensolaris.org
6210913Sgdamore@opensolaris.org gpr_t gpr[MAX_GPR_PARMS];
6310913Sgdamore@opensolaris.org } gpr_info;
6410913Sgdamore@opensolaris.org
6510913Sgdamore@opensolaris.org typedef struct {
6610913Sgdamore@opensolaris.org unsigned int nconst;
6710913Sgdamore@opensolaris.org
6810913Sgdamore@opensolaris.org const_t consts[MAX_CONST_PARMS];
6910913Sgdamore@opensolaris.org } const_info;
7010913Sgdamore@opensolaris.org
7110913Sgdamore@opensolaris.org typedef struct {
7210913Sgdamore@opensolaris.org unsigned int code[1024];
7310913Sgdamore@opensolaris.org gpr_info parms;
7410913Sgdamore@opensolaris.org const_info consts;
7510913Sgdamore@opensolaris.org int ninit;
7610913Sgdamore@opensolaris.org struct {
7710913Sgdamore@opensolaris.org uint32_t gpr;
7810913Sgdamore@opensolaris.org uint32_t value;
7910913Sgdamore@opensolaris.org char name[GPR_NAME_SIZE];
8010913Sgdamore@opensolaris.org } init[MAX_GPR];
8110913Sgdamore@opensolaris.org } emu10k1_file;
8210913Sgdamore@opensolaris.org
8310913Sgdamore@opensolaris.org #define MAX_NAME 64
8410913Sgdamore@opensolaris.org #define MAX_SYMBOLS 1024
8510913Sgdamore@opensolaris.org
8610913Sgdamore@opensolaris.org static int parms_only = 0;
8710913Sgdamore@opensolaris.org static int is_audigy = 0;
8810913Sgdamore@opensolaris.org static int verbose = 0;
8910913Sgdamore@opensolaris.org
9010913Sgdamore@opensolaris.org static int gpr_base = 0x100;
9110913Sgdamore@opensolaris.org static int input_base = 0x10;
9210913Sgdamore@opensolaris.org static int output_base = 0x20;
9310913Sgdamore@opensolaris.org
9410913Sgdamore@opensolaris.org static char *progname;
9510913Sgdamore@opensolaris.org
9610913Sgdamore@opensolaris.org typedef struct {
9710913Sgdamore@opensolaris.org char name[MAX_NAME];
9810913Sgdamore@opensolaris.org int type;
9910913Sgdamore@opensolaris.org #define SY_DUMMY 0
10010913Sgdamore@opensolaris.org #define SY_GPR 1
10110913Sgdamore@opensolaris.org #define SY_INPUT 2
10210913Sgdamore@opensolaris.org #define SY_OUTPUT 3
10310913Sgdamore@opensolaris.org #define SY_CONST 4
10410913Sgdamore@opensolaris.org #define SY_FX 5
10510913Sgdamore@opensolaris.org #define SY_ACCUM 6
10610913Sgdamore@opensolaris.org #define SY_PARM 7
10710913Sgdamore@opensolaris.org int arg;
10810913Sgdamore@opensolaris.org } sym_t;
10910913Sgdamore@opensolaris.org
11010913Sgdamore@opensolaris.org typedef struct {
11110913Sgdamore@opensolaris.org char *name;
11210913Sgdamore@opensolaris.org int opcode;
11310913Sgdamore@opensolaris.org } instruction_t;
11410913Sgdamore@opensolaris.org
11510913Sgdamore@opensolaris.org static char remarks[2048] = "";
11610913Sgdamore@opensolaris.org static char *banner =
11710913Sgdamore@opensolaris.org "/*\n"
11810913Sgdamore@opensolaris.org " * Note: This file was automatically generated by %s\n"
11910913Sgdamore@opensolaris.org " * on %s.\n"
12010913Sgdamore@opensolaris.org " */\n";
12110913Sgdamore@opensolaris.org
12210913Sgdamore@opensolaris.org /*
12310913Sgdamore@opensolaris.org * Instructions. Each instruction takes 4 arguments, R, A, X, and Y.
12410913Sgdamore@opensolaris.org */
12510913Sgdamore@opensolaris.org static instruction_t instructions[] = {
12610913Sgdamore@opensolaris.org { "MACS", 0x0}, /* R = A + (X * Y >> 31); saturation */
12710913Sgdamore@opensolaris.org { "MACS1", 0x1}, /* R = A + (-X * Y >> 31); saturation */
12810913Sgdamore@opensolaris.org { "MACW", 0x2}, /* R = A + (X * Y >> 31); wraparound */
12910913Sgdamore@opensolaris.org { "MACW1", 0x3}, /* R = A + (-X * Y >> 31); wraparound */
13010913Sgdamore@opensolaris.org { "MACINTS", 0x4}, /* R = A + (X * Y); saturation */
13110913Sgdamore@opensolaris.org { "MACINTW", 0x5}, /* R = A + (X * Y); wraparound */
13210913Sgdamore@opensolaris.org { "SUM", 0x6}, /* R = A + X + Y; saturation */
13310913Sgdamore@opensolaris.org { "ACC3", 0x6}, /* R = A + X + Y; saturation */
13410913Sgdamore@opensolaris.org { "MACMV", 0x7}, /* R = A, acc += X * Y >> 31 */
13510913Sgdamore@opensolaris.org { "ANDXOR", 0x8}, /* R = (A & X) ^ Y */
13610913Sgdamore@opensolaris.org { "TSTNEG", 0x9}, /* R = (A >= Y) ? X : ~X */
13710913Sgdamore@opensolaris.org { "LIMIT", 0xa}, /* R = (A >= Y) ? X : Y */
13810913Sgdamore@opensolaris.org { "LIMIT1", 0xb}, /* R = (A < Y) ? X : Y */
13910913Sgdamore@opensolaris.org { "LOG", 0xc}, /* R = ... (log?) */
14010913Sgdamore@opensolaris.org { "EXP", 0xd}, /* R = ... (exp?) */
14110913Sgdamore@opensolaris.org { "INTERP", 0xe}, /* R = A + (X * (Y - A) >> 31) */
14210913Sgdamore@opensolaris.org { "SKIP", 0xf}, /* R, CCR, CC_TEST, COUNT */
14310913Sgdamore@opensolaris.org { NULL, 0}
14410913Sgdamore@opensolaris.org };
14510913Sgdamore@opensolaris.org
14610913Sgdamore@opensolaris.org #define CHECK_COUNT(tokens, cnt, mincnt, maxcnt) \
14710913Sgdamore@opensolaris.org if (cnt < mincnt) { \
14810913Sgdamore@opensolaris.org error("Too few parameters for '%s' (have %d, min %d)", \
14910913Sgdamore@opensolaris.org tokens[0], cnt - 1, mincnt - 1); \
15010913Sgdamore@opensolaris.org return; \
15110913Sgdamore@opensolaris.org } \
15210913Sgdamore@opensolaris.org if (cnt > maxcnt) { \
15310913Sgdamore@opensolaris.org error("Too many parameters for '%s' (have %d, max %d)", \
15410913Sgdamore@opensolaris.org tokens[0], cnt - 1, maxcnt - 1); \
15510913Sgdamore@opensolaris.org return; \
15610913Sgdamore@opensolaris.org }
15710913Sgdamore@opensolaris.org
15810913Sgdamore@opensolaris.org static sym_t symtab[MAX_SYMBOLS];
15910913Sgdamore@opensolaris.org static int nsyms = 0;
16010913Sgdamore@opensolaris.org
16110913Sgdamore@opensolaris.org static int lineno = 0, errors = 0;
16210913Sgdamore@opensolaris.org static emu10k1_file fle;
16310913Sgdamore@opensolaris.org static int pc;
16410913Sgdamore@opensolaris.org
16510913Sgdamore@opensolaris.org static int ngpr = 0;
16610913Sgdamore@opensolaris.org static char *infile;
16710913Sgdamore@opensolaris.org
16810913Sgdamore@opensolaris.org static int
getaline(FILE * input,char ** tokens)169*13093SRoger.Faulkner@Oracle.COM getaline(FILE *input, char **tokens)
17010913Sgdamore@opensolaris.org {
17110913Sgdamore@opensolaris.org char *s, *ls;
17210913Sgdamore@opensolaris.org static char *stmt = NULL, *lasts = NULL;
17310913Sgdamore@opensolaris.org static char line[4096];
17410913Sgdamore@opensolaris.org int cnt, tokcnt;
17510913Sgdamore@opensolaris.org
17610913Sgdamore@opensolaris.org for (;;) {
17710913Sgdamore@opensolaris.org
17810913Sgdamore@opensolaris.org if (stmt == NULL) {
17910913Sgdamore@opensolaris.org if (fgets(line, sizeof (line), input) == NULL)
18010913Sgdamore@opensolaris.org return (-1);
18110913Sgdamore@opensolaris.org lineno++;
18210913Sgdamore@opensolaris.org
18310913Sgdamore@opensolaris.org /*
18410913Sgdamore@opensolaris.org * Special handling for .' comments. We use
18510913Sgdamore@opensolaris.org * .' as a keyword to ensure that entire
18610913Sgdamore@opensolaris.org * comment makes it through the C preprocessor
18710913Sgdamore@opensolaris.org * unmolested. We also need to make sure *we*
18810913Sgdamore@opensolaris.org * don't molest it either. The comment will
18910913Sgdamore@opensolaris.org * be exported to any resulting header,
19010913Sgdamore@opensolaris.org * allowing us to pass through copyright and
19110913Sgdamore@opensolaris.org * other information from the source file to
19210913Sgdamore@opensolaris.org * the resulting header.
19310913Sgdamore@opensolaris.org */
19410913Sgdamore@opensolaris.org s = line;
19510913Sgdamore@opensolaris.org s += strspn(s, " \t");
19610913Sgdamore@opensolaris.org if ((strncmp(s, ".'", 2) == 0) &&
19710913Sgdamore@opensolaris.org (strchr(" \t\n", s[2]) != NULL)) {
19810913Sgdamore@opensolaris.org /* chop off trailing new line */
19910913Sgdamore@opensolaris.org (void) strtok(line, "\n");
20010913Sgdamore@opensolaris.org tokens[0] = s;
20110913Sgdamore@opensolaris.org s += 2;
20210913Sgdamore@opensolaris.org s += strspn(s, " \t");
20310913Sgdamore@opensolaris.org if ((s[0] == '\'') &&
20410913Sgdamore@opensolaris.org (s[strlen(s) - 1] == '\'')) {
20510913Sgdamore@opensolaris.org s[strlen(s) - 1] = 0;
20610913Sgdamore@opensolaris.org s++;
20710913Sgdamore@opensolaris.org }
20810913Sgdamore@opensolaris.org tokens[1] = s;
20910913Sgdamore@opensolaris.org tokens[0][2] = 0;
21010913Sgdamore@opensolaris.org tokens[2] = NULL;
21110913Sgdamore@opensolaris.org stmt = NULL;
21210913Sgdamore@opensolaris.org return (strlen(tokens[1]) ? 2 : 1);
21310913Sgdamore@opensolaris.org }
21410913Sgdamore@opensolaris.org
21510913Sgdamore@opensolaris.org /* strip off any C++ style comments that CPP missed */
21610913Sgdamore@opensolaris.org if ((s = strstr(line, "//")) != NULL) {
21710913Sgdamore@opensolaris.org *s = NULL;
21810913Sgdamore@opensolaris.org }
21910913Sgdamore@opensolaris.org stmt = strtok_r(line, ";\n", &lasts);
22010913Sgdamore@opensolaris.org } else {
22110913Sgdamore@opensolaris.org stmt = strtok_r(NULL, ";\n", &lasts);
22210913Sgdamore@opensolaris.org }
22310913Sgdamore@opensolaris.org
22410913Sgdamore@opensolaris.org if (stmt != NULL) {
22510913Sgdamore@opensolaris.org break;
22610913Sgdamore@opensolaris.org }
22710913Sgdamore@opensolaris.org }
22810913Sgdamore@opensolaris.org
22910913Sgdamore@opensolaris.org /*
23010913Sgdamore@opensolaris.org * Ok, we have a statement, lets tokenize it. For
23110913Sgdamore@opensolaris.org * simplicities sake we convert "OPCODE(arg1, arg2)" into
23210913Sgdamore@opensolaris.org * "OPCODE arg1 arg2". This means that commas and parens are
23310913Sgdamore@opensolaris.org * treated as whitespace. This can lead to some really messed
23410913Sgdamore@opensolaris.org * up syntaxes that get assembled properly (such as nested
23510913Sgdamore@opensolaris.org * calls, empty arguments, etc.) Hopefully people don't abuse
23610913Sgdamore@opensolaris.org * this.
23710913Sgdamore@opensolaris.org */
23810913Sgdamore@opensolaris.org ls = NULL;
23910913Sgdamore@opensolaris.org s = strtok_r(stmt, " \t\n(),", &ls);
24010913Sgdamore@opensolaris.org cnt = 0;
24110913Sgdamore@opensolaris.org tokcnt = 0;
24210913Sgdamore@opensolaris.org while (cnt < 10) {
24310913Sgdamore@opensolaris.org tokens[cnt++] = s;
24410913Sgdamore@opensolaris.org if (s != NULL) {
24510913Sgdamore@opensolaris.org tokcnt++;
24610913Sgdamore@opensolaris.org s = strtok_r(NULL, " \t\n(),", &ls);
24710913Sgdamore@opensolaris.org }
24810913Sgdamore@opensolaris.org }
24910913Sgdamore@opensolaris.org return (tokcnt);
25010913Sgdamore@opensolaris.org }
25110913Sgdamore@opensolaris.org
25210913Sgdamore@opensolaris.org static void
error(char * msg,...)25310913Sgdamore@opensolaris.org error(char *msg, ...)
25410913Sgdamore@opensolaris.org {
25510913Sgdamore@opensolaris.org va_list va;
25610913Sgdamore@opensolaris.org char msgbuf[1024];
25710913Sgdamore@opensolaris.org
25810913Sgdamore@opensolaris.org va_start(va, msg);
25910913Sgdamore@opensolaris.org (void) vsnprintf(msgbuf, sizeof (msgbuf), msg, va);
26010913Sgdamore@opensolaris.org va_end(va);
26110913Sgdamore@opensolaris.org
26210913Sgdamore@opensolaris.org (void) fprintf(stderr, "Error: %s on line %d of %s\n", msgbuf, lineno,
26310913Sgdamore@opensolaris.org infile);
26410913Sgdamore@opensolaris.org errors++;
26510913Sgdamore@opensolaris.org }
26610913Sgdamore@opensolaris.org
26710913Sgdamore@opensolaris.org static sym_t *
find_symbol(char * name)26810913Sgdamore@opensolaris.org find_symbol(char *name)
26910913Sgdamore@opensolaris.org {
27010913Sgdamore@opensolaris.org int i;
27110913Sgdamore@opensolaris.org
27210913Sgdamore@opensolaris.org for (i = 0; i < nsyms; i++)
27310913Sgdamore@opensolaris.org if (strcmp(symtab[i].name, name) == 0) {
27410913Sgdamore@opensolaris.org return (&symtab[i]);
27510913Sgdamore@opensolaris.org }
27610913Sgdamore@opensolaris.org
27710913Sgdamore@opensolaris.org return (NULL);
27810913Sgdamore@opensolaris.org }
27910913Sgdamore@opensolaris.org
28010913Sgdamore@opensolaris.org static void
add_symbol(char * name,int type,int arg)28110913Sgdamore@opensolaris.org add_symbol(char *name, int type, int arg)
28210913Sgdamore@opensolaris.org {
28310913Sgdamore@opensolaris.org sym_t *sym;
28410913Sgdamore@opensolaris.org
28510913Sgdamore@opensolaris.org if (nsyms >= MAX_SYMBOLS) {
28610913Sgdamore@opensolaris.org error("Symbol table full");
28710913Sgdamore@opensolaris.org exit(-1);
28810913Sgdamore@opensolaris.org }
28910913Sgdamore@opensolaris.org
29010913Sgdamore@opensolaris.org if (find_symbol(name) != NULL) {
29110913Sgdamore@opensolaris.org error("Dublicate symbol '%s'", name);
29210913Sgdamore@opensolaris.org return;
29310913Sgdamore@opensolaris.org }
29410913Sgdamore@opensolaris.org
29510913Sgdamore@opensolaris.org if (strlen(name) >= MAX_NAME) {
29610913Sgdamore@opensolaris.org error("Symbol name '%s' too long", name);
29710913Sgdamore@opensolaris.org exit(-1);
29810913Sgdamore@opensolaris.org }
29910913Sgdamore@opensolaris.org
30010913Sgdamore@opensolaris.org sym = &symtab[nsyms++];
30110913Sgdamore@opensolaris.org
30210913Sgdamore@opensolaris.org (void) strcpy(sym->name, name);
30310913Sgdamore@opensolaris.org sym->type = type;
30410913Sgdamore@opensolaris.org sym->arg = arg;
30510913Sgdamore@opensolaris.org }
30610913Sgdamore@opensolaris.org
30710913Sgdamore@opensolaris.org static void
add_init(uint32_t gpr,uint32_t val,const char * name)30810913Sgdamore@opensolaris.org add_init(uint32_t gpr, uint32_t val, const char *name)
30910913Sgdamore@opensolaris.org {
31010913Sgdamore@opensolaris.org int n;
31110913Sgdamore@opensolaris.org
31210913Sgdamore@opensolaris.org n = fle.ninit;
31310913Sgdamore@opensolaris.org if (n >= MAX_GPR) {
31410913Sgdamore@opensolaris.org error("Too many GPRs");
31510913Sgdamore@opensolaris.org return;
31610913Sgdamore@opensolaris.org }
31710913Sgdamore@opensolaris.org fle.init[n].gpr = gpr;
31810913Sgdamore@opensolaris.org fle.init[n].value = val;
31910913Sgdamore@opensolaris.org if (name)
32010913Sgdamore@opensolaris.org (void) strlcpy(fle.init[n].name, name,
32110913Sgdamore@opensolaris.org sizeof (fle.init[n].name));
32210913Sgdamore@opensolaris.org fle.ninit++;
32310913Sgdamore@opensolaris.org }
32410913Sgdamore@opensolaris.org
32510913Sgdamore@opensolaris.org static void
compile_gpr(char ** tokens,int cnt)32610913Sgdamore@opensolaris.org compile_gpr(char **tokens, int cnt)
32710913Sgdamore@opensolaris.org {
32810913Sgdamore@opensolaris.org CHECK_COUNT(tokens, cnt, 2, 2);
32910913Sgdamore@opensolaris.org
33010913Sgdamore@opensolaris.org if (ngpr >= MAX_GPR)
33110913Sgdamore@opensolaris.org error("Too many GPR variables");
33210913Sgdamore@opensolaris.org
33310913Sgdamore@opensolaris.org add_symbol(tokens[1], SY_GPR, gpr_base + ngpr++);
33410913Sgdamore@opensolaris.org }
33510913Sgdamore@opensolaris.org
33610913Sgdamore@opensolaris.org static void
compile_rem(char ** tokens,int cnt)33710913Sgdamore@opensolaris.org compile_rem(char **tokens, int cnt)
33810913Sgdamore@opensolaris.org {
33910913Sgdamore@opensolaris.org int i;
34010913Sgdamore@opensolaris.org
34110913Sgdamore@opensolaris.org (void) strlcat(remarks, " *", sizeof (remarks));
34210913Sgdamore@opensolaris.org for (i = 1; i < cnt; i++) {
34310913Sgdamore@opensolaris.org (void) strlcat(remarks, " ", sizeof (remarks));
34410913Sgdamore@opensolaris.org (void) strlcat(remarks, tokens[i], sizeof (remarks));
34510913Sgdamore@opensolaris.org }
34610913Sgdamore@opensolaris.org (void) strlcat(remarks, "\n", sizeof (remarks));
34710913Sgdamore@opensolaris.org }
34810913Sgdamore@opensolaris.org
34910913Sgdamore@opensolaris.org static void
declare_const(unsigned int gpr,char * value)35010913Sgdamore@opensolaris.org declare_const(unsigned int gpr, char *value)
35110913Sgdamore@opensolaris.org {
35210913Sgdamore@opensolaris.org int n, intv;
35310913Sgdamore@opensolaris.org float v;
35410913Sgdamore@opensolaris.org
35510913Sgdamore@opensolaris.org n = fle.consts.nconst;
35610913Sgdamore@opensolaris.org
35710913Sgdamore@opensolaris.org if (n >= MAX_CONST_PARMS) {
35810913Sgdamore@opensolaris.org error("Too many constant parameters");
35910913Sgdamore@opensolaris.org return;
36010913Sgdamore@opensolaris.org }
36110913Sgdamore@opensolaris.org
36210913Sgdamore@opensolaris.org if (*value == 'I') {
36310913Sgdamore@opensolaris.org if (sscanf(&value[1], "%g", &v) != 1) {
36410913Sgdamore@opensolaris.org error("Bad floating point value (%s)", value);
36510913Sgdamore@opensolaris.org return;
36610913Sgdamore@opensolaris.org }
36710913Sgdamore@opensolaris.org intv = (int)v;
36810913Sgdamore@opensolaris.org } else if (*value == '0' && value[1] == 'x') {
36910913Sgdamore@opensolaris.org if (sscanf(&value[2], "%x", (unsigned *)&intv) != 1) {
37010913Sgdamore@opensolaris.org error("Bad hexadecimal value (%s)", value);
37110913Sgdamore@opensolaris.org return;
37210913Sgdamore@opensolaris.org }
37310913Sgdamore@opensolaris.org } else {
37410913Sgdamore@opensolaris.org if (sscanf(value, "%g", &v) != 1) {
37510913Sgdamore@opensolaris.org error("Bad floating point value (%s)", value);
37610913Sgdamore@opensolaris.org return;
37710913Sgdamore@opensolaris.org }
37810913Sgdamore@opensolaris.org intv = (int)(v * 0x7fffffff);
37910913Sgdamore@opensolaris.org }
38010913Sgdamore@opensolaris.org
38110913Sgdamore@opensolaris.org fle.consts.consts[n].gpr = gpr;
38210913Sgdamore@opensolaris.org fle.consts.consts[n].value = intv;
38310913Sgdamore@opensolaris.org fle.consts.nconst = n + 1;
38410913Sgdamore@opensolaris.org
38510913Sgdamore@opensolaris.org add_init(gpr, intv, NULL);
38610913Sgdamore@opensolaris.org }
38710913Sgdamore@opensolaris.org
38810913Sgdamore@opensolaris.org static void
compile_const(char ** tokens,int cnt)38910913Sgdamore@opensolaris.org compile_const(char **tokens, int cnt)
39010913Sgdamore@opensolaris.org {
39110913Sgdamore@opensolaris.org CHECK_COUNT(tokens, cnt, 2, 3);
39210913Sgdamore@opensolaris.org char *name = tokens[1];
39310913Sgdamore@opensolaris.org char *value = tokens[2] ? tokens[2] : tokens[1];
39410913Sgdamore@opensolaris.org
39510913Sgdamore@opensolaris.org if (ngpr >= MAX_GPR)
39610913Sgdamore@opensolaris.org error("Too many GPR variables");
39710913Sgdamore@opensolaris.org
39810913Sgdamore@opensolaris.org declare_const(ngpr, value);
39910913Sgdamore@opensolaris.org
40010913Sgdamore@opensolaris.org add_symbol(name, SY_GPR, gpr_base + ngpr++);
40110913Sgdamore@opensolaris.org }
40210913Sgdamore@opensolaris.org
40310913Sgdamore@opensolaris.org static void
compile_bool(char ** tokens,int cnt)40410913Sgdamore@opensolaris.org compile_bool(char **tokens, int cnt)
40510913Sgdamore@opensolaris.org {
40610913Sgdamore@opensolaris.org char *parm, *def;
40710913Sgdamore@opensolaris.org int n, num;
40810913Sgdamore@opensolaris.org
40910913Sgdamore@opensolaris.org CHECK_COUNT(tokens, cnt, 3, 3);
41010913Sgdamore@opensolaris.org
41110913Sgdamore@opensolaris.org parm = tokens[1];
41210913Sgdamore@opensolaris.org def = tokens[2];
41310913Sgdamore@opensolaris.org
41410913Sgdamore@opensolaris.org n = fle.parms.ngpr;
41510913Sgdamore@opensolaris.org if (n >= MAX_GPR_PARMS) {
41610913Sgdamore@opensolaris.org error("Too many GPR parameters");
41710913Sgdamore@opensolaris.org return;
41810913Sgdamore@opensolaris.org }
41910913Sgdamore@opensolaris.org
42010913Sgdamore@opensolaris.org if (sscanf(def, "%d", &num) != 1) {
42110913Sgdamore@opensolaris.org error("Bad integer value near '%s'", def);
42210913Sgdamore@opensolaris.org return;
42310913Sgdamore@opensolaris.org }
42410913Sgdamore@opensolaris.org
42510913Sgdamore@opensolaris.org (void) strcpy(fle.parms.gpr[n].name, parm);
42610913Sgdamore@opensolaris.org fle.parms.gpr[n].num = ngpr;
42710913Sgdamore@opensolaris.org fle.parms.gpr[n].def = num;
42810913Sgdamore@opensolaris.org fle.parms.ngpr = n + 1;
42910913Sgdamore@opensolaris.org
43010913Sgdamore@opensolaris.org add_init(ngpr, num, parm);
43110913Sgdamore@opensolaris.org
43210913Sgdamore@opensolaris.org add_symbol(parm, SY_PARM, gpr_base + ngpr++);
43310913Sgdamore@opensolaris.org }
43410913Sgdamore@opensolaris.org
43510913Sgdamore@opensolaris.org static void
compile_mono(char ** tokens,int cnt)43610913Sgdamore@opensolaris.org compile_mono(char **tokens, int cnt)
43710913Sgdamore@opensolaris.org {
43810913Sgdamore@opensolaris.org char *parm, *def;
43910913Sgdamore@opensolaris.org int n, num;
44010913Sgdamore@opensolaris.org char tmp[128];
44110913Sgdamore@opensolaris.org
44210913Sgdamore@opensolaris.org CHECK_COUNT(tokens, cnt, 3, 3);
44310913Sgdamore@opensolaris.org
44410913Sgdamore@opensolaris.org parm = tokens[1];
44510913Sgdamore@opensolaris.org def = tokens[2];
44610913Sgdamore@opensolaris.org
44710913Sgdamore@opensolaris.org n = fle.parms.ngpr;
44810913Sgdamore@opensolaris.org if (n >= MAX_GPR_PARMS) {
44910913Sgdamore@opensolaris.org error("Too many GPR parameters");
45010913Sgdamore@opensolaris.org return;
45110913Sgdamore@opensolaris.org }
45210913Sgdamore@opensolaris.org
45310913Sgdamore@opensolaris.org if (sscanf(def, "%d", &num) != 1) {
45410913Sgdamore@opensolaris.org error("Bad integer value near '%s'", def);
45510913Sgdamore@opensolaris.org return;
45610913Sgdamore@opensolaris.org }
45710913Sgdamore@opensolaris.org
45810913Sgdamore@opensolaris.org (void) strcpy(fle.parms.gpr[n].name, parm);
45910913Sgdamore@opensolaris.org fle.parms.gpr[n].num = ngpr;
46010913Sgdamore@opensolaris.org fle.parms.gpr[n].def = num;
46110913Sgdamore@opensolaris.org fle.parms.ngpr = n + 1;
46210913Sgdamore@opensolaris.org
46310913Sgdamore@opensolaris.org add_init(ngpr, num, parm);
46410913Sgdamore@opensolaris.org
46510913Sgdamore@opensolaris.org add_symbol(parm, SY_PARM, gpr_base + ngpr++);
46610913Sgdamore@opensolaris.org }
46710913Sgdamore@opensolaris.org
46810913Sgdamore@opensolaris.org static void
compile_stereo(char ** tokens,int cnt)46910913Sgdamore@opensolaris.org compile_stereo(char **tokens, int cnt)
47010913Sgdamore@opensolaris.org {
47110913Sgdamore@opensolaris.org char *parm, *def;
47210913Sgdamore@opensolaris.org int n, num;
47310913Sgdamore@opensolaris.org char tmp[128];
47410913Sgdamore@opensolaris.org
47510913Sgdamore@opensolaris.org CHECK_COUNT(tokens, cnt, 3, 3);
47610913Sgdamore@opensolaris.org
47710913Sgdamore@opensolaris.org parm = tokens[1];
47810913Sgdamore@opensolaris.org def = tokens[2];
47910913Sgdamore@opensolaris.org
48010913Sgdamore@opensolaris.org n = fle.parms.ngpr;
48110913Sgdamore@opensolaris.org if (n >= MAX_GPR_PARMS) {
48210913Sgdamore@opensolaris.org error("Too many GPR parameters");
48310913Sgdamore@opensolaris.org return;
48410913Sgdamore@opensolaris.org }
48510913Sgdamore@opensolaris.org
48610913Sgdamore@opensolaris.org if (sscanf(def, "%d", &num) != 1) {
48710913Sgdamore@opensolaris.org error("Bad integer value near '%s'", def);
48810913Sgdamore@opensolaris.org return;
48910913Sgdamore@opensolaris.org }
49010913Sgdamore@opensolaris.org
49110913Sgdamore@opensolaris.org (void) strcpy(fle.parms.gpr[n].name, parm);
49210913Sgdamore@opensolaris.org fle.parms.gpr[n].num = ngpr;
49310913Sgdamore@opensolaris.org fle.parms.gpr[n].def = num | (num << 8);
49410913Sgdamore@opensolaris.org fle.parms.ngpr = n + 1;
49510913Sgdamore@opensolaris.org
49610913Sgdamore@opensolaris.org add_init(ngpr, num, parm);
49710913Sgdamore@opensolaris.org add_init(ngpr + 1, num, NULL);
49810913Sgdamore@opensolaris.org
49910913Sgdamore@opensolaris.org (void) sprintf(tmp, "%s_L", parm);
50010913Sgdamore@opensolaris.org add_symbol(tmp, SY_PARM, gpr_base + ngpr++);
50110913Sgdamore@opensolaris.org (void) sprintf(tmp, "%s_R", parm);
50210913Sgdamore@opensolaris.org add_symbol(tmp, SY_PARM, gpr_base + ngpr++);
50310913Sgdamore@opensolaris.org }
50410913Sgdamore@opensolaris.org
50510913Sgdamore@opensolaris.org static void
compile_input(char ** tokens,int cnt)50610913Sgdamore@opensolaris.org compile_input(char **tokens, int cnt)
50710913Sgdamore@opensolaris.org {
50810913Sgdamore@opensolaris.org int num;
50910913Sgdamore@opensolaris.org
51010913Sgdamore@opensolaris.org CHECK_COUNT(tokens, cnt, 3, 3);
51110913Sgdamore@opensolaris.org
51210913Sgdamore@opensolaris.org if (sscanf(tokens[2], "%d", &num) != 1) {
51310913Sgdamore@opensolaris.org error("Bad integer value near '%s'", tokens[2]);
51410913Sgdamore@opensolaris.org return;
51510913Sgdamore@opensolaris.org }
51610913Sgdamore@opensolaris.org
51710913Sgdamore@opensolaris.org add_symbol(tokens[1], SY_INPUT, input_base + num);
51810913Sgdamore@opensolaris.org }
51910913Sgdamore@opensolaris.org
52010913Sgdamore@opensolaris.org static void
compile_send(char ** tokens,int cnt)52110913Sgdamore@opensolaris.org compile_send(char **tokens, int cnt)
52210913Sgdamore@opensolaris.org {
52310913Sgdamore@opensolaris.org int num;
52410913Sgdamore@opensolaris.org
52510913Sgdamore@opensolaris.org CHECK_COUNT(tokens, cnt, 3, 3);
52610913Sgdamore@opensolaris.org
52710913Sgdamore@opensolaris.org if (sscanf(tokens[2], "%d", &num) != 1) {
52810913Sgdamore@opensolaris.org error("Bad integer near '%s'", tokens[2]);
52910913Sgdamore@opensolaris.org return;
53010913Sgdamore@opensolaris.org }
53110913Sgdamore@opensolaris.org
53210913Sgdamore@opensolaris.org add_symbol(tokens[1], SY_FX, num);
53310913Sgdamore@opensolaris.org }
53410913Sgdamore@opensolaris.org
53510913Sgdamore@opensolaris.org static void
compile_output(char ** tokens,int cnt)53610913Sgdamore@opensolaris.org compile_output(char **tokens, int cnt)
53710913Sgdamore@opensolaris.org {
53810913Sgdamore@opensolaris.org int num;
53910913Sgdamore@opensolaris.org
54010913Sgdamore@opensolaris.org CHECK_COUNT(tokens, cnt, 3, 3);
54110913Sgdamore@opensolaris.org
54210913Sgdamore@opensolaris.org if (sscanf(tokens[2], "%d", &num) != 1) {
54310913Sgdamore@opensolaris.org error("Bad integer value near '%s'", tokens[2]);
54410913Sgdamore@opensolaris.org return;
54510913Sgdamore@opensolaris.org }
54610913Sgdamore@opensolaris.org
54710913Sgdamore@opensolaris.org add_symbol(tokens[1], SY_OUTPUT, output_base + num);
54810913Sgdamore@opensolaris.org }
54910913Sgdamore@opensolaris.org
55010913Sgdamore@opensolaris.org static void
compile_directive(char ** tokens,int cnt)55110913Sgdamore@opensolaris.org compile_directive(char **tokens, int cnt)
55210913Sgdamore@opensolaris.org {
55310913Sgdamore@opensolaris.org if (strcmp(tokens[0], ".gpr") == 0) {
55410913Sgdamore@opensolaris.org compile_gpr(tokens, cnt);
55510913Sgdamore@opensolaris.org return;
55610913Sgdamore@opensolaris.org }
55710913Sgdamore@opensolaris.org
55810913Sgdamore@opensolaris.org if (strcmp(tokens[0], ".const") == 0) {
55910913Sgdamore@opensolaris.org compile_const(tokens, cnt);
56010913Sgdamore@opensolaris.org return;
56110913Sgdamore@opensolaris.org }
56210913Sgdamore@opensolaris.org
56310913Sgdamore@opensolaris.org if (strcmp(tokens[0], ".stereo") == 0) {
56410913Sgdamore@opensolaris.org compile_stereo(tokens, cnt);
56510913Sgdamore@opensolaris.org return;
56610913Sgdamore@opensolaris.org }
56710913Sgdamore@opensolaris.org
56810913Sgdamore@opensolaris.org if (strcmp(tokens[0], ".mono") == 0) {
56910913Sgdamore@opensolaris.org compile_mono(tokens, cnt);
57010913Sgdamore@opensolaris.org return;
57110913Sgdamore@opensolaris.org }
57210913Sgdamore@opensolaris.org
57310913Sgdamore@opensolaris.org if (strcmp(tokens[0], ".bool") == 0) {
57410913Sgdamore@opensolaris.org compile_bool(tokens, cnt);
57510913Sgdamore@opensolaris.org return;
57610913Sgdamore@opensolaris.org }
57710913Sgdamore@opensolaris.org
57810913Sgdamore@opensolaris.org if (strcmp(tokens[0], ".input") == 0) {
57910913Sgdamore@opensolaris.org compile_input(tokens, cnt);
58010913Sgdamore@opensolaris.org return;
58110913Sgdamore@opensolaris.org }
58210913Sgdamore@opensolaris.org
58310913Sgdamore@opensolaris.org if (strcmp(tokens[0], ".send") == 0) {
58410913Sgdamore@opensolaris.org compile_send(tokens, cnt);
58510913Sgdamore@opensolaris.org return;
58610913Sgdamore@opensolaris.org }
58710913Sgdamore@opensolaris.org
58810913Sgdamore@opensolaris.org if (strcmp(tokens[0], ".output") == 0) {
58910913Sgdamore@opensolaris.org compile_output(tokens, cnt);
59010913Sgdamore@opensolaris.org return;
59110913Sgdamore@opensolaris.org }
59210913Sgdamore@opensolaris.org
59310913Sgdamore@opensolaris.org if (strcmp(tokens[0], ".rem") == 0) {
59410913Sgdamore@opensolaris.org compile_rem(tokens, cnt);
59510913Sgdamore@opensolaris.org return;
59610913Sgdamore@opensolaris.org }
59710913Sgdamore@opensolaris.org if (strcmp(tokens[0], ".'") == 0) {
59810913Sgdamore@opensolaris.org compile_rem(tokens, cnt);
59910913Sgdamore@opensolaris.org return;
60010913Sgdamore@opensolaris.org }
60110913Sgdamore@opensolaris.org
60210913Sgdamore@opensolaris.org error("Unknown directive '%s'", tokens[0]);
60310913Sgdamore@opensolaris.org }
60410913Sgdamore@opensolaris.org
60510913Sgdamore@opensolaris.org static void
compile_asm(char ** tokens,int cnt)60610913Sgdamore@opensolaris.org compile_asm(char **tokens, int cnt)
60710913Sgdamore@opensolaris.org {
60810913Sgdamore@opensolaris.org char *parms[4];
60910913Sgdamore@opensolaris.org sym_t *symbols[4];
61010913Sgdamore@opensolaris.org #define EMIT(o, r, a, x, y) \
61110913Sgdamore@opensolaris.org fle.code[pc*2] = ((x) << 10) | (y); \
61210913Sgdamore@opensolaris.org fle.code[pc*2+1] = ((o) << 20) | ((r) << 10) | a; pc++
61310913Sgdamore@opensolaris.org #define EMIT_AUDIGY(o, r, a, x, y) \
61410913Sgdamore@opensolaris.org fle.code[pc*2] = ((x) << 12) | (y); \
61510913Sgdamore@opensolaris.org fle.code[pc*2+1] = ((o) << 24) | ((r) << 12) | a; pc++
61610913Sgdamore@opensolaris.org
61710913Sgdamore@opensolaris.org int i, n = 0, nerr = 0;
61810913Sgdamore@opensolaris.org int ninputs = 0;
61910913Sgdamore@opensolaris.org
62010913Sgdamore@opensolaris.org CHECK_COUNT(tokens, cnt, 5, 5);
62110913Sgdamore@opensolaris.org
62210913Sgdamore@opensolaris.org for (i = 0; i < 4; i++) {
62310913Sgdamore@opensolaris.org if ((symbols[i] = find_symbol(tokens[i+1])) == NULL) {
62410913Sgdamore@opensolaris.org (void) fprintf(stderr, "%s\n", tokens[i+1]);
62510913Sgdamore@opensolaris.org nerr++;
62610913Sgdamore@opensolaris.org error("Undefined symbol '%s'", tokens[i + 1]);
62710913Sgdamore@opensolaris.org continue;
62810913Sgdamore@opensolaris.org }
62910913Sgdamore@opensolaris.org
63010913Sgdamore@opensolaris.org if (symbols[i]->type == SY_INPUT)
63110913Sgdamore@opensolaris.org ninputs++;
63210913Sgdamore@opensolaris.org
63310913Sgdamore@opensolaris.org if (symbols[i]->type == SY_ACCUM && i != 1)
63410913Sgdamore@opensolaris.org error("Bad usage of 'accum' operand.");
63510913Sgdamore@opensolaris.org }
63610913Sgdamore@opensolaris.org
63710913Sgdamore@opensolaris.org if (nerr > 0)
63810913Sgdamore@opensolaris.org return;
63910913Sgdamore@opensolaris.org
64010913Sgdamore@opensolaris.org if (ninputs > 1) {
64110913Sgdamore@opensolaris.org error("Attempt to access more than one input "
64210913Sgdamore@opensolaris.org "GPRs by the same instruction");
64310913Sgdamore@opensolaris.org }
64410913Sgdamore@opensolaris.org
64510913Sgdamore@opensolaris.org for (i = 0; instructions[i].name != NULL; i++)
64610913Sgdamore@opensolaris.org if (strcasecmp(tokens[0], instructions[i].name) == 0) {
64710913Sgdamore@opensolaris.org
64810913Sgdamore@opensolaris.org if (is_audigy) {
64910913Sgdamore@opensolaris.org EMIT_AUDIGY(instructions[i].opcode,
65010913Sgdamore@opensolaris.org symbols[0]->arg,
65110913Sgdamore@opensolaris.org symbols[1]->arg,
65210913Sgdamore@opensolaris.org symbols[2]->arg,
65310913Sgdamore@opensolaris.org symbols[3]->arg);
65410913Sgdamore@opensolaris.org } else {
65510913Sgdamore@opensolaris.org EMIT(instructions[i].opcode,
65610913Sgdamore@opensolaris.org symbols[0]->arg,
65710913Sgdamore@opensolaris.org symbols[1]->arg,
65810913Sgdamore@opensolaris.org symbols[2]->arg,
65910913Sgdamore@opensolaris.org symbols[3]->arg);
66010913Sgdamore@opensolaris.org }
66110913Sgdamore@opensolaris.org
66210913Sgdamore@opensolaris.org return;
66310913Sgdamore@opensolaris.org }
66410913Sgdamore@opensolaris.org
66510913Sgdamore@opensolaris.org error("Unrecognized instruction '%s'", tokens[0]);
66610913Sgdamore@opensolaris.org }
66710913Sgdamore@opensolaris.org
66810913Sgdamore@opensolaris.org static void
init_compiler(void)66910913Sgdamore@opensolaris.org init_compiler(void)
67010913Sgdamore@opensolaris.org {
67110913Sgdamore@opensolaris.org char tmp[100];
67210913Sgdamore@opensolaris.org int i;
67310913Sgdamore@opensolaris.org
67410913Sgdamore@opensolaris.org (void) memset(&fle, 0, sizeof (fle));
67510913Sgdamore@opensolaris.org /*
67610913Sgdamore@opensolaris.org * Initialize few predefined GPR parameter registers. These
67710913Sgdamore@opensolaris.org * definitions have to be in sync with the GPR_* macros in
67810913Sgdamore@opensolaris.org * <sblive.h>.
67910913Sgdamore@opensolaris.org */
68010913Sgdamore@opensolaris.org
68110913Sgdamore@opensolaris.org /*
68210913Sgdamore@opensolaris.org * Make sure we start at gpr id 2 for now; 0 and 1 may be used
68310913Sgdamore@opensolaris.org * differently.
68410913Sgdamore@opensolaris.org */
68510913Sgdamore@opensolaris.org add_symbol("NULL", SY_DUMMY, gpr_base + ngpr++);
68610913Sgdamore@opensolaris.org add_symbol("NULL_", SY_DUMMY, gpr_base + ngpr++);
68710913Sgdamore@opensolaris.org
68810913Sgdamore@opensolaris.org pc = 0;
68910913Sgdamore@opensolaris.org
69010913Sgdamore@opensolaris.org if (is_audigy) {
69110913Sgdamore@opensolaris.org /* Initialize the code array with NOPs (AUDIGY) */
69210913Sgdamore@opensolaris.org for (i = 0; i < 512; i++) {
69310913Sgdamore@opensolaris.org fle.code[i * 2 + 0] = (0xc0 << 12) | 0xc0;
69410913Sgdamore@opensolaris.org fle.code[i * 2 + 1] =
69510913Sgdamore@opensolaris.org (0x06 << 24) | (0xc0 << 12) | 0xc0;
69610913Sgdamore@opensolaris.org }
69710913Sgdamore@opensolaris.org
69810913Sgdamore@opensolaris.org for (i = 0; i < 32; i++) {
69910913Sgdamore@opensolaris.org (void) sprintf(tmp, "fx%d", i);
70010913Sgdamore@opensolaris.org add_symbol(tmp, SY_FX, i);
70110913Sgdamore@opensolaris.org }
70210913Sgdamore@opensolaris.org } else {
70310913Sgdamore@opensolaris.org /* Initialize the code array with NOPs (LIVE) */
70410913Sgdamore@opensolaris.org for (i = 0; i < 512; i++) {
70510913Sgdamore@opensolaris.org fle.code[i * 2 + 0] = 0x10040;
70610913Sgdamore@opensolaris.org fle.code[i * 2 + 1] = 0x610040;
70710913Sgdamore@opensolaris.org }
70810913Sgdamore@opensolaris.org
70910913Sgdamore@opensolaris.org for (i = 0; i < 16; i++) {
71010913Sgdamore@opensolaris.org (void) sprintf(tmp, "fx%d", i);
71110913Sgdamore@opensolaris.org add_symbol(tmp, SY_FX, i);
71210913Sgdamore@opensolaris.org }
71310913Sgdamore@opensolaris.org }
71410913Sgdamore@opensolaris.org
71510913Sgdamore@opensolaris.org /*
71610913Sgdamore@opensolaris.org * Constants
71710913Sgdamore@opensolaris.org */
71810913Sgdamore@opensolaris.org
71910913Sgdamore@opensolaris.org if (is_audigy) {
72010913Sgdamore@opensolaris.org /* Audigy symbols */
72110913Sgdamore@opensolaris.org add_symbol("0", SY_CONST, 0x0c0);
72210913Sgdamore@opensolaris.org add_symbol("1", SY_CONST, 0x0c1);
72310913Sgdamore@opensolaris.org add_symbol("2", SY_CONST, 0x0c2);
72410913Sgdamore@opensolaris.org add_symbol("3", SY_CONST, 0x0c3);
72510913Sgdamore@opensolaris.org add_symbol("4", SY_CONST, 0x0c4);
72610913Sgdamore@opensolaris.org add_symbol("8", SY_CONST, 0x0c5);
72710913Sgdamore@opensolaris.org add_symbol("16", SY_CONST, 0x0c6);
72810913Sgdamore@opensolaris.org add_symbol("32", SY_CONST, 0x0c7);
72910913Sgdamore@opensolaris.org add_symbol("256", SY_CONST, 0x0c8);
73010913Sgdamore@opensolaris.org add_symbol("65536", SY_CONST, 0x0c9);
73110913Sgdamore@opensolaris.org
73210913Sgdamore@opensolaris.org add_symbol("2048", SY_CONST, 0x0ca);
73310913Sgdamore@opensolaris.org add_symbol("0x800", SY_CONST, 0x0ca);
73410913Sgdamore@opensolaris.org
73510913Sgdamore@opensolaris.org add_symbol("2^28", SY_CONST, 0x0cb);
73610913Sgdamore@opensolaris.org add_symbol("0x10000000", SY_CONST, 0x0cb);
73710913Sgdamore@opensolaris.org
73810913Sgdamore@opensolaris.org add_symbol("2^29", SY_CONST, 0x0cc);
73910913Sgdamore@opensolaris.org add_symbol("0x20000000", SY_CONST, 0x0cc);
74010913Sgdamore@opensolaris.org
74110913Sgdamore@opensolaris.org add_symbol("2^30", SY_CONST, 0x0cd);
74210913Sgdamore@opensolaris.org add_symbol("0x40000000", SY_CONST, 0x0cd);
74310913Sgdamore@opensolaris.org
74410913Sgdamore@opensolaris.org add_symbol("2^31", SY_CONST, 0x0ce);
74510913Sgdamore@opensolaris.org add_symbol("0x80000000", SY_CONST, 0x0ce);
74610913Sgdamore@opensolaris.org
74710913Sgdamore@opensolaris.org add_symbol("0x7fffffff", SY_CONST, 0x0cf);
74810913Sgdamore@opensolaris.org
74910913Sgdamore@opensolaris.org add_symbol("0xffffffff", SY_CONST, 0x0d0);
75010913Sgdamore@opensolaris.org add_symbol("-1", SY_CONST, 0x0d0);
75110913Sgdamore@opensolaris.org
75210913Sgdamore@opensolaris.org add_symbol("0xfffffffe", SY_CONST, 0x0d1);
75310913Sgdamore@opensolaris.org add_symbol("-2", SY_CONST, 0x0d1);
75410913Sgdamore@opensolaris.org
75510913Sgdamore@opensolaris.org add_symbol("0xc0000000", SY_CONST, 0x0d2);
75610913Sgdamore@opensolaris.org
75710913Sgdamore@opensolaris.org add_symbol("0x4f1bbcdc", SY_CONST, 0x0d3);
75810913Sgdamore@opensolaris.org
75910913Sgdamore@opensolaris.org add_symbol("0x5a7ef9db", SY_CONST, 0x0d4);
76010913Sgdamore@opensolaris.org
76110913Sgdamore@opensolaris.org add_symbol("0x100000", SY_CONST, 0x0d5);
76210913Sgdamore@opensolaris.org add_symbol("accum", SY_ACCUM, 0x0d6);
76310913Sgdamore@opensolaris.org add_symbol("CCR", SY_CONST, 0x0d7);
76410913Sgdamore@opensolaris.org
76510913Sgdamore@opensolaris.org add_symbol("noise_L", SY_CONST, 0x0d8);
76610913Sgdamore@opensolaris.org add_symbol("noise_R", SY_CONST, 0x0d9);
76710913Sgdamore@opensolaris.org add_symbol("IRQREQ", SY_CONST, 0x0da);
76810913Sgdamore@opensolaris.org } else {
76910913Sgdamore@opensolaris.org /* SB Live symbols */
77010913Sgdamore@opensolaris.org add_symbol("0", SY_CONST, 0x040);
77110913Sgdamore@opensolaris.org add_symbol("1", SY_CONST, 0x041);
77210913Sgdamore@opensolaris.org add_symbol("2", SY_CONST, 0x042);
77310913Sgdamore@opensolaris.org add_symbol("3", SY_CONST, 0x043);
77410913Sgdamore@opensolaris.org add_symbol("4", SY_CONST, 0x044);
77510913Sgdamore@opensolaris.org add_symbol("8", SY_CONST, 0x045);
77610913Sgdamore@opensolaris.org add_symbol("16", SY_CONST, 0x046);
77710913Sgdamore@opensolaris.org add_symbol("32", SY_CONST, 0x047);
77810913Sgdamore@opensolaris.org add_symbol("256", SY_CONST, 0x048);
77910913Sgdamore@opensolaris.org add_symbol("65536", SY_CONST, 0x049);
78010913Sgdamore@opensolaris.org
78110913Sgdamore@opensolaris.org add_symbol("2^23", SY_CONST, 0x04a);
78210913Sgdamore@opensolaris.org add_symbol("0x80000", SY_CONST, 0x04a);
78310913Sgdamore@opensolaris.org
78410913Sgdamore@opensolaris.org add_symbol("2^28", SY_CONST, 0x04b);
78510913Sgdamore@opensolaris.org add_symbol("0x10000000", SY_CONST, 0x04b);
78610913Sgdamore@opensolaris.org
78710913Sgdamore@opensolaris.org add_symbol("2^29", SY_CONST, 0x04c);
78810913Sgdamore@opensolaris.org add_symbol("0x20000000", SY_CONST, 0x04c);
78910913Sgdamore@opensolaris.org
79010913Sgdamore@opensolaris.org add_symbol("2^30", SY_CONST, 0x04d);
79110913Sgdamore@opensolaris.org add_symbol("0x40000000", SY_CONST, 0x04d);
79210913Sgdamore@opensolaris.org
79310913Sgdamore@opensolaris.org add_symbol("2^31", SY_CONST, 0x04e);
79410913Sgdamore@opensolaris.org add_symbol("0x80000000", SY_CONST, 0x04e);
79510913Sgdamore@opensolaris.org
79610913Sgdamore@opensolaris.org add_symbol("0x7fffffff", SY_CONST, 0x04f);
79710913Sgdamore@opensolaris.org
79810913Sgdamore@opensolaris.org add_symbol("0xffffffff", SY_CONST, 0x050);
79910913Sgdamore@opensolaris.org add_symbol("-1", SY_CONST, 0x050);
80010913Sgdamore@opensolaris.org
80110913Sgdamore@opensolaris.org add_symbol("0xfffffffe", SY_CONST, 0x051);
80210913Sgdamore@opensolaris.org add_symbol("-2", SY_CONST, 0x051);
80310913Sgdamore@opensolaris.org
80410913Sgdamore@opensolaris.org add_symbol("accum", SY_ACCUM, 0x056);
80510913Sgdamore@opensolaris.org add_symbol("CCR", SY_CONST, 0x057);
80610913Sgdamore@opensolaris.org
80710913Sgdamore@opensolaris.org add_symbol("noise_L", SY_CONST, 0x058);
80810913Sgdamore@opensolaris.org add_symbol("noise_R", SY_CONST, 0x059);
80910913Sgdamore@opensolaris.org add_symbol("IRQREQ", SY_CONST, 0x05a);
81010913Sgdamore@opensolaris.org }
81110913Sgdamore@opensolaris.org }
81210913Sgdamore@opensolaris.org
81310913Sgdamore@opensolaris.org static void
produce_map(char * name)81410913Sgdamore@opensolaris.org produce_map(char *name)
81510913Sgdamore@opensolaris.org {
81610913Sgdamore@opensolaris.org char fname[1024];
81710913Sgdamore@opensolaris.org int i;
81810913Sgdamore@opensolaris.org FILE *f;
81910913Sgdamore@opensolaris.org
82010913Sgdamore@opensolaris.org if ((f = fopen(name, "w")) == NULL) {
82110913Sgdamore@opensolaris.org perror(name);
82210913Sgdamore@opensolaris.org return;
82310913Sgdamore@opensolaris.org }
82410913Sgdamore@opensolaris.org
82510913Sgdamore@opensolaris.org (void) fprintf(f, "%d\n", pc);
82610913Sgdamore@opensolaris.org
82710913Sgdamore@opensolaris.org for (i = 0; i < nsyms; i++) {
82810913Sgdamore@opensolaris.org (void) fprintf(f, "%04x %x %s\n",
82910913Sgdamore@opensolaris.org symtab[i].arg, symtab[i].type, symtab[i].name);
83010913Sgdamore@opensolaris.org }
83110913Sgdamore@opensolaris.org
83210913Sgdamore@opensolaris.org (void) fclose(f);
83310913Sgdamore@opensolaris.org if (verbose) {
83410913Sgdamore@opensolaris.org (void) fprintf(stderr,
83510913Sgdamore@opensolaris.org "No errors detected - Map written to %s\n", name);
83610913Sgdamore@opensolaris.org }
83710913Sgdamore@opensolaris.org }
83810913Sgdamore@opensolaris.org
83910913Sgdamore@opensolaris.org static void
produce_output(char * fname)84010913Sgdamore@opensolaris.org produce_output(char *fname)
84110913Sgdamore@opensolaris.org {
84210913Sgdamore@opensolaris.org int fd;
84310913Sgdamore@opensolaris.org
84410913Sgdamore@opensolaris.org if ((fd = creat(fname, 0644)) == -1) {
84510913Sgdamore@opensolaris.org perror(fname);
84610913Sgdamore@opensolaris.org exit(-1);
84710913Sgdamore@opensolaris.org }
84810913Sgdamore@opensolaris.org
84910913Sgdamore@opensolaris.org if (write(fd, &fle, sizeof (fle)) != sizeof (fle)) {
85010913Sgdamore@opensolaris.org perror(fname);
85110913Sgdamore@opensolaris.org exit(-1);
85210913Sgdamore@opensolaris.org }
85310913Sgdamore@opensolaris.org
85410913Sgdamore@opensolaris.org if (verbose) {
85510913Sgdamore@opensolaris.org (void) fprintf(stderr,
85610913Sgdamore@opensolaris.org "No errors detected - Binary written to %s\n",
85710913Sgdamore@opensolaris.org fname);
85810913Sgdamore@opensolaris.org }
85910913Sgdamore@opensolaris.org
86010913Sgdamore@opensolaris.org (void) close(fd);
86110913Sgdamore@opensolaris.org }
86210913Sgdamore@opensolaris.org
86310913Sgdamore@opensolaris.org static void
produce_header(char * fname,char * prefix)86410913Sgdamore@opensolaris.org produce_header(char *fname, char *prefix)
86510913Sgdamore@opensolaris.org {
86610913Sgdamore@opensolaris.org FILE *f;
86710913Sgdamore@opensolaris.org char *s;
86810913Sgdamore@opensolaris.org char sname[MAXPATHLEN + 1];
86910913Sgdamore@opensolaris.org char dname[MAXPATHLEN + 1];
87010913Sgdamore@opensolaris.org int i;
87110913Sgdamore@opensolaris.org clock_t now;
87210913Sgdamore@opensolaris.org char when[128];
87310913Sgdamore@opensolaris.org
87410913Sgdamore@opensolaris.org /* get basename */
87510913Sgdamore@opensolaris.org if (prefix == NULL) {
87610913Sgdamore@opensolaris.org s = strrchr(fname, '/');
87710913Sgdamore@opensolaris.org s = (s == NULL) ? fname : s + 1;
87810913Sgdamore@opensolaris.org } else {
87910913Sgdamore@opensolaris.org s = prefix;
88010913Sgdamore@opensolaris.org }
88110913Sgdamore@opensolaris.org (void) strlcpy(sname, s, sizeof (sname));
88210913Sgdamore@opensolaris.org
88310913Sgdamore@opensolaris.org /* strip off any extension */
88410913Sgdamore@opensolaris.org s = strchr(sname, '.');
88510913Sgdamore@opensolaris.org if (s != NULL) {
88610913Sgdamore@opensolaris.org *s = 0;
88710913Sgdamore@opensolaris.org }
88810913Sgdamore@opensolaris.org if ((f = fopen(fname, "w")) == NULL) {
88910913Sgdamore@opensolaris.org perror(fname);
89010913Sgdamore@opensolaris.org return;
89110913Sgdamore@opensolaris.org }
89210913Sgdamore@opensolaris.org
89310913Sgdamore@opensolaris.org if (remarks[0] != 0) {
89410913Sgdamore@opensolaris.org (void) fprintf(f, "/*\n%s */\n", remarks);
89510913Sgdamore@opensolaris.org }
89610913Sgdamore@opensolaris.org now = time(NULL);
89710913Sgdamore@opensolaris.org strftime(when, sizeof (when), "%c", localtime(&now));
89810913Sgdamore@opensolaris.org (void) fprintf(f, banner, progname, when);
89910913Sgdamore@opensolaris.org
90010913Sgdamore@opensolaris.org (void) strlcpy(dname, prefix ? prefix : sname, sizeof (dname));
90110913Sgdamore@opensolaris.org for (i = 0; dname[i]; i++) {
90210913Sgdamore@opensolaris.org dname[i] = toupper(dname[i]);
90310913Sgdamore@opensolaris.org if (!isalnum(dname[i])) {
90410913Sgdamore@opensolaris.org dname[i] = '_';
90510913Sgdamore@opensolaris.org }
90610913Sgdamore@opensolaris.org }
90710913Sgdamore@opensolaris.org
90810913Sgdamore@opensolaris.org for (i = 0; i < fle.parms.ngpr; i++) {
90910913Sgdamore@opensolaris.org (void) fprintf(f, "#define\t%s_%s\t\t%d\n",
91010913Sgdamore@opensolaris.org dname, fle.parms.gpr[i].name, fle.parms.gpr[i].num);
91110913Sgdamore@opensolaris.org }
91210913Sgdamore@opensolaris.org
91310913Sgdamore@opensolaris.org (void) fprintf(f, "\n");
91410913Sgdamore@opensolaris.org
91510913Sgdamore@opensolaris.org if (parms_only)
91610913Sgdamore@opensolaris.org goto done;
91710913Sgdamore@opensolaris.org
91810913Sgdamore@opensolaris.org (void) fprintf(f, "uint32_t %s_code[] = {\n", sname);
91910913Sgdamore@opensolaris.org
92010913Sgdamore@opensolaris.org for (i = 0; i < pc * 2; i++) {
92110913Sgdamore@opensolaris.org if (i == 0) {
92210913Sgdamore@opensolaris.org (void) fprintf(f, "\t0x%08xU", fle.code[i]);
92310913Sgdamore@opensolaris.org } else if ((i % 4) == 0) {
92410913Sgdamore@opensolaris.org (void) fprintf(f, ",\n\t0x%08xU", fle.code[i]);
92510913Sgdamore@opensolaris.org } else {
92610913Sgdamore@opensolaris.org (void) fprintf(f, ", 0x%08xU", fle.code[i]);
92710913Sgdamore@opensolaris.org }
92810913Sgdamore@opensolaris.org }
92910913Sgdamore@opensolaris.org (void) fprintf(f, "\n};\n");
93010913Sgdamore@opensolaris.org
93110913Sgdamore@opensolaris.org (void) fprintf(f, "uint32_t %s_ninit = %d;\n", sname, fle.ninit);
93210913Sgdamore@opensolaris.org (void) fprintf(f, "uint32_t %s_init[] = {\n", sname);
93310913Sgdamore@opensolaris.org
93410913Sgdamore@opensolaris.org for (i = 0; i < fle.ninit; i++) {
93510913Sgdamore@opensolaris.org if (fle.init[i].name[0]) {
93610913Sgdamore@opensolaris.org (void) fprintf(f, "\t%u, 0x%x%s,\t/* %s */\n",
93710913Sgdamore@opensolaris.org fle.init[i].gpr, fle.init[i].value,
93810913Sgdamore@opensolaris.org fle.init[i].value >= 0x80000000U ? "U" : "",
93910913Sgdamore@opensolaris.org fle.init[i].name);
94010913Sgdamore@opensolaris.org } else {
94110913Sgdamore@opensolaris.org (void) fprintf(f, "\t%u, 0x%x%s,\n",
94210913Sgdamore@opensolaris.org fle.init[i].gpr, fle.init[i].value,
94310913Sgdamore@opensolaris.org fle.init[i].value >= 0x80000000U ? "U" : "");
94410913Sgdamore@opensolaris.org }
94510913Sgdamore@opensolaris.org }
94610913Sgdamore@opensolaris.org (void) fprintf(f, "};\n");
94710913Sgdamore@opensolaris.org
94810913Sgdamore@opensolaris.org done:
94910913Sgdamore@opensolaris.org (void) fclose(f);
95010913Sgdamore@opensolaris.org if (verbose) {
95110913Sgdamore@opensolaris.org (void) fprintf(stderr,
95210913Sgdamore@opensolaris.org "No errors detected - Header written to %s\n",
95310913Sgdamore@opensolaris.org fname);
95410913Sgdamore@opensolaris.org }
95510913Sgdamore@opensolaris.org }
95610913Sgdamore@opensolaris.org
95710913Sgdamore@opensolaris.org int
main(int argc,char * argv[])95810913Sgdamore@opensolaris.org main(int argc, char *argv[])
95910913Sgdamore@opensolaris.org {
96010913Sgdamore@opensolaris.org char line[4096], *p, *s, *outfile;
96110913Sgdamore@opensolaris.org char *iline;
96210913Sgdamore@opensolaris.org int i;
96310913Sgdamore@opensolaris.org FILE *input;
96410913Sgdamore@opensolaris.org char *tokens[10];
96510913Sgdamore@opensolaris.org int tokcnt;
96610913Sgdamore@opensolaris.org char *mapfile = NULL;
96710913Sgdamore@opensolaris.org char *header = NULL;
96810913Sgdamore@opensolaris.org char *prefix = NULL;
96910913Sgdamore@opensolaris.org
97010913Sgdamore@opensolaris.org outfile = NULL;
97110913Sgdamore@opensolaris.org infile = NULL;
97210913Sgdamore@opensolaris.org input = NULL;
97310913Sgdamore@opensolaris.org progname = argv[0];
97410913Sgdamore@opensolaris.org
97510913Sgdamore@opensolaris.org while ((i = getopt(argc, argv, "m:h:o:i:P:021v")) != EOF) {
97610913Sgdamore@opensolaris.org switch (i) {
97710913Sgdamore@opensolaris.org case 'o':
97810913Sgdamore@opensolaris.org outfile = optarg;
97910913Sgdamore@opensolaris.org break;
98010913Sgdamore@opensolaris.org case 'i':
98110913Sgdamore@opensolaris.org infile = strdup(optarg);
98210913Sgdamore@opensolaris.org break;
98310913Sgdamore@opensolaris.org case 'm':
98410913Sgdamore@opensolaris.org mapfile = optarg;
98510913Sgdamore@opensolaris.org break;
98610913Sgdamore@opensolaris.org case 'P':
98710913Sgdamore@opensolaris.org prefix = optarg;
98810913Sgdamore@opensolaris.org break;
98910913Sgdamore@opensolaris.org case 'h':
99010913Sgdamore@opensolaris.org header = optarg;
99110913Sgdamore@opensolaris.org break;
99210913Sgdamore@opensolaris.org case '0':
99310913Sgdamore@opensolaris.org parms_only = 1;
99410913Sgdamore@opensolaris.org break;
99510913Sgdamore@opensolaris.org case '2':
99610913Sgdamore@opensolaris.org is_audigy = 1;
99710913Sgdamore@opensolaris.org break;
99810913Sgdamore@opensolaris.org case '1':
99910913Sgdamore@opensolaris.org is_audigy = 0;
100010913Sgdamore@opensolaris.org break;
100110913Sgdamore@opensolaris.org case 'v':
100210913Sgdamore@opensolaris.org verbose++;
100310913Sgdamore@opensolaris.org break;
100410913Sgdamore@opensolaris.org default:
100510913Sgdamore@opensolaris.org (void) fprintf(stderr,
100610913Sgdamore@opensolaris.org "usage: %s [-m <map>] [-h <header>] "
100710913Sgdamore@opensolaris.org "[-o <binary>] [-i <source>] [-2|-1]",
100810913Sgdamore@opensolaris.org progname);
100910913Sgdamore@opensolaris.org exit(-1);
101010913Sgdamore@opensolaris.org break;
101110913Sgdamore@opensolaris.org }
101210913Sgdamore@opensolaris.org }
101310913Sgdamore@opensolaris.org
101410913Sgdamore@opensolaris.org if ((outfile == NULL) && (mapfile == NULL) && (header == NULL)) {
101510913Sgdamore@opensolaris.org outfile = "dsp.bin";
101610913Sgdamore@opensolaris.org }
101710913Sgdamore@opensolaris.org
101810913Sgdamore@opensolaris.org if (infile) {
101910913Sgdamore@opensolaris.org input = fopen(infile, "r");
102010913Sgdamore@opensolaris.org if (input == NULL) {
102110913Sgdamore@opensolaris.org perror(infile);
102210913Sgdamore@opensolaris.org exit(-1);
102310913Sgdamore@opensolaris.org }
102410913Sgdamore@opensolaris.org } else {
102510913Sgdamore@opensolaris.org infile = strdup("<stdin>");
102610913Sgdamore@opensolaris.org input = stdin;
102710913Sgdamore@opensolaris.org }
102810913Sgdamore@opensolaris.org
102910913Sgdamore@opensolaris.org if (is_audigy) {
103010913Sgdamore@opensolaris.org gpr_base = 0x400;
103110913Sgdamore@opensolaris.org input_base = 0x40;
103210913Sgdamore@opensolaris.org output_base = 0x60;
103310913Sgdamore@opensolaris.org if (verbose)
103410913Sgdamore@opensolaris.org (void) fprintf(stderr, "Compiling for SB Audigy\n");
103510913Sgdamore@opensolaris.org } else {
103610913Sgdamore@opensolaris.org if (verbose)
103710913Sgdamore@opensolaris.org (void) fprintf(stderr, "Compiling for SB Live\n");
103810913Sgdamore@opensolaris.org }
103910913Sgdamore@opensolaris.org
104010913Sgdamore@opensolaris.org init_compiler();
104110913Sgdamore@opensolaris.org
1042*13093SRoger.Faulkner@Oracle.COM while ((tokcnt = getaline(input, tokens)) != -1) {
104310913Sgdamore@opensolaris.org /* skip empty lines */
104410913Sgdamore@opensolaris.org if (tokcnt == 0) {
104510913Sgdamore@opensolaris.org continue;
104610913Sgdamore@opensolaris.org }
104710913Sgdamore@opensolaris.org
104810913Sgdamore@opensolaris.org if (strcmp(tokens[0], "#") == 0) {
104910913Sgdamore@opensolaris.org int num;
105010913Sgdamore@opensolaris.org if ((tokcnt >= 3) &&
105110913Sgdamore@opensolaris.org (sscanf(tokens[1], "%d", &num) == 1)) {
105210913Sgdamore@opensolaris.org lineno = num;
105310913Sgdamore@opensolaris.org free(infile);
105410913Sgdamore@opensolaris.org infile = strdup(tokens[2]);
105510913Sgdamore@opensolaris.org /* we don't want to count the # directive */
105610913Sgdamore@opensolaris.org lineno--;
105710913Sgdamore@opensolaris.org }
105810913Sgdamore@opensolaris.org
105910913Sgdamore@opensolaris.org /* unknown # directive? muddle on... */
106010913Sgdamore@opensolaris.org continue;
106110913Sgdamore@opensolaris.org }
106210913Sgdamore@opensolaris.org if (*tokens[0] == '.') {
106310913Sgdamore@opensolaris.org compile_directive(tokens, tokcnt);
106410913Sgdamore@opensolaris.org } else {
106510913Sgdamore@opensolaris.org compile_asm(tokens, tokcnt);
106610913Sgdamore@opensolaris.org }
106710913Sgdamore@opensolaris.org }
106810913Sgdamore@opensolaris.org
106910913Sgdamore@opensolaris.org if (lineno < 1) {
107010913Sgdamore@opensolaris.org error("Empty input");
107110913Sgdamore@opensolaris.org }
107210913Sgdamore@opensolaris.org
107310913Sgdamore@opensolaris.org if (errors == 0) {
107410913Sgdamore@opensolaris.org if (verbose) {
107510913Sgdamore@opensolaris.org (void) fprintf(stderr,
107610913Sgdamore@opensolaris.org "%d instructions out of 512 assembled\n", pc);
107710913Sgdamore@opensolaris.org }
107810913Sgdamore@opensolaris.org
107910913Sgdamore@opensolaris.org if (outfile)
108010913Sgdamore@opensolaris.org produce_output(outfile);
108110913Sgdamore@opensolaris.org if (mapfile)
108210913Sgdamore@opensolaris.org produce_map(mapfile);
108310913Sgdamore@opensolaris.org if (header)
108410913Sgdamore@opensolaris.org produce_header(header, prefix);
108510913Sgdamore@opensolaris.org }
108610913Sgdamore@opensolaris.org
108710913Sgdamore@opensolaris.org if (errors > 0) {
108810913Sgdamore@opensolaris.org (void) fprintf(stderr, "%d errors - compile failed\n", errors);
108910913Sgdamore@opensolaris.org exit(-1);
109010913Sgdamore@opensolaris.org }
109110913Sgdamore@opensolaris.org
109210913Sgdamore@opensolaris.org return (0);
109310913Sgdamore@opensolaris.org }
1094