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 79 putcode(u_int16_t *v, int n) 80 { 81 for( ; n > 0; --n ) 82 put1code(*v++); 83 } 84 85 void 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 125 c_checkbuf() 126 { 127 if (c_bufptr > (sizeof(c_buf)/sizeof(*c_buf))) 128 c_dumpbuf(); 129 } 130 131 void 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 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 164 do_list_pc() 165 { 166 if( pass2 ) 167 show_pc = TRUE; 168 } 169 170 void 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 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 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 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 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