1 /* $NetBSD: gsp_out.c,v 1.10 2009/04/15 08:26:35 lukem 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.10 2009/04/15 08:26:35 lukem Exp $");
37 #endif
38
39 #include <stdio.h>
40 #include <stdlib.h>
41 #include <string.h>
42 #include <util.h>
43 #include "gsp_ass.h"
44
45 u_int16_t codes[5];
46 unsigned ncode;
47 unsigned code_idx;
48 short show_pc;
49 short show_val;
50 int32_t val_to_show;
51 extern unsigned line_pc;
52
53 unsigned obj_addr = 0;
54
55 extern FILE *objfile, *listfile;
56 extern char line[];
57
58 extern char *c_name;
59 u_int16_t c_buf[4096];
60 u_int32_t c_bufptr, c_binads;
61
62 void c_checkbuf(void);
63 void c_dumpbuf(void);
64
65 struct error {
66 struct error *next;
67 char string[1];
68 };
69
70 struct error *error_list, *error_last;
71
72 void do_list_pc(void);
73 void do_show_val(int32_t);
74 void listing_line(void);
75 void put1code(u_int16_t);
76 void show_errors(void);
77
78 void
putcode(u_int16_t * v,int n)79 putcode(u_int16_t *v, int n)
80 {
81 for( ; n > 0; --n )
82 put1code(*v++);
83 }
84
85 void
put1code(u_int16_t v)86 put1code(u_int16_t v)
87 {
88 if( code_idx >= 3 )
89 listing_line();
90 codes[code_idx] = v;
91 if( objfile != NULL ){
92 if( pc != obj_addr ){
93 if (c_name) {
94 if (c_bufptr > 0)
95 c_dumpbuf();
96 c_binads = pc;
97 c_bufptr = 0;
98 } else {
99 /* expect this only when ncode == 0 */
100 if (ncode % 8 != 0)
101 fprintf(objfile, "\n");
102 fprintf(objfile, "@%x\n", pc);
103 }
104 obj_addr = pc;
105 } else {
106 if((ncode % 8 != 0) && !c_name)
107 fprintf(objfile, " ");
108 }
109 if (c_name) {
110 c_checkbuf();
111 c_buf[c_bufptr++] = v;
112 } else
113 fprintf(objfile, "%.4X", v & 0xFFFF);
114 obj_addr += 0x10;
115 if((ncode % 8 == 7) && !c_name)
116 fprintf(objfile, "\n");
117 }
118 ++ncode;
119 ++code_idx;
120 pc += 0x10;
121 show_pc = TRUE;
122 }
123
124 void
c_checkbuf()125 c_checkbuf()
126 {
127 if (c_bufptr > (sizeof(c_buf)/sizeof(*c_buf)))
128 c_dumpbuf();
129 }
130
131 void
c_dumpbuf()132 c_dumpbuf()
133 {
134 uint32_t i;
135
136 fprintf(objfile, "\n\n\t%d, 0x%04x, 0x%04x, /* new block */",
137 c_bufptr, (int)(c_binads >> 16), (int)(c_binads & 0xffff));
138
139 for (i=0; i < c_bufptr; ++i) {
140 if (i%8 == 0)
141 fprintf(objfile, "\n\t");
142 fprintf(objfile, "0x%04x, ", c_buf[i]);
143 }
144 c_binads += c_bufptr;
145 c_bufptr = 0;
146 }
147
148 void
start_at(u_int32_t val)149 start_at(u_int32_t val)
150 {
151 if( objfile != NULL ) {
152 if (c_name) {
153 c_checkbuf();
154 fprintf(objfile,
155 "\n\n\t2, 0xffff, 0xfee0, 0x%04x, 0x%04x,"
156 "\n\t2, 0xffff, 0xffe0, 0x%04x, 0x%04x,\n",
157 val & 0xffff, val >> 16, val & 0xffff, val >> 16);
158 } else
159 fprintf(objfile, ":%lX\n", (long)val);
160 }
161 }
162
163 void
do_list_pc()164 do_list_pc()
165 {
166 if( pass2 )
167 show_pc = TRUE;
168 }
169
170 void
do_show_val(int32_t v)171 do_show_val(int32_t v)
172 {
173 if( ncode == 0 ){
174 val_to_show = v;
175 show_val = TRUE;
176 show_pc = FALSE;
177 }
178 }
179
180 void
list_error(char * string)181 list_error(char *string)
182 {
183 struct error *p;
184 int l;
185
186 if( listfile == NULL )
187 return;
188 l = strlen(string);
189 p = emalloc(sizeof(struct error) + l);
190 strcpy(p->string, string);
191 p->next = NULL;
192 if( error_list == NULL )
193 error_list = p;
194 else
195 error_last->next = p;
196 error_last = p;
197 }
198
199 void
show_errors()200 show_errors()
201 {
202 struct error *p, *q;
203
204 for( p = error_list; p != NULL; p = q ){
205 if( listfile != NULL )
206 fprintf(listfile, "\t\t\t%s\n", p->string);
207 q = p->next;
208 free(p);
209 }
210 error_list = error_last = NULL;
211 }
212
213 void
listing()214 listing()
215 {
216 if( objfile != NULL && ncode % 8 != 0 && !c_name)
217 fprintf(objfile, "\n");
218 listing_line();
219 show_errors();
220 ncode = 0;
221 show_pc = FALSE;
222 }
223
224 void
listing_line()225 listing_line()
226 {
227 unsigned i;
228
229 if( listfile == NULL ){
230 code_idx = 0;
231 return;
232 }
233 if( show_pc )
234 fprintf(listfile, "%.8X", line_pc);
235 else
236 fprintf(listfile, " ");
237 if( show_val ){
238 fprintf(listfile, " %.8X", val_to_show);
239 i = 2;
240 } else {
241 for( i = 0; i < code_idx; ++i )
242 fprintf(listfile, " %.4X", codes[i]);
243 }
244 if( ncode <= 3 ){
245 for( ; i < 3; ++i )
246 fprintf(listfile, " ");
247 fprintf(listfile, " %s", line);
248 } else
249 fprintf(listfile, "\n");
250 line_pc += code_idx << 4;
251 code_idx = 0;
252 show_val = FALSE;
253 }
254