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