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