1 1.1 christos /* Simulation code for the CR16 processor. 2 1.1 christos Copyright (C) 2008-2024 Free Software Foundation, Inc. 3 1.1 christos Contributed by M Ranga Swami Reddy <MR.Swami.Reddy (at) nsc.com> 4 1.1 christos 5 1.1 christos This file is part of GDB, the GNU debugger. 6 1.1 christos 7 1.1 christos This program is free software; you can redistribute it and/or modify 8 1.1 christos it under the terms of the GNU General Public License as published by 9 1.1 christos the Free Software Foundation; either version 3, or (at your option) 10 1.1 christos any later version. 11 1.1 christos 12 1.1 christos This program is distributed in the hope that it will be useful, 13 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of 14 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 1.1 christos GNU General Public License for more details. 16 1.1 christos 17 1.1 christos You should have received a copy of the GNU General Public License 18 1.1 christos along with this program. If not, see <http://www.gnu.org/licenses/>. */ 19 1.1 christos 20 1.1 christos 21 1.1 christos #include <stdio.h> 22 1.1 christos #include <ctype.h> 23 1.1 christos #include <limits.h> 24 1.1 christos #include "ansidecl.h" 25 1.1 christos #include "sim/callback.h" 26 1.1 christos #include "opcode/cr16.h" 27 1.1 christos #include "bfd.h" 28 1.1 christos #include "sim-main.h" 29 1.1 christos 30 1.1 christos #define DEBUG_TRACE 0x00000001 31 1.1 christos #define DEBUG_VALUES 0x00000002 32 1.1 christos #define DEBUG_LINE_NUMBER 0x00000004 33 1.1 christos #define DEBUG_MEMSIZE 0x00000008 34 1.1 christos #define DEBUG_INSTRUCTION 0x00000010 35 1.1 christos #define DEBUG_TRAP 0x00000020 36 1.1 christos #define DEBUG_MEMORY 0x00000040 37 1.1 christos 38 1.1 christos #ifndef DEBUG 39 1.1 christos #define DEBUG (DEBUG_TRACE | DEBUG_VALUES | DEBUG_LINE_NUMBER) 40 1.1 christos #endif 41 1.1 christos 42 1.1 christos extern int cr16_debug; 43 1.1 christos 44 1.1 christos #include "sim/sim.h" 45 1.1 christos #include "sim-config.h" 46 1.1 christos #include "sim-types.h" 47 1.1 christos 48 1.1 christos /* FIXME: CR16 defines */ 49 1.1 christos typedef uint16_t reg_t; 50 1.1 christos typedef uint32_t creg_t; 51 1.1 christos 52 1.1 christos struct simops 53 1.1 christos { 54 1.1 christos char mnemonic[12]; 55 1.1 christos uint32_t size; 56 1.1 christos uint32_t mask; 57 1.1 christos uint32_t opcode; 58 1.1 christos int format; 59 1.1 christos char fname[12]; 60 1.1 christos void (*func)(SIM_DESC, SIM_CPU *); 61 1.1 christos int numops; 62 1.1 christos operand_desc operands[4]; 63 1.1 christos }; 64 1.1 christos 65 1.1 christos enum _ins_type 66 1.1 christos { 67 1.1 christos INS_UNKNOWN, /* unknown instruction */ 68 1.1 christos INS_NO_TYPE_INS, 69 1.1 christos INS_ARITH_INS, 70 1.1 christos INS_LD_STOR_INS, 71 1.1 christos INS_BRANCH_INS, 72 1.1 christos INS_ARITH_BYTE_INS, 73 1.1 christos INS_SHIFT_INS, 74 1.1 christos INS_BRANCH_NEQ_INS, 75 1.1 christos INS_STOR_IMM_INS, 76 1.1 christos INS_CSTBIT_INS, 77 1.1 christos INS_MAX 78 1.1 christos }; 79 1.1 christos 80 1.1 christos extern unsigned long ins_type_counters[ (int)INS_MAX ]; 81 1.1 christos 82 1.1 christos enum { 83 1.1 christos SP_IDX = 15, 84 1.1 christos }; 85 1.1 christos 86 1.1 christos /* Write-back slots */ 87 1.1 christos union slot_data { 88 1.1 christos unsigned_1 _1; 89 1.1 christos unsigned_2 _2; 90 1.1 christos unsigned_4 _4; 91 1.1 christos }; 92 1.1 christos struct slot { 93 1.1 christos void *dest; 94 1.1 christos int size; 95 1.1 christos union slot_data data; 96 1.1 christos union slot_data mask; 97 1.1 christos }; 98 1.1 christos enum { 99 1.1 christos NR_SLOTS = 16 100 1.1 christos }; 101 1.1 christos #define SLOT (State.slot) 102 1.1 christos #define SLOT_NR (State.slot_nr) 103 1.1 christos #define SLOT_PEND_MASK(DEST, MSK, VAL) \ 104 1.1 christos do \ 105 1.1 christos { \ 106 1.1 christos SLOT[SLOT_NR].dest = &(DEST); \ 107 1.1 christos SLOT[SLOT_NR].size = sizeof (DEST); \ 108 1.1 christos switch (sizeof (DEST)) \ 109 1.1 christos { \ 110 1.1 christos case 1: \ 111 1.1 christos SLOT[SLOT_NR].data._1 = (unsigned_1) (VAL); \ 112 1.1 christos SLOT[SLOT_NR].mask._1 = (unsigned_1) (MSK); \ 113 1.1 christos break; \ 114 1.1 christos case 2: \ 115 1.1 christos SLOT[SLOT_NR].data._2 = (unsigned_2) (VAL); \ 116 1.1 christos SLOT[SLOT_NR].mask._2 = (unsigned_2) (MSK); \ 117 1.1 christos break; \ 118 1.1 christos case 4: \ 119 1.1 christos SLOT[SLOT_NR].data._4 = (unsigned_4) (VAL); \ 120 1.1 christos SLOT[SLOT_NR].mask._4 = (unsigned_4) (MSK); \ 121 1.1 christos break; \ 122 1.1 christos } \ 123 1.1 christos SLOT_NR = (SLOT_NR + 1); \ 124 1.1 christos } \ 125 1.1 christos while (0) 126 1.1 christos #define SLOT_PEND(DEST, VAL) SLOT_PEND_MASK(DEST, 0, VAL) 127 1.1 christos #define SLOT_DISCARD() (SLOT_NR = 0) 128 1.1 christos #define SLOT_FLUSH() \ 129 1.1 christos do \ 130 1.1 christos { \ 131 1.1 christos int i; \ 132 1.1 christos for (i = 0; i < SLOT_NR; i++) \ 133 1.1 christos { \ 134 1.1 christos switch (SLOT[i].size) \ 135 1.1 christos { \ 136 1.1 christos case 1: \ 137 1.1 christos *(unsigned_1*) SLOT[i].dest &= SLOT[i].mask._1; \ 138 1.1 christos *(unsigned_1*) SLOT[i].dest |= SLOT[i].data._1; \ 139 1.1 christos break; \ 140 1.1 christos case 2: \ 141 1.1 christos *(unsigned_2*) SLOT[i].dest &= SLOT[i].mask._2; \ 142 1.1 christos *(unsigned_2*) SLOT[i].dest |= SLOT[i].data._2; \ 143 1.1 christos break; \ 144 1.1 christos case 4: \ 145 1.1 christos *(unsigned_4*) SLOT[i].dest &= SLOT[i].mask._4; \ 146 1.1 christos *(unsigned_4*) SLOT[i].dest |= SLOT[i].data._4; \ 147 1.1 christos break; \ 148 1.1 christos } \ 149 1.1 christos } \ 150 1.1 christos SLOT_NR = 0; \ 151 1.1 christos } \ 152 1.1 christos while (0) 153 1.1 christos #define SLOT_DUMP() \ 154 1.1 christos do \ 155 1.1 christos { \ 156 1.1 christos int i; \ 157 1.1 christos for (i = 0; i < SLOT_NR; i++) \ 158 1.1 christos { \ 159 1.1 christos switch (SLOT[i].size) \ 160 1.1 christos { \ 161 1.1 christos case 1: \ 162 1.1 christos printf ("SLOT %d *0x%08lx & 0x%02x | 0x%02x\n", i, \ 163 1.1 christos (long) SLOT[i].dest, \ 164 1.1 christos (unsigned) SLOT[i].mask._1, \ 165 1.1 christos (unsigned) SLOT[i].data._1); \ 166 1.1 christos break; \ 167 1.1 christos case 2: \ 168 1.1 christos printf ("SLOT %d *0x%08lx & 0x%04x | 0x%04x\n", i, \ 169 1.1 christos (long) SLOT[i].dest, \ 170 1.1 christos (unsigned) SLOT[i].mask._2, \ 171 1.1 christos (unsigned) SLOT[i].data._2); \ 172 1.1 christos break; \ 173 1.1 christos case 4: \ 174 1.1 christos printf ("SLOT %d *0x%08lx & 0x%08x | 0x%08x\n", i, \ 175 1.1 christos (long) SLOT[i].dest, \ 176 1.1 christos (unsigned) SLOT[i].mask._4, \ 177 1.1 christos (unsigned) SLOT[i].data._4); \ 178 1.1 christos break; \ 179 1.1 christos case 8: \ 180 1.1 christos printf ("SLOT %d *0x%08lx & 0x%08x%08x | 0x%08x%08x\n", i, \ 181 1.1 christos (long) SLOT[i].dest, \ 182 1.1 christos (unsigned) (SLOT[i].mask._8 >> 32), \ 183 1.1 christos (unsigned) SLOT[i].mask._8, \ 184 1.1 christos (unsigned) (SLOT[i].data._8 >> 32), \ 185 1.1 christos (unsigned) SLOT[i].data._8); \ 186 1.1 christos break; \ 187 1.1 christos } \ 188 1.1 christos } \ 189 1.1 christos } \ 190 1.1 christos while (0) 191 1.1 christos 192 1.1 christos struct _state 193 1.1 christos { 194 1.1 christos creg_t regs[16]; /* general-purpose registers */ 195 1.1 christos #define GPR(N) (State.regs[(N)] + 0) 196 1.1 christos #define SET_GPR(N,VAL) (State.regs[(N)] = (VAL)) 197 1.1 christos 198 1.1 christos #define GPR32(N) \ 199 1.1 christos (N < 12) ? \ 200 1.1 christos ((((uint16_t) State.regs[(N) + 1]) << 16) | (uint16_t) State.regs[(N)]) \ 201 1.1 christos : GPR (N) 202 1.1 christos 203 1.1 christos #define SET_GPR32(N,VAL) do { \ 204 1.1 christos if (N < 11) \ 205 1.1 christos { SET_GPR (N + 1, (VAL) >> 16); SET_GPR (N, ((VAL) & 0xffff));} \ 206 1.1 christos else { if ( N == 11) \ 207 1.1 christos { SET_GPR (N + 1, ((GPR32 (12)) & 0xffff0000)|((VAL) >> 16)); \ 208 1.1 christos SET_GPR (N, ((VAL) & 0xffff));} \ 209 1.1 christos else SET_GPR (N, (VAL));} \ 210 1.1 christos } while (0) 211 1.1 christos 212 1.1 christos creg_t cregs[16]; /* control registers */ 213 1.1 christos #define CREG(N) (State.cregs[(N)] + 0) 214 1.1 christos #define SET_CREG(N,VAL) move_to_cr (sd, cpu, (N), 0, (VAL), 0) 215 1.1 christos #define SET_HW_CREG(N,VAL) move_to_cr (sd, cpu, (N), 0, (VAL), 1) 216 1.1 christos 217 1.1 christos reg_t sp[2]; /* holding area for SPI(0)/SPU(1) */ 218 1.1 christos #define HELD_SP(N) (State.sp[(N)] + 0) 219 1.1 christos #define SET_HELD_SP(N,VAL) SLOT_PEND (State.sp[(N)], (VAL)) 220 1.1 christos 221 1.1 christos /* writeback info */ 222 1.1 christos struct slot slot[NR_SLOTS]; 223 1.1 christos int slot_nr; 224 1.1 christos 225 1.1 christos /* trace data */ 226 1.1 christos struct { 227 1.1 christos uint16_t psw; 228 1.1 christos } trace; 229 1.1 christos 230 1.1 christos int pc_changed; 231 1.1 christos 232 1.1 christos /* NOTE: everything below this line is not reset by 233 1.1 christos sim_create_inferior() */ 234 1.1 christos 235 1.1 christos enum _ins_type ins_type; 236 1.1 christos 237 1.1 christos }; 238 1.1 christos 239 1.1 christos extern struct _state State; 240 1.1 christos 241 1.1 christos 242 1.1 christos extern uint32_t OP[4]; 243 1.1 christos extern uint32_t sign_flag; 244 1.1 christos extern struct simops Simops[]; 245 1.1 christos 246 1.1 christos enum 247 1.1 christos { 248 1.1 christos PC_CR = 0, 249 1.1 christos BDS_CR = 1, 250 1.1 christos BSR_CR = 2, 251 1.1 christos DCR_CR = 3, 252 1.1 christos CAR0_CR = 5, 253 1.1 christos CAR1_CR = 7, 254 1.1 christos CFG_CR = 9, 255 1.1 christos PSR_CR = 10, 256 1.1 christos INTBASE_CR = 11, 257 1.1 christos ISP_CR = 13, 258 1.1 christos USP_CR = 15 259 1.1 christos }; 260 1.1 christos 261 1.1 christos enum 262 1.1 christos { 263 1.1 christos PSR_I_BIT = 0x0800, 264 1.1 christos PSR_P_BIT = 0x0400, 265 1.1 christos PSR_E_BIT = 0x0200, 266 1.1 christos PSR_N_BIT = 0x0080, 267 1.1 christos PSR_Z_BIT = 0x0040, 268 1.1 christos PSR_F_BIT = 0x0020, 269 1.1 christos PSR_U_BIT = 0x0008, 270 1.1 christos PSR_L_BIT = 0x0004, 271 1.1 christos PSR_T_BIT = 0x0002, 272 1.1 christos PSR_C_BIT = 0x0001 273 1.1 christos }; 274 1.1 christos 275 1.1 christos #define PSR CREG (PSR_CR) 276 1.1 christos #define SET_PSR(VAL) SET_CREG (PSR_CR, (VAL)) 277 1.1 christos #define SET_HW_PSR(VAL) SET_HW_CREG (PSR_CR, (VAL)) 278 1.1 christos #define SET_PSR_BIT(MASK,VAL) move_to_cr (sd, cpu, PSR_CR, ~((creg_t) MASK), (VAL) ? (MASK) : 0, 1) 279 1.1 christos 280 1.1 christos #define PSR_SM ((PSR & PSR_SM_BIT) != 0) 281 1.1 christos #define SET_PSR_SM(VAL) SET_PSR_BIT (PSR_SM_BIT, (VAL)) 282 1.1 christos 283 1.1 christos #define PSR_I ((PSR & PSR_I_BIT) != 0) 284 1.1 christos #define SET_PSR_I(VAL) SET_PSR_BIT (PSR_I_BIT, (VAL)) 285 1.1 christos 286 1.1 christos #define PSR_DB ((PSR & PSR_DB_BIT) != 0) 287 1.1 christos #define SET_PSR_DB(VAL) SET_PSR_BIT (PSR_DB_BIT, (VAL)) 288 1.1 christos 289 1.1 christos #define PSR_P ((PSR & PSR_P_BIT) != 0) 290 1.1 christos #define SET_PSR_P(VAL) SET_PSR_BIT (PSR_P_BIT, (VAL)) 291 1.1 christos 292 1.1 christos #define PSR_E ((PSR & PSR_E_BIT) != 0) 293 1.1 christos #define SET_PSR_E(VAL) SET_PSR_BIT (PSR_E_BIT, (VAL)) 294 1.1 christos 295 1.1 christos #define PSR_N ((PSR & PSR_N_BIT) != 0) 296 1.1 christos #define SET_PSR_N(VAL) SET_PSR_BIT (PSR_N_BIT, (VAL)) 297 1.1 christos 298 1.1 christos #define PSR_Z ((PSR & PSR_Z_BIT) != 0) 299 1.1 christos #define SET_PSR_Z(VAL) SET_PSR_BIT (PSR_Z_BIT, (VAL)) 300 1.1 christos 301 1.1 christos #define PSR_F ((PSR & PSR_F_BIT) != 0) 302 1.1 christos #define SET_PSR_F(VAL) SET_PSR_BIT (PSR_F_BIT, (VAL)) 303 1.1 christos 304 1.1 christos #define PSR_U ((PSR & PSR_U_BIT) != 0) 305 1.1 christos #define SET_PSR_U(VAL) SET_PSR_BIT (PSR_U_BIT, (VAL)) 306 1.1 christos 307 1.1 christos #define PSR_L ((PSR & PSR_L_BIT) != 0) 308 1.1 christos #define SET_PSR_L(VAL) SET_PSR_BIT (PSR_L_BIT, (VAL)) 309 1.1 christos 310 1.1 christos #define PSR_T ((PSR & PSR_T_BIT) != 0) 311 1.1 christos #define SET_PSR_T(VAL) SET_PSR_BIT (PSR_T_BIT, (VAL)) 312 1.1 christos 313 1.1 christos #define PSR_C ((PSR & PSR_C_BIT) != 0) 314 1.1 christos #define SET_PSR_C(VAL) SET_PSR_BIT (PSR_C_BIT, (VAL)) 315 1.1 christos 316 1.1 christos /* See simopsc.:move_to_cr() for registers that can not be read-from 317 1.1 christos or assigned-to directly */ 318 1.1 christos 319 1.1 christos #define PC CREG (PC_CR) 320 1.1 christos #define SET_PC(VAL) SET_CREG (PC_CR, (VAL)) 321 1.1 christos //#define SET_PC(VAL) (State.cregs[PC_CR] = (VAL)) 322 1.1 christos 323 1.1 christos #define BPSR CREG (BPSR_CR) 324 1.1 christos #define SET_BPSR(VAL) SET_CREG (BPSR_CR, (VAL)) 325 1.1 christos 326 1.1 christos #define BPC CREG (BPC_CR) 327 1.1 christos #define SET_BPC(VAL) SET_CREG (BPC_CR, (VAL)) 328 1.1 christos 329 1.1 christos #define DPSR CREG (DPSR_CR) 330 1.1 christos #define SET_DPSR(VAL) SET_CREG (DPSR_CR, (VAL)) 331 1.1 christos 332 1.1 christos #define DPC CREG (DPC_CR) 333 1.1 christos #define SET_DPC(VAL) SET_CREG (DPC_CR, (VAL)) 334 1.1 christos 335 1.1 christos #define RPT_C CREG (RPT_C_CR) 336 1.1 christos #define SET_RPT_C(VAL) SET_CREG (RPT_C_CR, (VAL)) 337 1.1 christos 338 1.1 christos #define RPT_S CREG (RPT_S_CR) 339 1.1 christos #define SET_RPT_S(VAL) SET_CREG (RPT_S_CR, (VAL)) 340 1.1 christos 341 1.1 christos #define RPT_E CREG (RPT_E_CR) 342 1.1 christos #define SET_RPT_E(VAL) SET_CREG (RPT_E_CR, (VAL)) 343 1.1 christos 344 1.1 christos #define MOD_S CREG (MOD_S_CR) 345 1.1 christos #define SET_MOD_S(VAL) SET_CREG (MOD_S_CR, (VAL)) 346 1.1 christos 347 1.1 christos #define MOD_E CREG (MOD_E_CR) 348 1.1 christos #define SET_MOD_E(VAL) SET_CREG (MOD_E_CR, (VAL)) 349 1.1 christos 350 1.1 christos #define IBA CREG (IBA_CR) 351 1.1 christos #define SET_IBA(VAL) SET_CREG (IBA_CR, (VAL)) 352 1.1 christos 353 1.1 christos 354 1.1 christos #define SIG_CR16_STOP -1 355 1.1 christos #define SIG_CR16_EXIT -2 356 1.1 christos #define SIG_CR16_BUS -3 357 1.1 christos #define SIG_CR16_IAD -4 358 1.1 christos 359 1.1 christos /* TODO: Resolve conflicts with common headers. */ 360 1.1 christos #undef SEXT8 361 1.1 christos #undef SEXT16 362 1.1 christos #undef SEXT32 363 1.1 christos 364 1.1 christos #define SEXT3(x) ((((x)&0x7)^(~3))+4) 365 1.1 christos 366 1.1 christos /* sign-extend a 4-bit number */ 367 1.1 christos #define SEXT4(x) ((((x)&0xf)^(~7))+8) 368 1.1 christos 369 1.1 christos /* sign-extend an 8-bit number */ 370 1.1 christos #define SEXT8(x) ((((x)&0xff)^(~0x7f))+0x80) 371 1.1 christos 372 1.1 christos /* sign-extend a 16-bit number */ 373 1.1 christos #define SEXT16(x) ((((x)&0xffff)^(~0x7fff))+0x8000) 374 1.1 christos 375 1.1 christos /* sign-extend a 24-bit number */ 376 1.1 christos #define SEXT24(x) ((((x)&0xffffff)^(~0x7fffff))+0x800000) 377 1.1 christos 378 1.1 christos /* sign-extend a 32-bit number */ 379 1.1 christos #define SEXT32(x) ((((x)&0xffffffff)^(~0x7fffffff))+0x80000000) 380 1.1 christos 381 1.1 christos #define SB(addr, data) sim_core_write_1 (cpu, PC, read_map, addr, data) 382 1.1 christos #define RB(addr) sim_core_read_1 (cpu, PC, read_map, addr) 383 1.1 christos #define SW(addr, data) sim_core_write_unaligned_2 (cpu, PC, read_map, addr, data) 384 1.1 christos #define RW(addr) sim_core_read_unaligned_2 (cpu, PC, read_map, addr) 385 1.1 christos #define SLW(addr, data) sim_core_write_unaligned_4 (cpu, PC, read_map, addr, data) 386 1.1 christos 387 1.1 christos /* Yes, this is as whacked as it looks. The sim currently reads little endian 388 1.1 christos for 16 bits, but then merge them like big endian to get 32 bits. */ 389 1.1 christos static inline uint32_t get_longword (SIM_CPU *cpu, address_word addr) 390 1.1 christos { 391 1.1 christos return (RW (addr) << 16) | RW (addr + 2); 392 1.1 christos } 393 1.1 christos #define RLW(addr) get_longword (cpu, addr) 394 1.1 christos 395 1.1 christos #define JMP(x) do { SET_PC (x); State.pc_changed = 1; } while (0) 396 1.1 christos 397 1.1 christos #define RIE_VECTOR_START 0xffc2 398 1.1 christos #define AE_VECTOR_START 0xffc3 399 1.1 christos #define TRAP_VECTOR_START 0xffc4 /* vector for trap 0 */ 400 1.1 christos #define DBT_VECTOR_START 0xffd4 401 1.1 christos #define SDBT_VECTOR_START 0xffd5 402 1.1 christos 403 1.1 christos #define INT_VECTOR_START 0xFFFE00 /*maskable interrupt - mapped to ICU */ 404 1.1 christos #define NMI_VECTOR_START 0xFFFF00 /*non-maskable interrupt;for observability*/ 405 1.1 christos #define ISE_VECTOR_START 0xFFFC00 /*in-system emulation trap */ 406 1.1 christos #define ADBG_VECTOR_START 0xFFFC02 /*alternate debug trap */ 407 1.1 christos #define ATRC_VECTOR_START 0xFFFC0C /*alternate trace trap */ 408 1.1 christos #define ABPT_VECTOR_START 0xFFFC0E /*alternate break point trap */ 409 1.1 christos 410 1.1 christos 411 1.1 christos /* Scedule a store of VAL into cr[CR]. MASK indicates the bits in 412 1.1 christos cr[CR] that should not be modified (i.e. cr[CR] = (cr[CR] & MASK) | 413 1.1 christos (VAL & ~MASK)). In addition, unless PSR_HW_P, a VAL intended for 414 1.1 christos PSR is masked for zero bits. */ 415 1.1 christos 416 1.1 christos extern creg_t move_to_cr (SIM_DESC, SIM_CPU *, int cr, creg_t mask, creg_t val, int psw_hw_p); 417 1.1 christos 418 1.1 christos #ifndef SIGTRAP 419 1.1 christos #define SIGTRAP 5 420 1.1 christos #endif 421 1.1 christos /* Special purpose trap */ 422 1.1 christos #define TRAP_BREAKPOINT 8 423