1 1.1 christos /* srcdest.c --- decoding M32C addressing modes. 2 1.1 christos 3 1.11 christos Copyright (C) 2005-2024 Free Software Foundation, Inc. 4 1.1 christos Contributed by Red Hat, Inc. 5 1.1 christos 6 1.1 christos This file is part of the GNU simulators. 7 1.1 christos 8 1.1 christos This program is free software; you can redistribute it and/or modify 9 1.1 christos it under the terms of the GNU General Public License as published by 10 1.1 christos the Free Software Foundation; either version 3 of the License, or 11 1.1 christos (at your option) any later version. 12 1.1 christos 13 1.1 christos This program is distributed in the hope that it will be useful, 14 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of 15 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 1.1 christos GNU General Public License for more details. 17 1.1 christos 18 1.1 christos You should have received a copy of the GNU General Public License 19 1.1 christos along with this program. If not, see <http://www.gnu.org/licenses/>. */ 20 1.1 christos 21 1.10 christos /* This must come before any other includes. */ 22 1.10 christos #include "defs.h" 23 1.1 christos 24 1.1 christos #include <stdio.h> 25 1.1 christos #include <stdlib.h> 26 1.1 christos 27 1.7 christos #include "libiberty.h" 28 1.1 christos #include "cpu.h" 29 1.1 christos #include "mem.h" 30 1.1 christos 31 1.1 christos static int src_indirect = 0; 32 1.1 christos static int dest_indirect = 0; 33 1.1 christos static int src_addend = 0; 34 1.1 christos static int dest_addend = 0; 35 1.1 christos 36 1.1 christos static int 37 1.5 christos disp8 (void) 38 1.1 christos { 39 1.1 christos int rv; 40 1.1 christos int tsave = trace; 41 1.1 christos 42 1.1 christos if (trace == 1) 43 1.1 christos trace = 0; 44 1.1 christos rv = mem_get_qi (get_reg (pc)); 45 1.1 christos regs.r_pc++; 46 1.1 christos trace = tsave; 47 1.1 christos return rv; 48 1.1 christos } 49 1.1 christos 50 1.1 christos static int 51 1.5 christos disp16 (void) 52 1.1 christos { 53 1.1 christos int rv; 54 1.1 christos int tsave = trace; 55 1.1 christos 56 1.1 christos if (trace == 1) 57 1.1 christos trace = 0; 58 1.1 christos rv = mem_get_hi (get_reg (pc)); 59 1.1 christos regs.r_pc += 2; 60 1.1 christos trace = tsave; 61 1.1 christos return rv; 62 1.1 christos } 63 1.1 christos 64 1.1 christos static int 65 1.5 christos disp24 (void) 66 1.1 christos { 67 1.1 christos int rv; 68 1.1 christos int tsave = trace; 69 1.1 christos 70 1.1 christos if (trace == 1) 71 1.1 christos trace = 0; 72 1.1 christos rv = mem_get_psi (get_reg (pc)); 73 1.1 christos regs.r_pc += 3; 74 1.1 christos trace = tsave; 75 1.1 christos return rv; 76 1.1 christos } 77 1.1 christos 78 1.1 christos static int 79 1.5 christos disp20 (void) 80 1.1 christos { 81 1.1 christos return disp24 () & 0x000fffff; 82 1.1 christos } 83 1.1 christos 84 1.1 christos const char * 85 1.1 christos bits (int v, int b) 86 1.1 christos { 87 1.1 christos static char buf[17]; 88 1.1 christos char *bp = buf + 16; 89 1.1 christos *bp = 0; 90 1.1 christos while (b) 91 1.1 christos { 92 1.1 christos *--bp = (v & 1) ? '1' : '0'; 93 1.1 christos v >>= 1; 94 1.1 christos b--; 95 1.1 christos } 96 1.1 christos return bp; 97 1.1 christos } 98 1.1 christos 99 1.1 christos static const char *the_bits = 0; 100 1.1 christos 101 1.1 christos void 102 1.1 christos decode_indirect (int si, int di) 103 1.1 christos { 104 1.1 christos src_indirect = si; 105 1.1 christos dest_indirect = di; 106 1.1 christos if (trace && (si || di)) 107 1.1 christos printf ("indirect: s:%d d:%d\n", si, di); 108 1.1 christos } 109 1.1 christos 110 1.1 christos void 111 1.1 christos decode_index (int sa, int da) 112 1.1 christos { 113 1.1 christos src_addend = sa; 114 1.1 christos dest_addend = da; 115 1.1 christos if (trace && (sa || da)) 116 1.1 christos printf ("index: s:%d d:%d\n", sa, da); 117 1.1 christos } 118 1.1 christos 119 1.1 christos srcdest 120 1.1 christos decode_srcdest4 (int destcode, int bw) 121 1.1 christos { 122 1.1 christos srcdest sd; 123 1.1 christos static const char *dc_wnames[16] = { "r0", "r1", "r2", "r3", 124 1.1 christos "a0", "a1", "[a0]", "[a1]", 125 1.1 christos "disp8[a0]", "disp8[a1]", "disp8[sb]", "disp8[fb]", 126 1.1 christos "disp16[a0]", "disp16[a1]", "disp16[sb]", "disp16" 127 1.1 christos }; 128 1.1 christos static const char *dc_bnames[4] = { "r0l", "r0h", "r1l", "r1h" };; 129 1.1 christos 130 1.5 christos sd.bytes = bw ? 2 : 1; 131 1.5 christos sd.mem = (destcode >= 6) ? 1 : 0; 132 1.5 christos 133 1.1 christos if (trace) 134 1.1 christos { 135 1.1 christos const char *n = dc_wnames[destcode]; 136 1.1 christos if (bw == 0 && destcode <= 3) 137 1.1 christos n = dc_bnames[destcode]; 138 1.1 christos if (!the_bits) 139 1.1 christos the_bits = bits (destcode, 4); 140 1.1 christos printf ("decode: %s (%d) : %s\n", the_bits, destcode, n); 141 1.1 christos the_bits = 0; 142 1.1 christos } 143 1.1 christos 144 1.1 christos switch (destcode) 145 1.1 christos { 146 1.1 christos case 0x0: 147 1.1 christos sd.u.reg = bw ? r0 : r0l; 148 1.1 christos break; 149 1.1 christos case 0x1: 150 1.1 christos sd.u.reg = bw ? r1 : r0h; 151 1.1 christos break; 152 1.1 christos case 0x2: 153 1.1 christos sd.u.reg = bw ? r2 : r1l; 154 1.1 christos break; 155 1.1 christos case 0x3: 156 1.1 christos sd.u.reg = bw ? r3 : r1h; 157 1.1 christos break; 158 1.1 christos case 0x4: 159 1.1 christos sd.u.reg = a0; 160 1.1 christos break; 161 1.1 christos case 0x5: 162 1.1 christos sd.u.reg = a1; 163 1.1 christos break; 164 1.1 christos case 0x6: 165 1.1 christos sd.u.addr = get_reg (a0); 166 1.1 christos break; 167 1.1 christos case 0x7: 168 1.1 christos sd.u.addr = get_reg (a1); 169 1.1 christos break; 170 1.1 christos case 0x8: 171 1.1 christos sd.u.addr = get_reg (a0) + disp8 (); 172 1.1 christos break; 173 1.1 christos case 0x9: 174 1.1 christos sd.u.addr = get_reg (a1) + disp8 (); 175 1.1 christos break; 176 1.1 christos case 0xa: 177 1.1 christos sd.u.addr = get_reg (sb) + disp8 (); 178 1.1 christos break; 179 1.1 christos case 0xb: 180 1.1 christos sd.u.addr = get_reg (fb) + sign_ext (disp8 (), 8); 181 1.1 christos break; 182 1.1 christos case 0xc: 183 1.1 christos sd.u.addr = get_reg (a0) + disp16 (); 184 1.1 christos break; 185 1.1 christos case 0xd: 186 1.1 christos sd.u.addr = get_reg (a1) + disp16 (); 187 1.1 christos break; 188 1.1 christos case 0xe: 189 1.1 christos sd.u.addr = get_reg (sb) + disp16 (); 190 1.1 christos break; 191 1.1 christos case 0xf: 192 1.1 christos sd.u.addr = disp16 (); 193 1.1 christos break; 194 1.1 christos default: 195 1.1 christos abort (); 196 1.1 christos } 197 1.1 christos if (sd.mem) 198 1.1 christos sd.u.addr &= addr_mask; 199 1.1 christos return sd; 200 1.1 christos } 201 1.1 christos 202 1.1 christos srcdest 203 1.1 christos decode_jumpdest (int destcode, int w) 204 1.1 christos { 205 1.1 christos srcdest sd; 206 1.1 christos static const char *dc_wnames[16] = { "r0", "r1", "r2", "r3", 207 1.1 christos "a0", "a1", "[a0]", "[a1]", 208 1.1 christos "disp8[a0]", "disp8[a1]", "disp8[sb]", "disp8[fb]", 209 1.1 christos "disp20[a0]", "disp20[a1]", "disp16[sb]", "abs16" 210 1.1 christos }; 211 1.1 christos static const char *dc_anames[4] = { "r0l", "r0h", "r1l", "r1h" }; 212 1.1 christos 213 1.5 christos sd.bytes = w ? 2 : 3; 214 1.5 christos sd.mem = (destcode >= 6) ? 1 : 0; 215 1.5 christos 216 1.1 christos if (trace) 217 1.1 christos { 218 1.1 christos const char *n = dc_wnames[destcode]; 219 1.1 christos if (w == 0 && destcode <= 3) 220 1.1 christos n = dc_anames[destcode]; 221 1.1 christos if (!the_bits) 222 1.1 christos the_bits = bits (destcode, 4); 223 1.1 christos printf ("decode: %s : %s\n", the_bits, n); 224 1.1 christos the_bits = 0; 225 1.1 christos } 226 1.1 christos 227 1.1 christos switch (destcode) 228 1.1 christos { 229 1.1 christos case 0x0: 230 1.1 christos sd.u.reg = w ? r0 : r2r0; 231 1.1 christos break; 232 1.1 christos case 0x1: 233 1.1 christos sd.u.reg = w ? r1 : r2r0; 234 1.1 christos break; 235 1.1 christos case 0x2: 236 1.1 christos sd.u.reg = w ? r2 : r3r1; 237 1.1 christos break; 238 1.1 christos case 0x3: 239 1.1 christos sd.u.reg = w ? r3 : r3r1; 240 1.1 christos break; 241 1.1 christos case 0x4: 242 1.1 christos sd.u.reg = w ? a0 : a1a0; 243 1.1 christos break; 244 1.1 christos case 0x5: 245 1.1 christos sd.u.reg = w ? a1 : a1a0; 246 1.1 christos break; 247 1.1 christos case 0x6: 248 1.1 christos sd.u.addr = get_reg (a0); 249 1.1 christos break; 250 1.1 christos case 0x7: 251 1.1 christos sd.u.addr = get_reg (a1); 252 1.1 christos break; 253 1.1 christos case 0x8: 254 1.1 christos sd.u.addr = get_reg (a0) + disp8 (); 255 1.1 christos break; 256 1.1 christos case 0x9: 257 1.1 christos sd.u.addr = get_reg (a1) + disp8 (); 258 1.1 christos break; 259 1.1 christos case 0xa: 260 1.1 christos sd.u.addr = get_reg (sb) + disp8 (); 261 1.1 christos break; 262 1.1 christos case 0xb: 263 1.1 christos sd.u.addr = get_reg (fb) + sign_ext (disp8 (), 8); 264 1.1 christos break; 265 1.1 christos case 0xc: 266 1.1 christos sd.u.addr = get_reg (a0) + disp20 (); 267 1.1 christos break; 268 1.1 christos case 0xd: 269 1.1 christos sd.u.addr = get_reg (a1) + disp20 (); 270 1.1 christos break; 271 1.1 christos case 0xe: 272 1.1 christos sd.u.addr = get_reg (sb) + disp16 (); 273 1.1 christos break; 274 1.1 christos case 0xf: 275 1.1 christos sd.u.addr = disp16 (); 276 1.1 christos break; 277 1.1 christos default: 278 1.1 christos abort (); 279 1.1 christos } 280 1.1 christos if (sd.mem) 281 1.1 christos sd.u.addr &= addr_mask; 282 1.1 christos return sd; 283 1.1 christos } 284 1.1 christos 285 1.1 christos srcdest 286 1.1 christos decode_dest3 (int destcode, int bw) 287 1.1 christos { 288 1.1 christos static char map[8] = { -1, -1, -1, 1, 0, 10, 11, 15 }; 289 1.1 christos 290 1.1 christos the_bits = bits (destcode, 3); 291 1.1 christos return decode_srcdest4 (map[destcode], bw); 292 1.1 christos } 293 1.1 christos 294 1.1 christos srcdest 295 1.1 christos decode_src2 (int srccode, int bw, int d) 296 1.1 christos { 297 1.1 christos static char map[4] = { 0, 10, 11, 15 }; 298 1.1 christos 299 1.1 christos the_bits = bits (srccode, 2); 300 1.1 christos return decode_srcdest4 (srccode ? map[srccode] : 1 - d, bw); 301 1.1 christos } 302 1.1 christos 303 1.1 christos static struct 304 1.1 christos { 305 1.1 christos reg_id b_regno; 306 1.1 christos reg_id w_regno; 307 1.1 christos int is_memory; 308 1.1 christos int disp_bytes; 309 1.1 christos char *name; 310 1.1 christos } modes23[] = 311 1.1 christos { 312 1.1 christos { 313 1.1 christos a0, a0, 1, 0, "[A0]"}, /* 0 0 0 0 0 */ 314 1.1 christos { 315 1.1 christos a1, a1, 1, 0, "[A1]"}, /* 0 0 0 0 1 */ 316 1.1 christos { 317 1.1 christos a0, a0, 0, 0, "A0"}, /* 0 0 0 1 0 */ 318 1.1 christos { 319 1.1 christos a1, a1, 0, 0, "A1"}, /* 0 0 0 1 1 */ 320 1.1 christos { 321 1.1 christos a0, a0, 1, 1, "dsp:8[A0]"}, /* 0 0 1 0 0 */ 322 1.1 christos { 323 1.1 christos a1, a1, 1, 1, "dsp:8[A1]"}, /* 0 0 1 0 1 */ 324 1.1 christos { 325 1.1 christos sb, sb, 1, 1, "dsp:8[SB]"}, /* 0 0 1 1 0 */ 326 1.1 christos { 327 1.1 christos fb, fb, 1, -1, "dsp:8[FB]"}, /* 0 0 1 1 1 */ 328 1.1 christos { 329 1.1 christos a0, a0, 1, 2, "dsp:16[A0]"}, /* 0 1 0 0 0 */ 330 1.1 christos { 331 1.1 christos a1, a1, 1, 2, "dsp:16[A1]"}, /* 0 1 0 0 1 */ 332 1.1 christos { 333 1.1 christos sb, sb, 1, 2, "dsp:16[SB]"}, /* 0 1 0 1 0 */ 334 1.1 christos { 335 1.1 christos fb, fb, 1, -2, "dsp:16[FB]"}, /* 0 1 0 1 1 */ 336 1.1 christos { 337 1.1 christos a0, a0, 1, 3, "dsp:24[A0]"}, /* 0 1 1 0 0 */ 338 1.1 christos { 339 1.1 christos a1, a1, 1, 3, "dsp:24[A1]"}, /* 0 1 1 0 1 */ 340 1.1 christos { 341 1.1 christos mem, mem, 1, 3, "abs24"}, /* 0 1 1 1 0 */ 342 1.1 christos { 343 1.1 christos mem, mem, 1, 2, "abs16"}, /* 0 1 1 1 1 */ 344 1.1 christos { 345 1.1 christos r0h, r2, 0, 0, "R0H/R2"}, /* 1 0 0 0 0 */ 346 1.1 christos { 347 1.1 christos r1h, r3, 0, 0, "R1H/R3"}, /* 1 0 0 0 1 */ 348 1.1 christos { 349 1.1 christos r0l, r0, 0, 0, "R0L/R0"}, /* 1 0 0 1 0 */ 350 1.1 christos { 351 1.1 christos r1l, r1, 0, 0, "R1L/R1"}, /* 1 0 0 1 1 */ 352 1.1 christos }; 353 1.1 christos 354 1.1 christos static srcdest 355 1.1 christos decode_sd23 (int bbb, int bb, int bytes, int ind, int add) 356 1.1 christos { 357 1.1 christos srcdest sd; 358 1.1 christos int code = (bbb << 2) | bb; 359 1.1 christos 360 1.7 christos if (code >= ARRAY_SIZE (modes23)) 361 1.1 christos abort (); 362 1.1 christos 363 1.1 christos if (trace) 364 1.1 christos { 365 1.1 christos char *b1 = ""; 366 1.1 christos char *b2 = ""; 367 1.1 christos char ad[30]; 368 1.1 christos if (ind) 369 1.1 christos { 370 1.1 christos b1 = "["; 371 1.1 christos b2 = "]"; 372 1.1 christos } 373 1.1 christos if (add) 374 1.1 christos sprintf (ad, "%+d", add); 375 1.1 christos else 376 1.1 christos ad[0] = 0; 377 1.1 christos if (!the_bits) 378 1.1 christos the_bits = bits (code, 4); 379 1.1 christos printf ("decode: %s (%d) : %s%s%s%s\n", the_bits, code, b1, 380 1.1 christos modes23[code].name, ad, b2); 381 1.1 christos the_bits = 0; 382 1.1 christos } 383 1.1 christos 384 1.1 christos sd.bytes = bytes; 385 1.1 christos sd.mem = modes23[code].is_memory; 386 1.1 christos if (sd.mem) 387 1.1 christos { 388 1.1 christos if (modes23[code].w_regno == mem) 389 1.1 christos sd.u.addr = 0; 390 1.1 christos else 391 1.1 christos sd.u.addr = get_reg (modes23[code].w_regno); 392 1.1 christos switch (modes23[code].disp_bytes) 393 1.1 christos { 394 1.1 christos case 1: 395 1.1 christos sd.u.addr += disp8 (); 396 1.1 christos break; 397 1.1 christos case 2: 398 1.1 christos sd.u.addr += disp16 (); 399 1.1 christos break; 400 1.1 christos case -1: 401 1.1 christos sd.u.addr += sign_ext (disp8 (), 8); 402 1.1 christos break; 403 1.1 christos case -2: 404 1.1 christos sd.u.addr += sign_ext (disp16 (), 16); 405 1.1 christos break; 406 1.1 christos case 3: 407 1.1 christos sd.u.addr += disp24 (); 408 1.1 christos break; 409 1.1 christos default: 410 1.1 christos break; 411 1.1 christos } 412 1.1 christos if (add) 413 1.1 christos sd.u.addr += add; 414 1.1 christos if (ind) 415 1.1 christos sd.u.addr = mem_get_si (sd.u.addr & membus_mask); 416 1.1 christos sd.u.addr &= membus_mask; 417 1.1 christos } 418 1.1 christos else 419 1.1 christos { 420 1.1 christos sd.u.reg = (bytes > 1) ? modes23[code].w_regno : modes23[code].b_regno; 421 1.1 christos if (bytes == 3 || bytes == 4) 422 1.1 christos { 423 1.1 christos switch (sd.u.reg) 424 1.1 christos { 425 1.1 christos case r0: 426 1.1 christos sd.u.reg = r2r0; 427 1.1 christos break; 428 1.1 christos case r1: 429 1.1 christos sd.u.reg = r3r1; 430 1.1 christos break; 431 1.1 christos case r2: 432 1.1 christos abort (); 433 1.1 christos case r3: 434 1.1 christos abort (); 435 1.1 christos default:; 436 1.1 christos } 437 1.1 christos } 438 1.1 christos 439 1.1 christos } 440 1.1 christos return sd; 441 1.1 christos } 442 1.1 christos 443 1.1 christos srcdest 444 1.1 christos decode_dest23 (int ddd, int dd, int bytes) 445 1.1 christos { 446 1.1 christos return decode_sd23 (ddd, dd, bytes, dest_indirect, dest_addend); 447 1.1 christos } 448 1.1 christos 449 1.1 christos srcdest 450 1.1 christos decode_src23 (int sss, int ss, int bytes) 451 1.1 christos { 452 1.1 christos return decode_sd23 (sss, ss, bytes, src_indirect, src_addend); 453 1.1 christos } 454 1.1 christos 455 1.1 christos srcdest 456 1.1 christos decode_dest2 (int dd, int bytes) 457 1.1 christos { 458 1.1 christos /* r0l/r0, abs16, dsp:8[SB], dsp:8[FB] */ 459 1.1 christos static char map[4] = { 0x12, 0x0f, 0x06, 0x07 }; 460 1.1 christos 461 1.1 christos the_bits = bits (dd, 2); 462 1.1 christos return decode_sd23 (map[dd] >> 2, map[dd] & 3, bytes, dest_indirect, 463 1.1 christos dest_addend); 464 1.1 christos } 465 1.1 christos 466 1.1 christos srcdest 467 1.1 christos decode_src3 (int sss, int bytes) 468 1.1 christos { 469 1.1 christos /* r0, r1, a0, a1, r2, r3, N/A, N/A */ 470 1.1 christos static char map[8] = { 0x12, 0x13, 0x02, 0x03, 0x10, 0x11, 0, 0 }; 471 1.1 christos 472 1.1 christos the_bits = bits (sss, 3); 473 1.1 christos return decode_sd23 (map[sss] >> 2, map[sss] & 3, bytes, src_indirect, 474 1.1 christos src_addend); 475 1.1 christos } 476 1.1 christos 477 1.1 christos srcdest 478 1.1 christos decode_dest1 (int destcode, int bw) 479 1.1 christos { 480 1.1 christos the_bits = bits (destcode, 1); 481 1.1 christos return decode_srcdest4 (destcode, bw); 482 1.1 christos } 483 1.1 christos 484 1.1 christos srcdest 485 1.1 christos decode_cr (int crcode) 486 1.1 christos { 487 1.1 christos static int regcode[] = { 0, intbl, intbh, flags, isp, sp, sb, fb }; 488 1.1 christos srcdest sd; 489 1.1 christos sd.mem = 0; 490 1.1 christos sd.bytes = 2; 491 1.1 christos sd.u.reg = regcode[crcode & 7]; 492 1.1 christos return sd; 493 1.1 christos } 494 1.1 christos 495 1.1 christos srcdest 496 1.1 christos decode_cr_b (int crcode, int bank) 497 1.1 christos { 498 1.1 christos /* FIXME: intbl, intbh, isp */ 499 1.1 christos static int regcode[3][8] = { 500 1.1 christos {0, 0, flags, 0, 0, 0, 0, 0}, 501 1.1 christos {intb, sp, sb, fb, 0, 0, 0, isp}, 502 1.1 christos {0, 0, 0, 0, 0, 0, 0, 0} 503 1.1 christos }; 504 1.1 christos srcdest sd; 505 1.1 christos sd.mem = 0; 506 1.1 christos sd.bytes = bank ? 3 : 2; 507 1.1 christos sd.u.reg = regcode[bank][crcode & 7]; 508 1.1 christos return sd; 509 1.1 christos } 510 1.1 christos 511 1.1 christos srcdest 512 1.1 christos widen_sd (srcdest sd) 513 1.1 christos { 514 1.1 christos sd.bytes *= 2; 515 1.1 christos if (!sd.mem) 516 1.1 christos switch (sd.u.reg) 517 1.1 christos { 518 1.1 christos case r0l: 519 1.1 christos sd.u.reg = r0; 520 1.1 christos break; 521 1.1 christos case r0: 522 1.1 christos sd.u.reg = r2r0; 523 1.1 christos break; 524 1.1 christos case r1l: 525 1.1 christos sd.u.reg = r1; 526 1.1 christos break; 527 1.1 christos case r1: 528 1.1 christos sd.u.reg = r3r1; 529 1.1 christos break; 530 1.1 christos case a0: 531 1.1 christos if (A16) 532 1.1 christos sd.u.reg = a1a0; 533 1.1 christos break; 534 1.1 christos default: 535 1.1 christos break; 536 1.1 christos } 537 1.1 christos return sd; 538 1.1 christos } 539 1.1 christos 540 1.1 christos srcdest 541 1.1 christos reg_sd (reg_id reg) 542 1.1 christos { 543 1.1 christos srcdest rv; 544 1.1 christos rv.bytes = reg_bytes[reg]; 545 1.1 christos rv.mem = 0; 546 1.1 christos rv.u.reg = reg; 547 1.1 christos return rv; 548 1.1 christos } 549 1.1 christos 550 1.1 christos int 551 1.1 christos get_src (srcdest sd) 552 1.1 christos { 553 1.1 christos int v; 554 1.1 christos if (sd.mem) 555 1.1 christos { 556 1.1 christos switch (sd.bytes) 557 1.1 christos { 558 1.1 christos case 1: 559 1.1 christos v = mem_get_qi (sd.u.addr); 560 1.1 christos break; 561 1.1 christos case 2: 562 1.1 christos v = mem_get_hi (sd.u.addr); 563 1.1 christos break; 564 1.1 christos case 3: 565 1.1 christos v = mem_get_psi (sd.u.addr); 566 1.1 christos break; 567 1.1 christos case 4: 568 1.1 christos v = mem_get_si (sd.u.addr); 569 1.1 christos break; 570 1.1 christos default: 571 1.1 christos abort (); 572 1.1 christos } 573 1.1 christos } 574 1.1 christos else 575 1.1 christos { 576 1.1 christos v = get_reg (sd.u.reg); 577 1.1 christos switch (sd.bytes) 578 1.1 christos { 579 1.1 christos case 1: 580 1.1 christos v &= 0xff; 581 1.1 christos break; 582 1.1 christos case 2: 583 1.1 christos v &= 0xffff; 584 1.1 christos break; 585 1.1 christos case 3: 586 1.1 christos v &= 0xffffff; 587 1.1 christos break; 588 1.1 christos } 589 1.1 christos } 590 1.1 christos return v; 591 1.1 christos } 592 1.1 christos 593 1.1 christos void 594 1.1 christos put_dest (srcdest sd, int v) 595 1.1 christos { 596 1.1 christos if (sd.mem) 597 1.1 christos { 598 1.1 christos switch (sd.bytes) 599 1.1 christos { 600 1.1 christos case 1: 601 1.1 christos mem_put_qi (sd.u.addr, v); 602 1.1 christos break; 603 1.1 christos case 2: 604 1.1 christos mem_put_hi (sd.u.addr, v); 605 1.1 christos break; 606 1.1 christos case 3: 607 1.1 christos mem_put_psi (sd.u.addr, v); 608 1.1 christos break; 609 1.1 christos case 4: 610 1.1 christos mem_put_si (sd.u.addr, v); 611 1.1 christos break; 612 1.1 christos } 613 1.1 christos } 614 1.1 christos else 615 1.1 christos { 616 1.1 christos switch (sd.bytes) 617 1.1 christos { 618 1.1 christos case 1: 619 1.1 christos v &= 0xff; 620 1.1 christos break; 621 1.1 christos case 2: 622 1.1 christos v &= 0xffff; 623 1.1 christos break; 624 1.1 christos case 3: 625 1.1 christos v &= 0xffffff; 626 1.1 christos break; 627 1.1 christos } 628 1.1 christos put_reg (sd.u.reg, v); 629 1.1 christos } 630 1.1 christos } 631 1.1 christos 632 1.1 christos srcdest 633 1.1 christos decode_bit (int destcode) 634 1.1 christos { 635 1.1 christos srcdest sd; 636 1.1 christos int addr = 0; 637 1.1 christos static const char *dc_names[] = { "r0", "r1", "r2", "r3", 638 1.1 christos "a0", "a1", "[a0]", "[a1]", 639 1.1 christos "disp8[a0]", "disp8[a1]", "disp8[sb]", "disp8[fb]", 640 1.1 christos "disp16[a0]", "disp16[a1]", "disp16[sb]", "abs16" 641 1.1 christos }; 642 1.1 christos 643 1.1 christos if (trace) 644 1.1 christos { 645 1.1 christos const char *the_bits = bits (destcode, 4); 646 1.1 christos printf ("decode: %s : %s\n", the_bits, dc_names[destcode]); 647 1.1 christos } 648 1.1 christos 649 1.1 christos switch (destcode) 650 1.1 christos { 651 1.1 christos case 0: 652 1.1 christos sd.u.reg = r0; 653 1.1 christos break; 654 1.1 christos case 1: 655 1.1 christos sd.u.reg = r1; 656 1.1 christos break; 657 1.1 christos case 2: 658 1.1 christos sd.u.reg = r2; 659 1.1 christos break; 660 1.1 christos case 3: 661 1.1 christos sd.u.reg = r3; 662 1.1 christos break; 663 1.1 christos case 4: 664 1.1 christos sd.u.reg = a0; 665 1.1 christos break; 666 1.1 christos case 5: 667 1.1 christos sd.u.reg = a1; 668 1.1 christos break; 669 1.1 christos case 6: 670 1.1 christos addr = get_reg (a0); 671 1.1 christos break; 672 1.1 christos case 7: 673 1.1 christos addr = get_reg (a1); 674 1.1 christos break; 675 1.1 christos case 8: 676 1.1 christos addr = get_reg (a0) + disp8 (); 677 1.1 christos break; 678 1.1 christos case 9: 679 1.1 christos addr = get_reg (a1) + disp8 (); 680 1.1 christos break; 681 1.1 christos case 10: 682 1.1 christos addr = get_reg (sb) * 8 + disp8 (); 683 1.1 christos break; 684 1.1 christos case 11: 685 1.1 christos addr = get_reg (fb) * 8 + sign_ext (disp8 (), 8); 686 1.1 christos break; 687 1.1 christos case 12: 688 1.1 christos addr = get_reg (a0) + disp16 (); 689 1.1 christos break; 690 1.1 christos case 13: 691 1.1 christos addr = get_reg (a1) + disp16 (); 692 1.1 christos break; 693 1.1 christos case 14: 694 1.1 christos addr = get_reg (sb) + disp16 (); 695 1.1 christos break; 696 1.1 christos case 15: 697 1.1 christos addr = disp16 (); 698 1.1 christos break; 699 1.1 christos } 700 1.1 christos 701 1.1 christos if (destcode < 6) 702 1.1 christos { 703 1.1 christos int d = disp8 (); 704 1.1 christos sd.mem = 0; 705 1.1 christos sd.mask = 1 << (d & 0x0f); 706 1.1 christos } 707 1.1 christos else 708 1.1 christos { 709 1.1 christos addr &= addr_mask; 710 1.1 christos sd.mem = 1; 711 1.1 christos sd.mask = 1 << (addr & 7); 712 1.1 christos sd.u.addr = addr >> 3; 713 1.1 christos } 714 1.1 christos return sd; 715 1.1 christos } 716 1.1 christos 717 1.1 christos srcdest 718 1.1 christos decode_bit11 (int op0) 719 1.1 christos { 720 1.1 christos srcdest sd; 721 1.1 christos sd.mask = 1 << (op0 & 7); 722 1.1 christos sd.mem = 1; 723 1.1 christos sd.u.addr = get_reg (sb) + disp8 (); 724 1.1 christos return sd; 725 1.1 christos } 726 1.1 christos 727 1.1 christos int 728 1.1 christos get_bit (srcdest sd) 729 1.1 christos { 730 1.1 christos int b; 731 1.1 christos if (sd.mem) 732 1.1 christos b = mem_get_qi (sd.u.addr) & sd.mask; 733 1.1 christos else 734 1.1 christos b = get_reg (sd.u.reg) & sd.mask; 735 1.1 christos return b ? 1 : 0; 736 1.1 christos } 737 1.1 christos 738 1.1 christos void 739 1.1 christos put_bit (srcdest sd, int val) 740 1.1 christos { 741 1.1 christos int b; 742 1.1 christos if (sd.mem) 743 1.1 christos b = mem_get_qi (sd.u.addr); 744 1.1 christos else 745 1.1 christos b = get_reg (sd.u.reg); 746 1.1 christos if (val) 747 1.1 christos b |= sd.mask; 748 1.1 christos else 749 1.1 christos b &= ~sd.mask; 750 1.1 christos if (sd.mem) 751 1.1 christos mem_put_qi (sd.u.addr, b); 752 1.1 christos else 753 1.1 christos put_reg (sd.u.reg, b); 754 1.1 christos } 755 1.1 christos 756 1.1 christos int 757 1.1 christos get_bit2 (srcdest sd, int bit) 758 1.1 christos { 759 1.1 christos int b; 760 1.1 christos if (sd.mem) 761 1.1 christos b = mem_get_qi (sd.u.addr + (bit >> 3)) & (1 << (bit & 7)); 762 1.1 christos else 763 1.1 christos b = get_reg (sd.u.reg) & (1 << bit); 764 1.1 christos return b ? 1 : 0; 765 1.1 christos } 766 1.1 christos 767 1.1 christos void 768 1.1 christos put_bit2 (srcdest sd, int bit, int val) 769 1.1 christos { 770 1.1 christos int b; 771 1.1 christos if (sd.mem) 772 1.1 christos b = mem_get_qi (sd.u.addr + (bit >> 3)); 773 1.1 christos else 774 1.1 christos b = get_reg (sd.u.reg); 775 1.1 christos if (val) 776 1.1 christos b |= (1 << (bit & 7)); 777 1.1 christos else 778 1.1 christos b &= ~(1 << (bit & 7)); 779 1.1 christos if (sd.mem) 780 1.1 christos mem_put_qi (sd.u.addr + (bit >> 3), b); 781 1.1 christos else 782 1.1 christos put_reg (sd.u.reg, b); 783 1.1 christos } 784