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