xref: /netbsd/usr.sbin/gspa/gspa/gsp_out.c (revision bf9ec67e)
1 /*	$NetBSD: gsp_out.c,v 1.7 2002/05/27 21:11:56 wiz Exp $	*/
2 /*
3  * GSP assembler - binary & listing output
4  *
5  * Copyright (c) 1993 Paul Mackerras.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. All advertising materials mentioning features or use of this software
17  *    must display the following acknowledgement:
18  *      This product includes software developed by Paul Mackerras.
19  * 4. The name of the author may not be used to endorse or promote products
20  *    derived from this software without specific prior written permission
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 #include <sys/cdefs.h>
35 #ifndef lint
36 __RCSID("$NetBSD: gsp_out.c,v 1.7 2002/05/27 21:11:56 wiz Exp $");
37 #endif
38 
39 #include <stdio.h>
40 #include <stdlib.h>
41 #include <string.h>
42 #include "gsp_ass.h"
43 
44 u_int16_t codes[5];
45 unsigned ncode;
46 unsigned code_idx;
47 short show_pc;
48 short show_val;
49 int32_t val_to_show;
50 extern unsigned line_pc;
51 
52 unsigned obj_addr = 0;
53 
54 extern FILE *objfile, *listfile;
55 extern char line[];
56 
57 extern char *c_name;
58 u_int16_t c_buf[4096];
59 u_int32_t c_bufptr, c_binads;
60 
61 void c_checkbuf(void);
62 void c_dumpbuf(void);
63 
64 struct error {
65 	struct error *next;
66 	char	string[1];
67 };
68 
69 struct error *error_list, *error_last;
70 
71 void do_list_pc(void);
72 void do_show_val(int32_t);
73 void listing_line(void);
74 void put1code(u_int16_t);
75 void show_errors(void);
76 
77 void
78 putcode(u_int16_t *v, int n)
79 {
80 	for( ; n > 0; --n )
81 		put1code(*v++);
82 }
83 
84 void
85 put1code(u_int16_t v)
86 {
87 	if( code_idx >= 3 )
88 		listing_line();
89 	codes[code_idx] = v;
90 	if( objfile != NULL ){
91 		if( pc != obj_addr ){
92 			if (c_name) {
93 				if (c_bufptr > 0)
94 					c_dumpbuf();
95 				c_binads = pc;
96 				c_bufptr = 0;
97 			} else {
98 				/* expect this only when ncode == 0 */
99 				if (ncode % 8 != 0)
100 					fprintf(objfile, "\n");
101 				fprintf(objfile, "@%x\n", pc);
102 			}
103 			obj_addr = pc;
104 		} else {
105 			if((ncode % 8 != 0) && !c_name)
106 				fprintf(objfile, " ");
107 		}
108 		if (c_name) {
109 			c_checkbuf();
110 			c_buf[c_bufptr++] = v;
111 		} else
112 			fprintf(objfile, "%.4X", v & 0xFFFF);
113 		obj_addr += 0x10;
114 		if((ncode % 8 == 7) && !c_name)
115 			fprintf(objfile, "\n");
116 	}
117 	++ncode;
118 	++code_idx;
119 	pc += 0x10;
120 	show_pc = TRUE;
121 }
122 
123 void
124 c_checkbuf()
125 {
126 	if (c_bufptr > (sizeof(c_buf)/sizeof(*c_buf)))
127 		c_dumpbuf();
128 }
129 
130 void
131 c_dumpbuf()
132 {
133 	int i;
134 
135 	fprintf(objfile, "\n\n\t%d, 0x%04x, 0x%04x, /* new block */",
136 	    c_bufptr, (int)(c_binads >> 16), (int)(c_binads & 0xffff));
137 
138 	for (i=0; i < c_bufptr; ++i) {
139 		if (i%8 == 0)
140 			fprintf(objfile, "\n\t");
141 		fprintf(objfile, "0x%04x, ", c_buf[i]);
142 	}
143 	c_binads += c_bufptr;
144 	c_bufptr = 0;
145 }
146 
147 void
148 start_at(u_int32_t val)
149 {
150 	if( objfile != NULL ) {
151 		if (c_name) {
152 			c_checkbuf();
153 			fprintf(objfile,
154 			    "\n\n\t2, 0xffff, 0xfee0, 0x%04x, 0x%04x,"
155 			      "\n\t2, 0xffff, 0xffe0, 0x%04x, 0x%04x,\n",
156 			    val & 0xffff, val >> 16, val & 0xffff, val >> 16);
157 		} else
158 			fprintf(objfile, ":%lX\n", (long)val);
159 	}
160 }
161 
162 void
163 do_list_pc()
164 {
165 	if( pass2 )
166 		show_pc = TRUE;
167 }
168 
169 void
170 do_show_val(int32_t v)
171 {
172 	if( ncode == 0 ){
173 		val_to_show = v;
174 		show_val = TRUE;
175 		show_pc = FALSE;
176 	}
177 }
178 
179 void
180 list_error(char *string)
181 {
182 	struct error *p;
183 	int l;
184 
185 	if( listfile == NULL )
186 		return;
187 	l = strlen(string);
188 	p = (struct error *) alloc(sizeof(struct error) + l);
189 	strcpy(p->string, string);
190 	p->next = NULL;
191 	if( error_list == NULL )
192 		error_list = p;
193 	else
194 		error_last->next = p;
195 	error_last = p;
196 }
197 
198 void
199 show_errors()
200 {
201 	struct error *p, *q;
202 
203 	for( p = error_list; p != NULL; p = q ){
204 		if( listfile != NULL )
205 			fprintf(listfile, "\t\t\t%s\n", p->string);
206 		q = p->next;
207 		free(p);
208 	}
209 	error_list = error_last = NULL;
210 }
211 
212 void
213 listing()
214 {
215 	if( objfile != NULL && ncode % 8 != 0 && !c_name)
216 		fprintf(objfile, "\n");
217 	listing_line();
218 	show_errors();
219 	ncode = 0;
220 	show_pc = FALSE;
221 }
222 
223 void
224 listing_line()
225 {
226 	int i;
227 
228 	if( listfile == NULL ){
229 		code_idx = 0;
230 		return;
231 	}
232 	if( show_pc )
233 		fprintf(listfile, "%.8X", line_pc);
234 	else
235 		fprintf(listfile, "        ");
236 	if( show_val ){
237 		fprintf(listfile, "  %.8X", val_to_show);
238 		i = 2;
239 	} else {
240 		for( i = 0; i < code_idx; ++i )
241 			fprintf(listfile, " %.4X", codes[i]);
242 	}
243 	if( ncode <= 3 ){
244 		for( ; i < 3; ++i )
245 			fprintf(listfile, "     ");
246 		fprintf(listfile, " %s", line);
247 	} else
248 		fprintf(listfile, "\n");
249 	line_pc += code_idx << 4;
250 	code_idx = 0;
251 	show_val = FALSE;
252 }
253