1 1.17 andvar /* $NetBSD: ncr53cxxx.c,v 1.17 2022/04/21 21:31:11 andvar Exp $ */ 2 1.1 bouyer 3 1.1 bouyer /* 4 1.1 bouyer * Copyright (c) 1995,1999 Michael L. Hitch 5 1.1 bouyer * All rights reserved. 6 1.1 bouyer * 7 1.1 bouyer * Redistribution and use in source and binary forms, with or without 8 1.1 bouyer * modification, are permitted provided that the following conditions 9 1.1 bouyer * are met: 10 1.1 bouyer * 1. Redistributions of source code must retain the above copyright 11 1.1 bouyer * notice, this list of conditions and the following disclaimer. 12 1.1 bouyer * 2. Redistributions in binary form must reproduce the above copyright 13 1.1 bouyer * notice, this list of conditions and the following disclaimer in the 14 1.1 bouyer * documentation and/or other materials provided with the distribution. 15 1.1 bouyer * 16 1.1 bouyer * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 1.1 bouyer * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 1.1 bouyer * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 1.1 bouyer * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 1.1 bouyer * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 1.1 bouyer * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 1.1 bouyer * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 1.1 bouyer * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 1.1 bouyer * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 1.1 bouyer * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 1.1 bouyer */ 27 1.1 bouyer 28 1.1 bouyer /* ncr53cxxx.c - SCSI SCRIPTS Assembler */ 29 1.1 bouyer 30 1.12 lukem #include <sys/cdefs.h> 31 1.17 andvar __RCSID("$NetBSD: ncr53cxxx.c,v 1.17 2022/04/21 21:31:11 andvar Exp $"); 32 1.12 lukem 33 1.1 bouyer #include <stdio.h> 34 1.1 bouyer #include <stdlib.h> 35 1.1 bouyer #include <string.h> 36 1.1 bouyer #include <time.h> 37 1.1 bouyer 38 1.1 bouyer #ifndef AMIGA 39 1.1 bouyer #define strcmpi strcasecmp 40 1.1 bouyer #endif 41 1.1 bouyer 42 1.1 bouyer #define MAXTOKENS 16 43 1.1 bouyer #define MAXINST 1024 44 1.1 bouyer #define MAXSYMBOLS 128 45 1.1 bouyer 46 1.1 bouyer struct { 47 1.1 bouyer int type; 48 1.1 bouyer char *name; 49 1.1 bouyer } tokens[MAXTOKENS]; 50 1.1 bouyer int ntokens; 51 1.1 bouyer int tokenix; 52 1.1 bouyer 53 1.1 bouyer void f_proc (void); 54 1.1 bouyer void f_pass (void); 55 1.1 bouyer void f_list (void); /* ENTRY, EXTERNAL label list */ 56 1.1 bouyer void f_define (void); /* ABSOLUTE, RELATIVE label list */ 57 1.1 bouyer void f_move (void); 58 1.1 bouyer void f_jump (void); 59 1.1 bouyer void f_call (void); 60 1.1 bouyer void f_return (void); 61 1.1 bouyer void f_int (void); 62 1.10 bouyer void f_intfly (void); 63 1.1 bouyer void f_select (void); 64 1.1 bouyer void f_reselect (void); 65 1.1 bouyer void f_wait (void); 66 1.1 bouyer void f_disconnect (void); 67 1.1 bouyer void f_set (void); 68 1.1 bouyer void f_clear (void); 69 1.1 bouyer void f_load (void); 70 1.1 bouyer void f_store (void); 71 1.2 bouyer void f_nop (void); 72 1.1 bouyer void f_arch (void); 73 1.1 bouyer 74 1.1 bouyer struct { 75 1.1 bouyer char *name; 76 1.1 bouyer void (*func)(void); 77 1.1 bouyer } directives[] = { 78 1.1 bouyer {"PROC", f_proc}, 79 1.1 bouyer {"PASS", f_pass}, 80 1.1 bouyer {"ENTRY", f_list}, 81 1.1 bouyer {"ABSOLUTE", f_define}, 82 1.1 bouyer {"EXTERN", f_list}, 83 1.1 bouyer {"EXTERNAL", f_list}, 84 1.1 bouyer {"RELATIVE", f_define}, 85 1.1 bouyer {"MOVE", f_move}, 86 1.1 bouyer {"JUMP", f_jump}, 87 1.1 bouyer {"CALL", f_call}, 88 1.1 bouyer {"RETURN", f_return}, 89 1.1 bouyer {"INT", f_int}, 90 1.10 bouyer {"INTFLY", f_intfly}, 91 1.1 bouyer {"SELECT", f_select}, 92 1.1 bouyer {"RESELECT", f_reselect}, 93 1.1 bouyer {"WAIT", f_wait}, 94 1.1 bouyer {"DISCONNECT", f_disconnect}, 95 1.1 bouyer {"SET", f_set}, 96 1.1 bouyer {"CLEAR", f_clear}, 97 1.1 bouyer {"LOAD", f_load}, 98 1.1 bouyer {"STORE", f_store}, 99 1.2 bouyer {"NOP", f_nop}, 100 1.1 bouyer {"ARCH", f_arch}, 101 1.1 bouyer {NULL, NULL}}; 102 1.1 bouyer 103 1.1 bouyer u_int32_t script[MAXINST]; 104 1.1 bouyer int dsps; 105 1.1 bouyer char *script_name = "SCRIPT"; 106 1.1 bouyer u_int32_t inst0, inst1, inst2; 107 1.1 bouyer unsigned int ninsts; 108 1.1 bouyer unsigned int npatches; 109 1.1 bouyer 110 1.1 bouyer struct patchlist { 111 1.1 bouyer struct patchlist *next; 112 1.1 bouyer unsigned offset; 113 1.7 fredette } *patches; 114 1.1 bouyer 115 1.1 bouyer #define S_LABEL 0x0000 116 1.1 bouyer #define S_ABSOLUTE 0x0001 117 1.1 bouyer #define S_RELATIVE 0x0002 118 1.1 bouyer #define S_EXTERNAL 0x0003 119 1.1 bouyer #define F_DEFINED 0x0001 120 1.1 bouyer #define F_ENTRY 0x0002 121 1.1 bouyer struct { 122 1.1 bouyer short type; 123 1.1 bouyer short flags; 124 1.1 bouyer u_int32_t value; 125 1.1 bouyer struct patchlist *patchlist; 126 1.1 bouyer char *name; 127 1.1 bouyer } symbols[MAXSYMBOLS]; 128 1.1 bouyer int nsymbols; 129 1.1 bouyer 130 1.1 bouyer char *stypes[] = {"Label", "Absolute", "Relative", "External"}; 131 1.1 bouyer 132 1.1 bouyer char *phases[] = { 133 1.1 bouyer "data_out", "data_in", "cmd", "status", 134 1.1 bouyer "res4", "res5", "msg_out", "msg_in" 135 1.1 bouyer }; 136 1.1 bouyer 137 1.1 bouyer struct ncrregs { 138 1.1 bouyer char *name; 139 1.7 fredette int addr[5]; 140 1.1 bouyer }; 141 1.7 fredette #define ARCH700 1 142 1.7 fredette #define ARCH710 2 143 1.7 fredette #define ARCH720 3 144 1.7 fredette #define ARCH810 4 145 1.7 fredette #define ARCH825 5 146 1.1 bouyer 147 1.1 bouyer struct ncrregs regs[] = { 148 1.7 fredette {"scntl0", {0x00, 0x00, 0x00, 0x00, 0x00}}, 149 1.7 fredette {"scntl1", {0x01, 0x01, 0x01, 0x01, 0x01}}, 150 1.7 fredette {"sdid", {0x02, 0x02, -1, -1, -1}}, 151 1.7 fredette {"sien", {0x03, 0x03, -1, -1, -1}}, 152 1.7 fredette {"scid", {0x04, 0x04, -1, -1, -1}}, 153 1.7 fredette {"scntl2", { -1, -1, 0x02, 0x02, 0x02}}, 154 1.7 fredette {"scntl3", { -1, -1, 0x03, 0x03, 0x03}}, 155 1.7 fredette {"scid", { -1, -1, 0x04, 0x04, 0x04}}, 156 1.7 fredette {"sxfer", {0x05, 0x05, 0x05, 0x05, 0x05}}, 157 1.7 fredette {"sodl", {0x06, 0x06, -1, -1, -1}}, 158 1.7 fredette {"socl", {0x07, 0x07, -1, -1, -1}}, 159 1.7 fredette {"sdid", { -1, -1, 0x06, 0x06, 0x06}}, 160 1.7 fredette {"gpreg", { -1, -1, 0x07, 0x07, 0x07}}, 161 1.7 fredette {"sfbr", {0x08, 0x08, 0x08, 0x08, 0x08}}, 162 1.7 fredette {"sidl", {0x09, 0x09, -1, -1, -1}}, 163 1.7 fredette {"sbdl", {0x0a, 0x0a, -1, -1, -1}}, 164 1.7 fredette {"socl", { -1, -1, 0x09, 0x09, 0x09}}, 165 1.7 fredette {"ssid", { -1, -1, 0x0a, 0x0a, 0x0a}}, 166 1.7 fredette {"sbcl", {0x0b, 0x0b, 0x0b, 0x0b, 0x0b}}, 167 1.7 fredette {"dstat", {0x0c, 0x0c, 0x0c, 0x0c, 0x0c}}, 168 1.7 fredette {"sstat0", {0x0d, 0x0d, 0x0d, 0x0d, 0x0d}}, 169 1.7 fredette {"sstat1", {0x0e, 0x0e, 0x0e, 0x0e, 0x0e}}, 170 1.7 fredette {"sstat2", {0x0f, 0x0f, 0x0f, 0x0f, 0x0f}}, 171 1.7 fredette {"dsa0", { -1, 0x10, 0x10, 0x10, 0x10}}, 172 1.7 fredette {"dsa1", { -1, 0x11, 0x11, 0x11, 0x11}}, 173 1.7 fredette {"dsa2", { -1, 0x12, 0x12, 0x12, 0x12}}, 174 1.7 fredette {"dsa3", { -1, 0x13, 0x13, 0x13, 0x13}}, 175 1.7 fredette {"ctest0", {0x14, 0x14, 0x18, 0x18, 0x18}}, 176 1.7 fredette {"ctest1", {0x15, 0x15, 0x19, 0x19, 0x19}}, 177 1.7 fredette {"ctest2", {0x16, 0x16, 0x1a, 0x1a, 0x1a}}, 178 1.7 fredette {"ctest3", {0x17, 0x17, 0x1b, 0x1b, 0x1b}}, 179 1.7 fredette {"ctest4", {0x18, 0x18, 0x21, 0x21, 0x21}}, 180 1.7 fredette {"ctest5", {0x19, 0x19, 0x22, 0x22, 0x22}}, 181 1.7 fredette {"ctest6", {0x1a, 0x1a, 0x23, 0x23, 0x23}}, 182 1.7 fredette {"ctest7", {0x1b, 0x1b, -1, -1, -1}}, 183 1.7 fredette {"temp0", {0x1c, 0x1c, 0x1c, 0x1c, 0x1c}}, 184 1.7 fredette {"temp1", {0x1d, 0x1d, 0x1d, 0x1d, 0x1d}}, 185 1.7 fredette {"temp2", {0x1e, 0x1e, 0x1e, 0x1e, 0x1e}}, 186 1.7 fredette {"temp3", {0x1f, 0x1f, 0x1f, 0x1f, 0x1f}}, 187 1.7 fredette {"dfifo", {0x20, 0x20, 0x20, 0x20, 0x20}}, 188 1.7 fredette {"istat", {0x21, 0x21, 0x14, 0x14, 0x14}}, 189 1.11 tsutsui {"ctest8", {0x22, 0x22, -1, -1, -1}}, 190 1.7 fredette {"lcrc", { -1, 0x23, -1, -1, -1}}, 191 1.11 tsutsui {"ctest9", {0x23, -1, -1, -1, -1}}, 192 1.7 fredette {"dbc0", {0x24, 0x24, 0x24, 0x24, 0x24}}, 193 1.7 fredette {"dbc1", {0x25, 0x25, 0x25, 0x25, 0x25}}, 194 1.7 fredette {"dbc2", {0x26, 0x26, 0x26, 0x26, 0x26}}, 195 1.7 fredette {"dcmd", {0x27, 0x27, 0x27, 0x27, 0x27}}, 196 1.7 fredette {"dnad0", {0x28, 0x28, 0x28, 0x28, 0x28}}, 197 1.7 fredette {"dnad1", {0x29, 0x29, 0x29, 0x29, 0x29}}, 198 1.7 fredette {"dnad2", {0x2a, 0x2a, 0x2a, 0x2a, 0x2a}}, 199 1.7 fredette {"dnad3", {0x2b, 0x2b, 0x2b, 0x2b, 0x2b}}, 200 1.7 fredette {"dsp0", {0x2c, 0x2c, 0x2c, 0x2c, 0x2c}}, 201 1.7 fredette {"dsp1", {0x2d, 0x2d, 0x2d, 0x2d, 0x2d}}, 202 1.7 fredette {"dsp2", {0x2e, 0x2e, 0x2e, 0x2e, 0x2e}}, 203 1.7 fredette {"dsp3", {0x2f, 0x2f, 0x2f, 0x2f, 0x2f}}, 204 1.7 fredette {"dsps0", {0x30, 0x30, 0x30, 0x30, 0x30}}, 205 1.7 fredette {"dsps1", {0x31, 0x31, 0x31, 0x31, 0x31}}, 206 1.7 fredette {"dsps2", {0x32, 0x32, 0x32, 0x32, 0x32}}, 207 1.7 fredette {"dsps3", {0x33, 0x33, 0x33, 0x33, 0x33}}, 208 1.7 fredette {"scratch0", { -1, 0x34, -1, -1, -1}}, 209 1.7 fredette {"scratch1", { -1, 0x35, -1, -1, -1}}, 210 1.7 fredette {"scratch2", { -1, 0x36, -1, -1, -1}}, 211 1.7 fredette {"scratch3", { -1, 0x37, -1, -1, -1}}, 212 1.11 tsutsui {"scratcha0", {0x10, -1, 0x34, 0x34, 0x34}}, 213 1.11 tsutsui {"scratcha1", {0x11, -1, 0x35, 0x35, 0x35}}, 214 1.11 tsutsui {"scratcha2", {0x12, -1, 0x36, 0x36, 0x36}}, 215 1.11 tsutsui {"scratcha3", {0x13, -1, 0x37, 0x37, 0x37}}, 216 1.7 fredette {"dmode", {0x34, 0x38, 0x38, 0x38, 0x38}}, 217 1.7 fredette {"dien", {0x39, 0x39, 0x39, 0x39, 0x39}}, 218 1.7 fredette {"dwt", {0x3a, 0x3a, 0x3a, -1, -1}}, 219 1.7 fredette {"sbr", { -1, -1, -1, 0x3a, 0x3a}}, 220 1.7 fredette {"dcntl", {0x3b, 0x3b, 0x3b, 0x3b, 0x3b}}, 221 1.7 fredette {"addr0", { -1, 0x3c, 0x3c, 0x3c, 0x3c}}, 222 1.7 fredette {"addr1", { -1, 0x3d, 0x3d, 0x3d, 0x3d}}, 223 1.7 fredette {"addr2", { -1, 0x3e, 0x3e, 0x3e, 0x3e}}, 224 1.7 fredette {"addr3", { -1, 0x3f, 0x3f, 0x3f, 0x3f}}, 225 1.7 fredette {"sien0", { -1, -1, 0x40, 0x40, 0x40}}, 226 1.7 fredette {"sien1", { -1, -1, 0x41, 0x41, 0x41}}, 227 1.7 fredette {"sist0", { -1, -1, 0x42, 0x42, 0x42}}, 228 1.7 fredette {"sist1", { -1, -1, 0x43, 0x43, 0x43}}, 229 1.7 fredette {"slpar", { -1, -1, 0x44, 0x44, 0x44}}, 230 1.7 fredette {"swide", { -1, -1, 0x45, -1, 0x45}}, 231 1.7 fredette {"macntl", { -1, -1, 0x46, 0x46, 0x46}}, 232 1.7 fredette {"gpcntl", { -1, -1, 0x47, 0x47, 0x47}}, 233 1.7 fredette {"stime0", { -1, -1, 0x48, 0x48, 0x48}}, 234 1.7 fredette {"stime1", { -1, -1, 0x49, 0x49, 0x49}}, 235 1.7 fredette {"respid0", { -1, -1, 0x4a, 0x4a, 0x4a}}, 236 1.7 fredette {"respid1", { -1, -1, 0x4b, -1, 0x4b}}, 237 1.7 fredette {"stest0", { -1, -1, 0x4c, 0x4c, 0x4c}}, 238 1.7 fredette {"stest1", { -1, -1, 0x4d, 0x4d, 0x4d}}, 239 1.7 fredette {"stest2", { -1, -1, 0x4e, 0x4e, 0x4e}}, 240 1.7 fredette {"stest3", { -1, -1, 0x4f, 0x4f, 0x4f}}, 241 1.7 fredette {"sidl0", { -1, -1, 0x50, 0x50, 0x50}}, 242 1.7 fredette {"sidl1", { -1, -1, 0x51, -1, 0x51}}, 243 1.7 fredette {"sodl0", { -1, -1, 0x54, 0x54, 0x54}}, 244 1.7 fredette {"sodl1", { -1, -1, 0x55, -1, 0x55}}, 245 1.7 fredette {"sbdl0", { -1, -1, 0x58, 0x58, 0x58}}, 246 1.7 fredette {"sbdl1", { -1, -1, 0x59, -1, 0x59}}, 247 1.11 tsutsui {"scratchb0", {0x3c, -1, 0x5c, 0x5c, 0x5c}}, 248 1.11 tsutsui {"scratchb1", {0x3d, -1, 0x5d, 0x5d, 0x5d}}, 249 1.11 tsutsui {"scratchb2", {0x3e, -1, 0x5e, 0x5e, 0x5e}}, 250 1.11 tsutsui {"scratchb3", {0x3f, -1, 0x5f, 0x5f, 0x5f}}, 251 1.7 fredette {"scratchc0", { -1, -1, -1, -1, 0x60}}, 252 1.7 fredette {"scratchc1", { -1, -1, -1, -1, 0x61}}, 253 1.7 fredette {"scratchc2", { -1, -1, -1, -1, 0x62}}, 254 1.7 fredette {"scratchc3", { -1, -1, -1, -1, 0x63}}, 255 1.7 fredette {"scratchd0", { -1, -1, -1, -1, 0x64}}, 256 1.7 fredette {"scratchd1", { -1, -1, -1, -1, 0x65}}, 257 1.9 bouyer {"scratchd2", { -1, -1, -1, -1, 0x66}}, 258 1.7 fredette {"scratchd3", { -1, -1, -1, -1, 0x67}}, 259 1.7 fredette {"scratche0", { -1, -1, -1, -1, 0x68}}, 260 1.7 fredette {"scratche1", { -1, -1, -1, -1, 0x69}}, 261 1.7 fredette {"scratche2", { -1, -1, -1, -1, 0x6a}}, 262 1.7 fredette {"scratche3", { -1, -1, -1, -1, 0x6b}}, 263 1.7 fredette {"scratchf0", { -1, -1, -1, -1, 0x6c}}, 264 1.7 fredette {"scratchf1", { -1, -1, -1, -1, 0x6d}}, 265 1.7 fredette {"scratchf2", { -1, -1, -1, -1, 0x6e}}, 266 1.7 fredette {"scratchf3", { -1, -1, -1, -1, 0x6f}}, 267 1.7 fredette {"scratchg0", { -1, -1, -1, -1, 0x70}}, 268 1.7 fredette {"scratchg1", { -1, -1, -1, -1, 0x71}}, 269 1.7 fredette {"scratchg2", { -1, -1, -1, -1, 0x72}}, 270 1.7 fredette {"scratchg3", { -1, -1, -1, -1, 0x73}}, 271 1.7 fredette {"scratchh0", { -1, -1, -1, -1, 0x74}}, 272 1.7 fredette {"scratchh1", { -1, -1, -1, -1, 0x75}}, 273 1.7 fredette {"scratchh2", { -1, -1, -1, -1, 0x7e}}, 274 1.7 fredette {"scratchh3", { -1, -1, -1, -1, 0x77}}, 275 1.7 fredette {"scratchi0", { -1, -1, -1, -1, 0x78}}, 276 1.7 fredette {"scratchi1", { -1, -1, -1, -1, 0x79}}, 277 1.7 fredette {"scratchi2", { -1, -1, -1, -1, 0x7a}}, 278 1.7 fredette {"scratchi3", { -1, -1, -1, -1, 0x7b}}, 279 1.7 fredette {"scratchj0", { -1, -1, -1, -1, 0x7c}}, 280 1.7 fredette {"scratchj1", { -1, -1, -1, -1, 0x7d}}, 281 1.7 fredette {"scratchj2", { -1, -1, -1, -1, 0x7e}}, 282 1.7 fredette {"scratchj3", { -1, -1, -1, -1, 0x7f}}, 283 1.1 bouyer }; 284 1.1 bouyer 285 1.1 bouyer int lineno; 286 1.1 bouyer int err_listed; 287 1.1 bouyer int arch; 288 1.1 bouyer int partial_flag; 289 1.1 bouyer 290 1.1 bouyer char inbuf[128]; 291 1.1 bouyer 292 1.1 bouyer char *sourcefile; 293 1.1 bouyer char *outputfile; 294 1.1 bouyer char *listfile; 295 1.1 bouyer char *errorfile; 296 1.1 bouyer 297 1.1 bouyer FILE *infp; 298 1.1 bouyer FILE *outfp; 299 1.1 bouyer FILE *listfp; 300 1.1 bouyer FILE *errfp; 301 1.1 bouyer 302 1.1 bouyer void setarch(char *); 303 1.1 bouyer void parse (void); 304 1.1 bouyer void process (void); 305 1.1 bouyer void emit_symbols (void); 306 1.1 bouyer void list_symbols (void); 307 1.1 bouyer void errout (char *); 308 1.1 bouyer void define_symbol (char *, u_int32_t, short, short); 309 1.7 fredette void patch_label (void); 310 1.1 bouyer void close_script (void); 311 1.1 bouyer void new_script (char *); 312 1.1 bouyer void store_inst (void); 313 1.1 bouyer int expression (int *); 314 1.1 bouyer int evaluate (int); 315 1.1 bouyer int number (char *); 316 1.1 bouyer int lookup (char *); 317 1.1 bouyer int reserved (char *, int); 318 1.1 bouyer int CheckPhase (int); 319 1.1 bouyer int CheckRegister (int); 320 1.1 bouyer void transfer (int, int); 321 1.1 bouyer void select_reselect (int); 322 1.1 bouyer void set_clear (u_int32_t); 323 1.1 bouyer void block_move (void); 324 1.1 bouyer void register_write (void); 325 1.1 bouyer void memory_to_memory (void); 326 1.1 bouyer void loadstore (int); 327 1.1 bouyer void error_line(void); 328 1.1 bouyer char *makefn(char *, char *); 329 1.1 bouyer void usage(void); 330 1.1 bouyer 331 1.1 bouyer int 332 1.1 bouyer main (int argc, char *argv[]) 333 1.1 bouyer { 334 1.1 bouyer int i; 335 1.7 fredette struct patchlist *p; 336 1.1 bouyer 337 1.1 bouyer if (argc < 2 || argv[1][0] == '-') 338 1.1 bouyer usage(); 339 1.1 bouyer sourcefile = argv[1]; 340 1.1 bouyer infp = fopen (sourcefile, "r"); 341 1.1 bouyer if (infp == NULL) { 342 1.1 bouyer perror ("open source"); 343 1.1 bouyer fprintf (stderr, "scc: error opening source file %s\n", argv[1]); 344 1.1 bouyer exit (1); 345 1.1 bouyer } 346 1.1 bouyer /* 347 1.1 bouyer * process options 348 1.1 bouyer * -l [listfile] 349 1.1 bouyer * -o [outputfile] 350 1.1 bouyer * -p [outputfile] 351 1.1 bouyer * -z [debugfile] 352 1.1 bouyer * -e [errorfile] 353 1.1 bouyer * -a arch 354 1.1 bouyer * -v 355 1.1 bouyer * -u 356 1.1 bouyer */ 357 1.1 bouyer for (i = 2; i < argc; ++i) { 358 1.1 bouyer if (argv[i][0] != '-') 359 1.1 bouyer usage(); 360 1.1 bouyer switch (argv[i][1]) { 361 1.1 bouyer case 'o': 362 1.1 bouyer case 'p': 363 1.1 bouyer partial_flag = argv[i][1] == 'p'; 364 1.1 bouyer if (i + 1 >= argc || argv[i + 1][0] == '-') 365 1.1 bouyer outputfile = makefn (sourcefile, "out"); 366 1.1 bouyer else { 367 1.1 bouyer outputfile = argv[i + 1]; 368 1.1 bouyer ++i; 369 1.1 bouyer } 370 1.1 bouyer break; 371 1.1 bouyer case 'l': 372 1.1 bouyer if (i + 1 >= argc || argv[i + 1][0] == '-') 373 1.1 bouyer listfile = makefn (sourcefile, "lis"); 374 1.1 bouyer else { 375 1.1 bouyer listfile = argv[i + 1]; 376 1.1 bouyer ++i; 377 1.1 bouyer } 378 1.1 bouyer break; 379 1.1 bouyer case 'e': 380 1.1 bouyer if (i + 1 >= argc || argv[i + 1][0] == '-') 381 1.1 bouyer errorfile = makefn (sourcefile, "err"); 382 1.1 bouyer else { 383 1.1 bouyer errorfile = argv[i + 1]; 384 1.1 bouyer ++i; 385 1.1 bouyer } 386 1.1 bouyer break; 387 1.1 bouyer case 'a': 388 1.1 bouyer if (i + 1 == argc) 389 1.1 bouyer usage(); 390 1.1 bouyer setarch(argv[i +1]); 391 1.1 bouyer if (arch == 0) { 392 1.1 bouyer fprintf(stderr,"%s: bad arch '%s'\n", 393 1.1 bouyer argv[0], argv[i +1]); 394 1.1 bouyer exit(1); 395 1.1 bouyer } 396 1.1 bouyer ++i; 397 1.1 bouyer break; 398 1.1 bouyer default: 399 1.1 bouyer fprintf (stderr, "scc: unrecognized option '%c'\n", 400 1.1 bouyer argv[i][1]); 401 1.1 bouyer usage(); 402 1.1 bouyer } 403 1.1 bouyer } 404 1.1 bouyer if (outputfile) 405 1.1 bouyer outfp = fopen (outputfile, "w"); 406 1.1 bouyer if (listfile) 407 1.1 bouyer listfp = fopen (listfile, "w"); 408 1.1 bouyer if (errorfile) 409 1.1 bouyer errfp = fopen (errorfile, "w"); 410 1.1 bouyer else 411 1.1 bouyer errfp = stderr; 412 1.1 bouyer 413 1.1 bouyer if (outfp) { 414 1.1 bouyer time_t cur_time; 415 1.1 bouyer 416 1.17 andvar fprintf(outfp, "/*\t$NetBSD: ncr53cxxx.c,v 1.17 2022/04/21 21:31:11 andvar Exp $\t*/\n"); 417 1.1 bouyer fprintf(outfp, "/*\n"); 418 1.1 bouyer fprintf(outfp, " *\tDO NOT EDIT - this file is automatically generated.\n"); 419 1.1 bouyer time(&cur_time); 420 1.1 bouyer fprintf(outfp, " *\tcreated from %s on %s", sourcefile, ctime(&cur_time)); 421 1.1 bouyer fprintf(outfp, " */\n"); 422 1.1 bouyer } 423 1.1 bouyer 424 1.1 bouyer while (fgets (inbuf, sizeof (inbuf), infp)) { 425 1.1 bouyer ++lineno; 426 1.1 bouyer if (listfp) 427 1.1 bouyer fprintf (listfp, "%3d: %s", lineno, inbuf); 428 1.1 bouyer err_listed = 0; 429 1.1 bouyer parse (); 430 1.1 bouyer if (ntokens) { 431 1.1 bouyer #ifdef DUMP_TOKENS 432 1.1 bouyer int i; 433 1.1 bouyer 434 1.1 bouyer fprintf (listfp, " %d tokens\n", ntokens); 435 1.1 bouyer for (i = 0; i < ntokens; ++i) { 436 1.1 bouyer fprintf (listfp, " %d: ", i); 437 1.1 bouyer if (tokens[i].type) 438 1.1 bouyer fprintf (listfp,"'%c'\n", tokens[i].type); 439 1.1 bouyer else 440 1.1 bouyer fprintf (listfp, "%s\n", tokens[i].name); 441 1.1 bouyer } 442 1.1 bouyer #endif 443 1.1 bouyer if (ntokens >= 2 && tokens[0].type == 0 && 444 1.1 bouyer tokens[1].type == ':') { 445 1.1 bouyer define_symbol (tokens[0].name, dsps, S_LABEL, F_DEFINED); 446 1.1 bouyer tokenix += 2; 447 1.1 bouyer } 448 1.1 bouyer if (tokenix < ntokens) 449 1.1 bouyer process (); 450 1.1 bouyer } 451 1.1 bouyer 452 1.1 bouyer } 453 1.1 bouyer close_script (); 454 1.1 bouyer emit_symbols (); 455 1.1 bouyer if (outfp && !partial_flag) { 456 1.1 bouyer fprintf (outfp, "\nu_int32_t INSTRUCTIONS = 0x%08x;\n", ninsts); 457 1.1 bouyer fprintf (outfp, "u_int32_t PATCHES = 0x%08x;\n", npatches); 458 1.7 fredette fprintf (outfp, "u_int32_t LABELPATCHES[] = {\n"); 459 1.7 fredette p = patches; 460 1.7 fredette while (p) { 461 1.7 fredette fprintf (outfp, "\t0x%08x,\n", p->offset / 4); 462 1.7 fredette p = p->next; 463 1.7 fredette } 464 1.7 fredette fprintf (outfp, "};\n\n"); 465 1.1 bouyer } 466 1.1 bouyer list_symbols (); 467 1.1 bouyer exit(0); 468 1.1 bouyer } 469 1.1 bouyer 470 1.1 bouyer void setarch(char *val) 471 1.1 bouyer { 472 1.1 bouyer switch (atoi(val)) { 473 1.7 fredette case 700: 474 1.7 fredette arch = ARCH700; 475 1.7 fredette break; 476 1.1 bouyer case 710: 477 1.1 bouyer arch = ARCH710; 478 1.1 bouyer break; 479 1.1 bouyer case 720: 480 1.1 bouyer arch = ARCH720; 481 1.1 bouyer break; 482 1.1 bouyer case 810: 483 1.1 bouyer arch = ARCH810; 484 1.1 bouyer break; 485 1.1 bouyer case 825: 486 1.1 bouyer arch = ARCH825; 487 1.1 bouyer break; 488 1.1 bouyer default: 489 1.1 bouyer arch = 0; 490 1.1 bouyer } 491 1.1 bouyer } 492 1.1 bouyer 493 1.1 bouyer void emit_symbols () 494 1.1 bouyer { 495 1.1 bouyer int i; 496 1.1 bouyer struct patchlist *p; 497 1.1 bouyer 498 1.1 bouyer if (nsymbols == 0 || outfp == NULL) 499 1.1 bouyer return; 500 1.1 bouyer 501 1.1 bouyer for (i = 0; i < nsymbols; ++i) { 502 1.1 bouyer char *code; 503 1.3 bouyer if ((symbols[i].flags & F_DEFINED) == 0 && 504 1.3 bouyer symbols[i].type != S_EXTERNAL) { 505 1.3 bouyer fprintf(stderr, "warning: symbol %s undefined\n", 506 1.3 bouyer symbols[i].name); 507 1.3 bouyer } 508 1.1 bouyer if (symbols[i].type == S_ABSOLUTE) 509 1.1 bouyer code = "A_"; 510 1.1 bouyer else if (symbols[i].type == S_RELATIVE) 511 1.1 bouyer code = "R_"; 512 1.1 bouyer else if (symbols[i].type == S_EXTERNAL) 513 1.1 bouyer code = "E_"; 514 1.1 bouyer else if (symbols[i].flags & F_ENTRY) 515 1.1 bouyer code = "Ent_"; 516 1.1 bouyer else 517 1.1 bouyer continue; 518 1.1 bouyer fprintf (outfp, "#define\t%s%s\t0x%08x\n", code, symbols[i].name, 519 1.1 bouyer symbols[i].value); 520 1.1 bouyer if (symbols[i].flags & F_ENTRY || symbols[i].patchlist == NULL) 521 1.1 bouyer continue; 522 1.1 bouyer fprintf (outfp, "u_int32_t %s%s_Used[] = {\n", code, symbols[i].name); 523 1.1 bouyer #if 1 524 1.1 bouyer p = symbols[i].patchlist; 525 1.1 bouyer while (p) { 526 1.1 bouyer fprintf (outfp, "\t0x%08x,\n", p->offset / 4); 527 1.1 bouyer p = p->next; 528 1.1 bouyer } 529 1.1 bouyer #endif 530 1.1 bouyer fprintf (outfp, "};\n\n"); 531 1.1 bouyer } 532 1.1 bouyer /* patches ? */ 533 1.1 bouyer } 534 1.1 bouyer 535 1.1 bouyer void list_symbols () 536 1.1 bouyer { 537 1.1 bouyer int i; 538 1.1 bouyer 539 1.1 bouyer if (nsymbols == 0 || listfp == NULL) 540 1.1 bouyer return; 541 1.1 bouyer fprintf (listfp, "\n\nValue Type Symbol\n"); 542 1.1 bouyer for (i = 0; i < nsymbols; ++i) { 543 1.1 bouyer fprintf (listfp, "%08x: %-8s %s\n", symbols[i].value, 544 1.1 bouyer stypes[symbols[i].type], symbols[i].name); 545 1.1 bouyer } 546 1.1 bouyer } 547 1.1 bouyer 548 1.1 bouyer void errout (char *text) 549 1.1 bouyer { 550 1.1 bouyer error_line(); 551 1.1 bouyer fprintf (errfp, "*** %s ***\n", text); 552 1.1 bouyer } 553 1.1 bouyer 554 1.1 bouyer void parse () 555 1.1 bouyer { 556 1.1 bouyer char *p = inbuf; 557 1.1 bouyer char c; 558 1.1 bouyer char string[64]; 559 1.1 bouyer char *s; 560 1.1 bouyer 561 1.1 bouyer ntokens = tokenix = 0; 562 1.1 bouyer while (1) { 563 1.1 bouyer while ((c = *p++) && c != '\n' && (c <= ' ' || c == '\t')) 564 1.1 bouyer ; 565 1.1 bouyer if (c == '\n' || c == 0 || c == ';') 566 1.1 bouyer break; 567 1.1 bouyer if (ntokens >= MAXTOKENS) { 568 1.1 bouyer errout ("Token table full"); 569 1.1 bouyer break; 570 1.1 bouyer } 571 1.1 bouyer if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') || 572 1.1 bouyer (c >= 'A' && c <= 'Z') || c == '$' || c == '_') { 573 1.1 bouyer s = string; 574 1.1 bouyer *s++ = c; 575 1.1 bouyer while (((c = *p) >= '0' && c <= '9') || 576 1.1 bouyer (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || 577 1.1 bouyer c == '_' || c == '$') { 578 1.1 bouyer *s++ = *p++; 579 1.1 bouyer } 580 1.1 bouyer *s = 0; 581 1.1 bouyer tokens[ntokens].name = malloc (strlen (string) + 1); 582 1.1 bouyer strcpy (tokens[ntokens].name, string); 583 1.1 bouyer tokens[ntokens].type = 0; 584 1.1 bouyer } 585 1.1 bouyer else { 586 1.1 bouyer tokens[ntokens].type = c; 587 1.1 bouyer } 588 1.1 bouyer ++ntokens; 589 1.1 bouyer } 590 1.1 bouyer return; 591 1.1 bouyer } 592 1.1 bouyer 593 1.1 bouyer void process () 594 1.1 bouyer { 595 1.1 bouyer int i; 596 1.1 bouyer 597 1.1 bouyer if (tokens[tokenix].type) { 598 1.1 bouyer error_line(); 599 1.1 bouyer fprintf (errfp, "Error: expected directive, found '%c'\n", 600 1.1 bouyer tokens[tokenix].type); 601 1.1 bouyer return; 602 1.1 bouyer } 603 1.1 bouyer for (i = 0; directives[i].name; ++i) { 604 1.1 bouyer if (strcmpi (directives[i].name, tokens[tokenix].name) == 0) 605 1.1 bouyer break; 606 1.1 bouyer } 607 1.1 bouyer if (directives[i].name == NULL) { 608 1.1 bouyer error_line(); 609 1.1 bouyer fprintf (errfp, "Error: expected directive, found \"%s\"\n", 610 1.1 bouyer tokens[tokenix].name); 611 1.1 bouyer return; 612 1.1 bouyer } 613 1.1 bouyer if (directives[i].func == NULL) { 614 1.1 bouyer error_line(); 615 1.1 bouyer fprintf (errfp, "No function for directive \"%s\"\n", tokens[tokenix].name); 616 1.1 bouyer } else { 617 1.1 bouyer #if 0 618 1.1 bouyer fprintf (listfp, "Processing directive \"%s\"\n", directives[i].name); 619 1.1 bouyer #endif 620 1.1 bouyer ++tokenix; 621 1.1 bouyer (*directives[i].func) (); 622 1.1 bouyer } 623 1.1 bouyer } 624 1.1 bouyer 625 1.1 bouyer void define_symbol (char *name, u_int32_t value, short type, short flags) 626 1.1 bouyer { 627 1.1 bouyer int i; 628 1.1 bouyer struct patchlist *p; 629 1.1 bouyer 630 1.1 bouyer for (i = 0; i < nsymbols; ++i) { 631 1.1 bouyer if (symbols[i].type == type && strcmp (symbols[i].name, name) == 0) { 632 1.1 bouyer if (symbols[i].flags & F_DEFINED) { 633 1.1 bouyer error_line(); 634 1.1 bouyer fprintf (errfp, "*** Symbol \"%s\" multiply defined\n", 635 1.1 bouyer name); 636 1.1 bouyer } else { 637 1.1 bouyer symbols[i].flags |= flags; 638 1.1 bouyer symbols[i].value = value; 639 1.1 bouyer p = symbols[i].patchlist; 640 1.1 bouyer while (p) { 641 1.1 bouyer if (p->offset > dsps) 642 1.1 bouyer errout ("Whoops\007"); 643 1.1 bouyer else 644 1.7 fredette script[p->offset / 4] += dsps; 645 1.1 bouyer p = p->next; 646 1.1 bouyer } 647 1.1 bouyer } 648 1.1 bouyer return; 649 1.1 bouyer } 650 1.1 bouyer } 651 1.1 bouyer if (nsymbols >= MAXSYMBOLS) { 652 1.1 bouyer errout ("Symbol table full"); 653 1.1 bouyer return; 654 1.1 bouyer } 655 1.1 bouyer symbols[nsymbols].type = type; 656 1.1 bouyer symbols[nsymbols].flags = flags; 657 1.1 bouyer symbols[nsymbols].value = value; 658 1.1 bouyer symbols[nsymbols].patchlist = NULL; 659 1.1 bouyer symbols[nsymbols].name = malloc (strlen (name) + 1); 660 1.1 bouyer strcpy (symbols[nsymbols].name, name); 661 1.1 bouyer ++nsymbols; 662 1.1 bouyer } 663 1.1 bouyer 664 1.7 fredette void patch_label (void) 665 1.7 fredette { 666 1.7 fredette struct patchlist *p, **h; 667 1.7 fredette 668 1.7 fredette h = &patches; 669 1.7 fredette while(*h) 670 1.7 fredette h = &(*h)->next; 671 1.7 fredette p = (struct patchlist *) malloc (sizeof (struct patchlist)); 672 1.7 fredette *h = p; 673 1.7 fredette p->next = NULL; 674 1.7 fredette p->offset = dsps + 4; 675 1.7 fredette npatches++; 676 1.7 fredette } 677 1.7 fredette 678 1.1 bouyer void close_script () 679 1.1 bouyer { 680 1.1 bouyer int i; 681 1.1 bouyer 682 1.1 bouyer if (dsps == 0) 683 1.1 bouyer return; 684 1.1 bouyer if (outfp) { 685 1.1 bouyer fprintf (outfp, "const u_int32_t %s[] = {\n", script_name); 686 1.1 bouyer for (i = 0; i < dsps / 4; i += 2) { 687 1.1 bouyer fprintf (outfp, "\t0x%08x, 0x%08x", script[i], 688 1.1 bouyer script[i + 1]); 689 1.1 bouyer /* check for memory move instruction */ 690 1.1 bouyer if ((script[i] & 0xe0000000) == 0xc0000000) 691 1.1 bouyer fprintf (outfp, ", 0x%08x,", script[i + 2]); 692 1.1 bouyer else 693 1.1 bouyer if ((i + 2) <= dsps / 4) fprintf (outfp, ",\t\t"); 694 1.1 bouyer fprintf (outfp, "\t/* %03x - %3d */\n", i * 4, i * 4); 695 1.1 bouyer if ((script[i] & 0xe0000000) == 0xc0000000) 696 1.1 bouyer ++i; 697 1.1 bouyer } 698 1.1 bouyer fprintf (outfp, "};\n\n"); 699 1.1 bouyer } 700 1.1 bouyer dsps = 0; 701 1.1 bouyer } 702 1.1 bouyer 703 1.1 bouyer void new_script (char *name) 704 1.1 bouyer { 705 1.1 bouyer close_script (); 706 1.1 bouyer script_name = malloc (strlen (name) + 1); 707 1.1 bouyer strcpy (script_name, name); 708 1.1 bouyer } 709 1.1 bouyer 710 1.1 bouyer int reserved (char *string, int t) 711 1.1 bouyer { 712 1.1 bouyer if (tokens[t].type == 0 && strcmpi (tokens[t].name, string) == 0) 713 1.1 bouyer return (1); 714 1.1 bouyer return (0); 715 1.1 bouyer } 716 1.1 bouyer 717 1.1 bouyer int CheckPhase (int t) 718 1.1 bouyer { 719 1.1 bouyer int i; 720 1.1 bouyer 721 1.1 bouyer for (i = 0; i < 8; ++i) { 722 1.1 bouyer if (reserved (phases[i], t)) { 723 1.1 bouyer inst0 |= i << 24; 724 1.1 bouyer return (1); 725 1.1 bouyer } 726 1.1 bouyer } 727 1.1 bouyer return (0); 728 1.1 bouyer } 729 1.1 bouyer 730 1.1 bouyer int CheckRegister (int t) 731 1.1 bouyer { 732 1.1 bouyer int i; 733 1.1 bouyer 734 1.1 bouyer if (arch <= 0) { 735 1.1 bouyer errout("'ARCH' statement missing"); 736 1.1 bouyer return -1; 737 1.1 bouyer } 738 1.1 bouyer for (i = 0; i < (sizeof(regs) / sizeof(regs[0])); i++) { 739 1.1 bouyer if (regs[i].addr[arch - 1] >= 0 && reserved(regs[i].name, t)) 740 1.1 bouyer return regs[i].addr[arch-1]; 741 1.1 bouyer } 742 1.1 bouyer return (-1); 743 1.1 bouyer } 744 1.1 bouyer 745 1.1 bouyer int expression (int *t) 746 1.1 bouyer { 747 1.1 bouyer int value; 748 1.1 bouyer int i = *t; 749 1.1 bouyer 750 1.1 bouyer value = evaluate (i++); 751 1.1 bouyer while (i < ntokens) { 752 1.1 bouyer if (tokens[i].type == '+') 753 1.1 bouyer value += evaluate (i + 1); 754 1.1 bouyer else if (tokens[i].type == '-') 755 1.1 bouyer value -= evaluate (i + 1); 756 1.1 bouyer else 757 1.1 bouyer errout ("Unknown identifier"); 758 1.1 bouyer i += 2; 759 1.1 bouyer } 760 1.1 bouyer *t = i; 761 1.1 bouyer return (value); 762 1.1 bouyer } 763 1.1 bouyer 764 1.1 bouyer int evaluate (t) 765 1.1 bouyer { 766 1.1 bouyer int value; 767 1.1 bouyer char *name; 768 1.1 bouyer 769 1.1 bouyer if (tokens[t].type) { 770 1.1 bouyer errout ("Expected an identifier"); 771 1.1 bouyer return (0); 772 1.1 bouyer } 773 1.1 bouyer name = tokens[t].name; 774 1.1 bouyer if (*name >= '0' && *name <= '9') 775 1.1 bouyer value = number (name); 776 1.1 bouyer else 777 1.1 bouyer value = lookup (name); 778 1.1 bouyer return (value); 779 1.1 bouyer } 780 1.1 bouyer 781 1.1 bouyer int number (char *s) 782 1.1 bouyer { 783 1.1 bouyer int value; 784 1.1 bouyer int n; 785 1.1 bouyer int radix; 786 1.1 bouyer 787 1.1 bouyer radix = 10; 788 1.1 bouyer if (*s == '0') { 789 1.1 bouyer ++s; 790 1.1 bouyer radix = 8; 791 1.1 bouyer switch (*s) { 792 1.1 bouyer case 'x': 793 1.1 bouyer case 'X': 794 1.1 bouyer radix = 16; 795 1.1 bouyer break; 796 1.1 bouyer case 'b': 797 1.1 bouyer case 'B': 798 1.1 bouyer radix = 2; 799 1.1 bouyer } 800 1.1 bouyer if (radix != 8) 801 1.1 bouyer ++s; 802 1.1 bouyer } 803 1.1 bouyer value = 0; 804 1.1 bouyer while (*s) { 805 1.1 bouyer n = *s++; 806 1.1 bouyer if (n >= '0' && n <= '9') 807 1.1 bouyer n -= '0'; 808 1.1 bouyer else if (n >= 'a' && n <= 'f') 809 1.1 bouyer n -= 'a' - 10; 810 1.1 bouyer else if (n >= 'A' && n <= 'F') 811 1.1 bouyer n -= 'A' - 10; 812 1.1 bouyer else { 813 1.1 bouyer error_line(); 814 1.1 bouyer fprintf (errfp, "*** Expected digit\n"); 815 1.1 bouyer n = 0; 816 1.1 bouyer } 817 1.1 bouyer if (n >= radix) 818 1.1 bouyer errout ("Expected digit"); 819 1.1 bouyer else 820 1.1 bouyer value = value * radix + n; 821 1.1 bouyer } 822 1.1 bouyer return (value); 823 1.1 bouyer } 824 1.1 bouyer 825 1.1 bouyer int lookup (char *name) 826 1.1 bouyer { 827 1.1 bouyer int i; 828 1.1 bouyer struct patchlist *p; 829 1.1 bouyer 830 1.1 bouyer for (i = 0; i < nsymbols; ++i) { 831 1.1 bouyer if (strcmp (name, symbols[i].name) == 0) { 832 1.1 bouyer if ((symbols[i].flags & F_DEFINED) == 0) { 833 1.1 bouyer p = (struct patchlist *) &symbols[i].patchlist; 834 1.1 bouyer while (p->next) 835 1.1 bouyer p = p->next; 836 1.1 bouyer p->next = (struct patchlist *) malloc (sizeof (struct patchlist)); 837 1.1 bouyer p = p->next; 838 1.1 bouyer p->next = NULL; 839 1.1 bouyer p->offset = dsps + 4; 840 1.1 bouyer } 841 1.1 bouyer return ((int) symbols[i].value); 842 1.1 bouyer } 843 1.1 bouyer } 844 1.1 bouyer if (nsymbols >= MAXSYMBOLS) { 845 1.1 bouyer errout ("Symbol table full"); 846 1.1 bouyer return (0); 847 1.1 bouyer } 848 1.1 bouyer symbols[nsymbols].type = S_LABEL; /* assume forward reference */ 849 1.1 bouyer symbols[nsymbols].flags = 0; 850 1.1 bouyer symbols[nsymbols].value = 0; 851 1.1 bouyer p = (struct patchlist *) malloc (sizeof (struct patchlist)); 852 1.1 bouyer symbols[nsymbols].patchlist = p; 853 1.1 bouyer p->next = NULL; 854 1.1 bouyer p->offset = dsps + 4; 855 1.1 bouyer symbols[nsymbols].name = malloc (strlen (name) + 1); 856 1.1 bouyer strcpy (symbols[nsymbols].name, name); 857 1.1 bouyer ++nsymbols; 858 1.1 bouyer return (0); 859 1.1 bouyer } 860 1.1 bouyer 861 1.1 bouyer void f_arch (void) 862 1.1 bouyer { 863 1.1 bouyer int i, archsave; 864 1.1 bouyer 865 1.1 bouyer i = tokenix; 866 1.1 bouyer 867 1.1 bouyer archsave = arch; 868 1.1 bouyer setarch(tokens[i].name); 869 1.1 bouyer if( arch == 0) { 870 1.1 bouyer errout("Unrecognized ARCH"); 871 1.1 bouyer arch = archsave; 872 1.1 bouyer } 873 1.1 bouyer } 874 1.1 bouyer 875 1.1 bouyer void f_proc (void) 876 1.1 bouyer { 877 1.1 bouyer if (tokens[tokenix].type != 0 || tokens[tokenix + 1].type != ':') 878 1.1 bouyer errout ("Invalid PROC statement"); 879 1.1 bouyer else 880 1.1 bouyer new_script (tokens[tokenix].name); 881 1.1 bouyer } 882 1.1 bouyer 883 1.1 bouyer void f_pass (void) 884 1.1 bouyer { 885 1.1 bouyer errout ("PASS option not implemented"); 886 1.1 bouyer } 887 1.1 bouyer 888 1.1 bouyer /* 889 1.1 bouyer * f_list: process list of symbols for the ENTRY and EXTERNAL directive 890 1.1 bouyer */ 891 1.1 bouyer 892 1.1 bouyer void f_list (void) 893 1.1 bouyer { 894 1.1 bouyer int i; 895 1.1 bouyer short type; 896 1.1 bouyer short flags; 897 1.1 bouyer 898 1.1 bouyer type = strcmpi (tokens[tokenix-1].name, "ENTRY") ? S_EXTERNAL : S_LABEL; 899 1.1 bouyer flags = type == S_LABEL ? F_ENTRY : 0; 900 1.1 bouyer for (i = tokenix; i < ntokens; ++i) { 901 1.1 bouyer if (tokens[i].type != 0) { 902 1.1 bouyer errout ("Expected an identifier"); 903 1.1 bouyer return; 904 1.1 bouyer } 905 1.1 bouyer define_symbol (tokens[i].name, 0, type, flags); 906 1.1 bouyer if (i + 1 < ntokens) { 907 1.1 bouyer if (tokens[++i].type == ',') 908 1.1 bouyer continue; 909 1.1 bouyer errout ("Expected a separator"); 910 1.1 bouyer return; 911 1.1 bouyer } 912 1.1 bouyer } 913 1.1 bouyer } 914 1.1 bouyer 915 1.1 bouyer /* 916 1.1 bouyer * f_define: process list of definitions for ABSOLUTE and RELATIVE directive 917 1.1 bouyer */ 918 1.1 bouyer 919 1.1 bouyer void f_define (void) 920 1.1 bouyer { 921 1.1 bouyer int i; 922 1.1 bouyer char *name; 923 1.1 bouyer u_int32_t value; 924 1.1 bouyer int type; 925 1.1 bouyer 926 1.1 bouyer type = strcmpi (tokens[tokenix-1].name, "ABSOLUTE") ? S_RELATIVE : S_ABSOLUTE; 927 1.1 bouyer i = tokenix; 928 1.1 bouyer while (i < ntokens) { 929 1.1 bouyer if (tokens[i].type) { 930 1.1 bouyer errout ("Expected an identifier"); 931 1.1 bouyer return; 932 1.1 bouyer } 933 1.1 bouyer if (tokens[i + 1].type != '=') { 934 1.1 bouyer errout ("Expected a separator"); 935 1.1 bouyer return; 936 1.1 bouyer } 937 1.1 bouyer name = tokens[i].name; 938 1.1 bouyer i += 2; 939 1.1 bouyer value = expression (&i); 940 1.1 bouyer define_symbol (name, value, type, F_DEFINED); 941 1.1 bouyer } 942 1.1 bouyer } 943 1.1 bouyer 944 1.1 bouyer void store_inst () 945 1.1 bouyer { 946 1.1 bouyer int i = dsps / 4; 947 1.1 bouyer int l = 8; 948 1.1 bouyer 949 1.1 bouyer if ((inst0 & 0xe0000000) == 0xc0000000) 950 1.1 bouyer l = 12; /* Memory to memory move is 12 bytes */ 951 1.1 bouyer if ((dsps + l) / 4 > MAXINST) { 952 1.1 bouyer errout ("Instruction table overflow"); 953 1.1 bouyer return; 954 1.1 bouyer } 955 1.1 bouyer script[i++] = inst0; 956 1.1 bouyer script[i++] = inst1; 957 1.1 bouyer if (l == 12) 958 1.1 bouyer script[i++] = inst2; 959 1.1 bouyer if (listfp) { 960 1.1 bouyer fprintf (listfp, "\t%04x: %08x %08x", dsps, inst0, inst1); 961 1.1 bouyer if (l == 12) 962 1.1 bouyer fprintf (listfp, " %08x", inst2); 963 1.1 bouyer fprintf (listfp, "\n"); 964 1.1 bouyer } 965 1.1 bouyer dsps += l; 966 1.1 bouyer inst0 = inst1 = inst2 = 0; 967 1.1 bouyer ++ninsts; 968 1.1 bouyer } 969 1.1 bouyer 970 1.1 bouyer void f_move (void) 971 1.1 bouyer { 972 1.1 bouyer if (reserved ("memory", tokenix)) 973 1.1 bouyer memory_to_memory (); 974 1.1 bouyer else if (reserved ("from", tokenix) || tokens[tokenix+1].type == ',') 975 1.1 bouyer block_move (); 976 1.1 bouyer else 977 1.1 bouyer register_write (); 978 1.1 bouyer store_inst (); 979 1.1 bouyer } 980 1.1 bouyer 981 1.1 bouyer void f_jump (void) 982 1.1 bouyer { 983 1.1 bouyer transfer (0x80000000, 0); 984 1.1 bouyer } 985 1.1 bouyer 986 1.1 bouyer void f_call (void) 987 1.1 bouyer { 988 1.1 bouyer transfer (0x88000000, 0); 989 1.1 bouyer } 990 1.1 bouyer 991 1.1 bouyer void f_return (void) 992 1.1 bouyer { 993 1.1 bouyer transfer (0x90000000, 1); 994 1.1 bouyer } 995 1.1 bouyer 996 1.1 bouyer void f_int (void) 997 1.1 bouyer { 998 1.1 bouyer transfer (0x98000000, 2); 999 1.1 bouyer } 1000 1.1 bouyer 1001 1.10 bouyer void f_intfly (void) 1002 1.10 bouyer { 1003 1.10 bouyer transfer (0x98100000, 2); 1004 1.10 bouyer } 1005 1.10 bouyer 1006 1.1 bouyer void f_select (void) 1007 1.1 bouyer { 1008 1.1 bouyer int t = tokenix; 1009 1.1 bouyer 1010 1.1 bouyer if (reserved ("atn", t)) { 1011 1.1 bouyer inst0 = 0x01000000; 1012 1.1 bouyer ++t; 1013 1.1 bouyer } 1014 1.1 bouyer select_reselect (t); 1015 1.1 bouyer } 1016 1.1 bouyer 1017 1.1 bouyer void f_reselect (void) 1018 1.1 bouyer { 1019 1.1 bouyer select_reselect (tokenix); 1020 1.1 bouyer } 1021 1.1 bouyer 1022 1.1 bouyer void f_wait (void) 1023 1.1 bouyer { 1024 1.1 bouyer int i = tokenix; 1025 1.1 bouyer 1026 1.1 bouyer inst1 = 0; 1027 1.1 bouyer if (reserved ("disconnect", i)) { 1028 1.1 bouyer inst0 = 0x48000000; 1029 1.1 bouyer } 1030 1.1 bouyer else { 1031 1.1 bouyer if (reserved ("reselect", i)) 1032 1.1 bouyer inst0 = 0x50000000; 1033 1.1 bouyer else if (reserved ("select", i)) 1034 1.1 bouyer inst0 = 0x50000000; 1035 1.1 bouyer else 1036 1.1 bouyer errout ("Expected SELECT or RESELECT"); 1037 1.1 bouyer ++i; 1038 1.1 bouyer if (reserved ("rel", i)) { 1039 1.11 tsutsui #if 0 /* driver will fix relative dsps to absolute */ 1040 1.7 fredette if (arch < ARCH710) { 1041 1.7 fredette errout ("Wrong arch for relative dsps"); 1042 1.7 fredette } 1043 1.11 tsutsui #endif 1044 1.1 bouyer i += 2; 1045 1.1 bouyer inst1 = evaluate (i) - dsps - 8; 1046 1.1 bouyer inst0 |= 0x04000000; 1047 1.1 bouyer } 1048 1.7 fredette else { 1049 1.1 bouyer inst1 = evaluate (i); 1050 1.7 fredette patch_label(); 1051 1.7 fredette } 1052 1.1 bouyer } 1053 1.1 bouyer store_inst (); 1054 1.1 bouyer } 1055 1.1 bouyer 1056 1.1 bouyer void f_disconnect (void) 1057 1.1 bouyer { 1058 1.1 bouyer inst0 = 0x48000000; 1059 1.1 bouyer store_inst (); 1060 1.1 bouyer } 1061 1.1 bouyer 1062 1.1 bouyer void f_set (void) 1063 1.1 bouyer { 1064 1.1 bouyer set_clear (0x58000000); 1065 1.1 bouyer } 1066 1.1 bouyer 1067 1.1 bouyer void f_clear (void) 1068 1.1 bouyer { 1069 1.1 bouyer set_clear (0x60000000); 1070 1.1 bouyer } 1071 1.1 bouyer 1072 1.1 bouyer void f_load (void) 1073 1.1 bouyer { 1074 1.1 bouyer inst0 = 0xe1000000; 1075 1.1 bouyer if (arch < ARCH810) { 1076 1.1 bouyer errout ("Wrong arch for load/store"); 1077 1.1 bouyer return; 1078 1.1 bouyer } 1079 1.1 bouyer loadstore(tokenix); 1080 1.1 bouyer } 1081 1.1 bouyer 1082 1.1 bouyer void f_store (void) 1083 1.1 bouyer { 1084 1.1 bouyer int i; 1085 1.1 bouyer inst0 = 0xe0000000; 1086 1.1 bouyer if (arch < ARCH810) { 1087 1.1 bouyer errout ("Wrong arch for load/store"); 1088 1.1 bouyer return; 1089 1.1 bouyer } 1090 1.1 bouyer i = tokenix; 1091 1.1 bouyer if (reserved("noflush", i)) { 1092 1.1 bouyer inst0 |= 0x2000000; 1093 1.1 bouyer i++; 1094 1.1 bouyer } 1095 1.1 bouyer loadstore(i); 1096 1.1 bouyer } 1097 1.1 bouyer 1098 1.2 bouyer void f_nop (void) 1099 1.2 bouyer { 1100 1.8 bouyer inst0 = 0x80000000; 1101 1.2 bouyer inst1 = 0x00000000; 1102 1.2 bouyer store_inst (); 1103 1.2 bouyer } 1104 1.2 bouyer 1105 1.1 bouyer void loadstore(int i) 1106 1.1 bouyer { 1107 1.1 bouyer int reg, size; 1108 1.1 bouyer 1109 1.1 bouyer reg = CheckRegister(i); 1110 1.1 bouyer if (reg < 0) 1111 1.1 bouyer errout ("Expected register"); 1112 1.1 bouyer else 1113 1.1 bouyer inst0 |= reg << 16; 1114 1.1 bouyer if (reg == 8) 1115 1.1 bouyer errout ("Register can't be SFBR"); 1116 1.1 bouyer i++; 1117 1.1 bouyer if (tokens[i].type == ',') 1118 1.1 bouyer i++; 1119 1.1 bouyer else 1120 1.1 bouyer errout ("expected ','"); 1121 1.1 bouyer size = evaluate(i); 1122 1.1 bouyer if (i < 1 || i > 4) 1123 1.1 bouyer errout("wrong size"); 1124 1.1 bouyer if ((reg & 0x3) + size > 4) 1125 1.1 bouyer errout("size too big for register"); 1126 1.1 bouyer inst0 |= size; 1127 1.1 bouyer i++; 1128 1.1 bouyer if (tokens[i].type == ',') 1129 1.1 bouyer i++; 1130 1.1 bouyer else 1131 1.1 bouyer errout ("expected ','"); 1132 1.1 bouyer if (reserved("from", i) || reserved("dsarel", i)) { 1133 1.7 fredette if (arch < ARCH710) { 1134 1.7 fredette errout ("Wrong arch for table indirect"); 1135 1.7 fredette return; 1136 1.7 fredette } 1137 1.1 bouyer i++; 1138 1.1 bouyer inst0 |= 0x10000000; 1139 1.1 bouyer } 1140 1.1 bouyer inst1 = evaluate(i); 1141 1.1 bouyer store_inst (); 1142 1.1 bouyer } 1143 1.1 bouyer 1144 1.1 bouyer void transfer (int word0, int type) 1145 1.1 bouyer { 1146 1.1 bouyer int i; 1147 1.1 bouyer 1148 1.1 bouyer i = tokenix; 1149 1.1 bouyer inst0 = word0; 1150 1.1 bouyer if (type == 0 && reserved ("rel", i)) { 1151 1.11 tsutsui #if 0 /* driver will fix relative dsps to absolute */ 1152 1.7 fredette if (arch < ARCH710) { 1153 1.7 fredette errout ("Wrong arch for relative dsps"); 1154 1.7 fredette } 1155 1.11 tsutsui #endif 1156 1.1 bouyer inst1 = evaluate (i + 2) - dsps - 8; 1157 1.4 bouyer i += 4; 1158 1.1 bouyer inst0 |= 0x00800000; 1159 1.1 bouyer } 1160 1.1 bouyer else if (type != 1) { 1161 1.1 bouyer inst1 = evaluate (i); 1162 1.4 bouyer ++i; 1163 1.7 fredette if (type == 0) 1164 1.7 fredette patch_label(); 1165 1.1 bouyer } 1166 1.1 bouyer if (i >= ntokens) { 1167 1.1 bouyer inst0 |= 0x00080000; 1168 1.1 bouyer store_inst (); 1169 1.1 bouyer return; 1170 1.1 bouyer } 1171 1.1 bouyer if (tokens[i].type != ',') 1172 1.1 bouyer errout ("Expected a separator, ',' assumed"); 1173 1.1 bouyer else 1174 1.1 bouyer ++i; 1175 1.1 bouyer if (reserved("when", i)) 1176 1.1 bouyer inst0 |= 0x00010000; 1177 1.1 bouyer else if (reserved ("if", i) == 0) { 1178 1.1 bouyer errout ("Expected a reserved word"); 1179 1.1 bouyer store_inst (); 1180 1.1 bouyer return; 1181 1.1 bouyer } 1182 1.5 bouyer i++; 1183 1.5 bouyer if (reserved("false", i)) { 1184 1.5 bouyer store_inst (); 1185 1.5 bouyer return; 1186 1.5 bouyer } 1187 1.5 bouyer if (reserved ("not", i)) 1188 1.1 bouyer ++i; 1189 1.1 bouyer else 1190 1.1 bouyer inst0 |= 0x00080000; 1191 1.1 bouyer if (reserved ("atn", i)) { 1192 1.1 bouyer inst0 |= 0x00020000; 1193 1.1 bouyer ++i; 1194 1.1 bouyer } else if (CheckPhase (i)) { 1195 1.1 bouyer inst0 |= 0x00020000; 1196 1.1 bouyer ++i; 1197 1.1 bouyer } 1198 1.1 bouyer if (i < ntokens && tokens[i].type != ',') { 1199 1.1 bouyer if (inst0 & 0x00020000) { 1200 1.1 bouyer if (inst0 & 0x00080000 && reserved ("and", i)) { 1201 1.1 bouyer ++i; 1202 1.1 bouyer } 1203 1.1 bouyer else if ((inst0 & 0x00080000) == 0 && reserved ("or", i)) { 1204 1.1 bouyer ++i; 1205 1.1 bouyer } 1206 1.1 bouyer else 1207 1.1 bouyer errout ("Expected a reserved word"); 1208 1.1 bouyer } 1209 1.1 bouyer inst0 |= 0x00040000 + (evaluate (i++) & 0xff); 1210 1.1 bouyer } 1211 1.1 bouyer if (i < ntokens) { 1212 1.1 bouyer if (tokens[i].type == ',') 1213 1.1 bouyer ++i; 1214 1.1 bouyer else 1215 1.1 bouyer errout ("Expected a separator, ',' assumed"); 1216 1.1 bouyer if (reserved ("and", i) && reserved ("mask", i + 1)) 1217 1.1 bouyer inst0 |= ((evaluate (i + 2) & 0xff) << 8); 1218 1.1 bouyer else 1219 1.1 bouyer errout ("Expected , AND MASK"); 1220 1.1 bouyer } 1221 1.1 bouyer store_inst (); 1222 1.1 bouyer } 1223 1.1 bouyer 1224 1.1 bouyer void select_reselect (int t) 1225 1.1 bouyer { 1226 1.1 bouyer inst0 |= 0x40000000; /* ATN may be set from SELECT */ 1227 1.1 bouyer if (reserved ("from", t)) { 1228 1.7 fredette if (arch < ARCH710) { 1229 1.7 fredette errout ("Wrong arch for table indirect"); 1230 1.7 fredette return; 1231 1.7 fredette } 1232 1.1 bouyer ++t; 1233 1.1 bouyer inst0 |= 0x02000000 | evaluate (t++); 1234 1.1 bouyer } 1235 1.1 bouyer else 1236 1.1 bouyer inst0 |= (evaluate (t++) & 0xff) << 16; 1237 1.1 bouyer if (tokens[t++].type == ',') { 1238 1.1 bouyer if (reserved ("rel", t)) { 1239 1.11 tsutsui #if 0 /* driver will fix relative dsps to absolute */ 1240 1.7 fredette if (arch < ARCH710) { 1241 1.7 fredette errout ("Wrong arch for relative dsps"); 1242 1.7 fredette } 1243 1.11 tsutsui #endif 1244 1.1 bouyer inst0 |= 0x04000000; 1245 1.1 bouyer inst1 = evaluate (t + 2) - dsps - 8; 1246 1.1 bouyer } 1247 1.7 fredette else { 1248 1.1 bouyer inst1 = evaluate (t); 1249 1.7 fredette patch_label(); 1250 1.7 fredette } 1251 1.1 bouyer } 1252 1.1 bouyer else 1253 1.1 bouyer errout ("Expected separator"); 1254 1.1 bouyer store_inst (); 1255 1.1 bouyer } 1256 1.1 bouyer 1257 1.1 bouyer void set_clear (u_int32_t code) 1258 1.1 bouyer { 1259 1.1 bouyer int i = tokenix; 1260 1.1 bouyer short need_and = 0; 1261 1.1 bouyer 1262 1.1 bouyer inst0 = code; 1263 1.1 bouyer while (i < ntokens) { 1264 1.1 bouyer if (need_and) { 1265 1.1 bouyer if (reserved ("and", i)) 1266 1.1 bouyer ++i; 1267 1.1 bouyer else 1268 1.1 bouyer errout ("Expected AND"); 1269 1.1 bouyer } 1270 1.1 bouyer if (reserved ("atn", i)) { 1271 1.1 bouyer inst0 |= 0x0008; 1272 1.1 bouyer ++i; 1273 1.1 bouyer } 1274 1.1 bouyer else if (reserved ("ack", i)) { 1275 1.1 bouyer inst0 |= 0x0040; 1276 1.1 bouyer ++i; 1277 1.1 bouyer } 1278 1.1 bouyer else if (reserved ("target", i)) { 1279 1.1 bouyer inst0 |= 0x0200; 1280 1.1 bouyer ++i; 1281 1.1 bouyer } 1282 1.10 bouyer else if (reserved ("carry", i)) { 1283 1.10 bouyer inst0 |= 0x0400; 1284 1.10 bouyer ++i; 1285 1.10 bouyer } 1286 1.1 bouyer else 1287 1.10 bouyer errout ("Expected ATN, ACK, TARGET or CARRY"); 1288 1.1 bouyer need_and = 1; 1289 1.1 bouyer } 1290 1.1 bouyer store_inst (); 1291 1.1 bouyer } 1292 1.1 bouyer 1293 1.1 bouyer void block_move () 1294 1.1 bouyer { 1295 1.1 bouyer if (reserved ("from", tokenix)) { 1296 1.7 fredette if (arch < ARCH710) { 1297 1.7 fredette errout ("Wrong arch for table indirect"); 1298 1.7 fredette return; 1299 1.7 fredette } 1300 1.1 bouyer inst1 = evaluate (tokenix+1); 1301 1.1 bouyer inst0 |= 0x10000000 | inst1; /*** ??? to match Zeus script */ 1302 1.1 bouyer tokenix += 2; 1303 1.1 bouyer } 1304 1.1 bouyer else { 1305 1.1 bouyer inst0 |= evaluate (tokenix++); /* count */ 1306 1.1 bouyer tokenix++; /* skip ',' */ 1307 1.1 bouyer if (reserved ("ptr", tokenix)) { 1308 1.14 simonb ++tokenix; 1309 1.1 bouyer inst0 |= 0x20000000; 1310 1.1 bouyer } 1311 1.1 bouyer inst1 = evaluate (tokenix++); /* address */ 1312 1.1 bouyer } 1313 1.1 bouyer if (tokens[tokenix].type != ',') 1314 1.1 bouyer errout ("Expected separator"); 1315 1.1 bouyer if (reserved ("when", tokenix + 1)) { 1316 1.1 bouyer inst0 |= 0x08000000; 1317 1.1 bouyer CheckPhase (tokenix + 2); 1318 1.1 bouyer } 1319 1.1 bouyer else if (reserved ("with", tokenix + 1)) { 1320 1.1 bouyer CheckPhase (tokenix + 2); 1321 1.1 bouyer } 1322 1.1 bouyer else 1323 1.1 bouyer errout ("Expected WITH or WHEN"); 1324 1.1 bouyer } 1325 1.1 bouyer 1326 1.1 bouyer void register_write () 1327 1.1 bouyer { 1328 1.1 bouyer /* 1329 1.1 bouyer * MOVE reg/data8 TO reg register write 1330 1.1 bouyer * MOVE reg <op> data8 TO reg register write 1331 1.1 bouyer * MOVE reg + data8 TO reg WITH CARRY register write 1332 1.1 bouyer */ 1333 1.1 bouyer int op; 1334 1.1 bouyer int reg; 1335 1.1 bouyer int data; 1336 1.1 bouyer 1337 1.1 bouyer if (reserved ("to", tokenix+1)) 1338 1.1 bouyer op = 0; 1339 1.10 bouyer else if (reserved ("shl", tokenix+1)) 1340 1.10 bouyer op = 1; 1341 1.10 bouyer else if (reserved ("shr", tokenix+1)) 1342 1.10 bouyer op = 5; 1343 1.1 bouyer else if (tokens[tokenix+1].type == '|') 1344 1.1 bouyer op = 2; 1345 1.10 bouyer else if (reserved ("xor", tokenix+1)) 1346 1.10 bouyer op = 3; 1347 1.1 bouyer else if (tokens[tokenix+1].type == '&') 1348 1.1 bouyer op = 4; 1349 1.1 bouyer else if (tokens[tokenix+1].type == '+') 1350 1.1 bouyer op = 6; 1351 1.1 bouyer else if (tokens[tokenix+1].type == '-') 1352 1.1 bouyer op = 8; 1353 1.1 bouyer else 1354 1.1 bouyer errout ("Unknown register operator"); 1355 1.10 bouyer switch (op) { 1356 1.10 bouyer case 2: 1357 1.10 bouyer case 3: 1358 1.10 bouyer case 4: 1359 1.10 bouyer case 6: 1360 1.10 bouyer case 8: 1361 1.10 bouyer if (reserved ("to", tokenix+3) == 0) 1362 1.10 bouyer errout ("Register command expected TO"); 1363 1.10 bouyer } 1364 1.1 bouyer reg = CheckRegister (tokenix); 1365 1.1 bouyer if (reg < 0) { /* Not register, must be data */ 1366 1.1 bouyer data = evaluate (tokenix); 1367 1.1 bouyer if (op) 1368 1.1 bouyer errout ("Register operator not move"); 1369 1.1 bouyer reg = CheckRegister (tokenix+2); 1370 1.1 bouyer if (reg < 0) 1371 1.1 bouyer errout ("Expected register"); 1372 1.1 bouyer inst0 = 0x78000000 | (data << 8) | reg << 16; 1373 1.1 bouyer #if 0 1374 1.1 bouyer fprintf (listfp, "Move data to register: %02x %d\n", data, reg); 1375 1.1 bouyer #endif 1376 1.10 bouyer } else if (op) { 1377 1.10 bouyer switch (op) { 1378 1.10 bouyer case 2: 1379 1.10 bouyer case 3: 1380 1.10 bouyer case 4: 1381 1.10 bouyer case 6: 1382 1.10 bouyer case 8: 1383 1.10 bouyer inst0 = 0; 1384 1.10 bouyer /* A register read/write operator */ 1385 1.10 bouyer if (reserved("sfbr", tokenix+2)) { 1386 1.10 bouyer if (arch < ARCH825) 1387 1.10 bouyer errout("wrong arch for add with SFBR"); 1388 1.10 bouyer if (op == 8) 1389 1.17 andvar errout("can't subtract SFBR"); 1390 1.10 bouyer inst0 |= 0x00800000; 1391 1.10 bouyer data = 0; 1392 1.10 bouyer } else 1393 1.10 bouyer data = evaluate (tokenix+2); 1394 1.10 bouyer if (tokenix+5 < ntokens) { 1395 1.10 bouyer if (!reserved("with", tokenix+5) || 1396 1.10 bouyer !reserved("carry", tokenix+6)) { 1397 1.10 bouyer errout("Expected 'WITH CARRY'"); 1398 1.10 bouyer } else if (op != 6) { 1399 1.10 bouyer errout("'WITH CARRY' only valide " 1400 1.10 bouyer "with '+'"); 1401 1.10 bouyer } 1402 1.10 bouyer op = 7; 1403 1.10 bouyer } 1404 1.10 bouyer if (op == 8) { 1405 1.10 bouyer data = -data; 1406 1.10 bouyer op = 6; 1407 1.1 bouyer } 1408 1.10 bouyer inst0 |= (data & 0xff) << 8; 1409 1.10 bouyer data = CheckRegister (tokenix+4); 1410 1.10 bouyer break; 1411 1.10 bouyer default: 1412 1.10 bouyer data = CheckRegister (tokenix+2); 1413 1.10 bouyer break; 1414 1.1 bouyer } 1415 1.1 bouyer if (data < 0) 1416 1.1 bouyer errout ("Expected register"); 1417 1.1 bouyer if (reg != data && reg != 8 && data != 8) 1418 1.1 bouyer errout ("One register MUST be SBFR"); 1419 1.1 bouyer if (reg == data) { /* A register read/modify/write */ 1420 1.1 bouyer #if 0 1421 1.1 bouyer fprintf (listfp, "Read/modify register: %02x %d %d\n", inst0 >> 8, op, reg); 1422 1.1 bouyer #endif 1423 1.1 bouyer inst0 |= 0x78000000 | (op << 24) | (reg << 16); 1424 1.1 bouyer } 1425 1.1 bouyer else { /* A move to/from SFBR */ 1426 1.1 bouyer if (reg == 8) { /* MOVE SFBR <> TO reg */ 1427 1.1 bouyer #if 0 1428 1.1 bouyer fprintf (listfp, "Move SFBR to register: %02x %d %d\n", inst0 >> 8, op, data); 1429 1.1 bouyer #endif 1430 1.1 bouyer inst0 |= 0x68000000 | (op << 24) | (data << 16); 1431 1.1 bouyer } 1432 1.1 bouyer else { 1433 1.1 bouyer #if 0 1434 1.1 bouyer fprintf (listfp, "Move register to SFBR: %02x %d %d\n", inst0 >> 8, op, reg); 1435 1.1 bouyer #endif 1436 1.1 bouyer inst0 |= 0x70000000 | (op << 24) | (reg << 16); 1437 1.1 bouyer } 1438 1.1 bouyer } 1439 1.10 bouyer } else { /* register to register */ 1440 1.1 bouyer data = CheckRegister (tokenix+2); 1441 1.7 fredette if (data < 0) 1442 1.7 fredette errout ("Expected register"); 1443 1.1 bouyer if (reg == 8) /* move SFBR to reg */ 1444 1.1 bouyer inst0 = 0x6a000000 | (data << 16); 1445 1.1 bouyer else if (data == 8) /* move reg to SFBR */ 1446 1.1 bouyer inst0 = 0x72000000 | (reg << 16); 1447 1.1 bouyer else 1448 1.1 bouyer errout ("One register must be SFBR"); 1449 1.1 bouyer } 1450 1.1 bouyer } 1451 1.1 bouyer 1452 1.1 bouyer void memory_to_memory () 1453 1.1 bouyer { 1454 1.1 bouyer inst0 = 0xc0000000 + evaluate (tokenix+1); 1455 1.1 bouyer inst1 = evaluate (tokenix+3); 1456 1.2 bouyer /* 1457 1.2 bouyer * need to hack dsps, otherwise patch offset will be wrong for 1458 1.2 bouyer * second pointer 1459 1.2 bouyer */ 1460 1.2 bouyer dsps += 4; 1461 1.1 bouyer inst2 = evaluate (tokenix+5); 1462 1.2 bouyer dsps -= 4; 1463 1.1 bouyer } 1464 1.1 bouyer 1465 1.1 bouyer void error_line() 1466 1.1 bouyer { 1467 1.1 bouyer if (errfp != listfp && errfp && err_listed == 0) { 1468 1.1 bouyer fprintf (errfp, "%3d: %s", lineno, inbuf); 1469 1.1 bouyer err_listed = 1; 1470 1.1 bouyer } 1471 1.1 bouyer } 1472 1.1 bouyer 1473 1.1 bouyer char * makefn (base, sub) 1474 1.1 bouyer char *base; 1475 1.1 bouyer char *sub; 1476 1.1 bouyer { 1477 1.1 bouyer char *fn; 1478 1.1 bouyer 1479 1.1 bouyer fn = malloc (strlen (base) + strlen (sub) + 2); 1480 1.1 bouyer strcpy (fn, base); 1481 1.1 bouyer base = strrchr(fn, '.'); 1482 1.1 bouyer if (base) 1483 1.1 bouyer *base = 0; 1484 1.1 bouyer strcat (fn, "."); 1485 1.1 bouyer strcat (fn, sub); 1486 1.1 bouyer return (fn); 1487 1.1 bouyer } 1488 1.1 bouyer 1489 1.1 bouyer void usage() 1490 1.1 bouyer { 1491 1.1 bouyer fprintf (stderr, "usage: scc sourcfile [options]\n"); 1492 1.1 bouyer exit(1); 1493 1.1 bouyer } 1494