1 1.1 christos /* Support code for various pieces of CGEN simulators. 2 1.11 christos Copyright (C) 1996-2024 Free Software Foundation, Inc. 3 1.1 christos Contributed by Cygnus Support. 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 of the License, or 10 1.1 christos (at your option) 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.10 christos /* This must come before any other includes. */ 21 1.10 christos #include "defs.h" 22 1.10 christos 23 1.1 christos #include "bfd.h" 24 1.10 christos #include "dis-asm.h" 25 1.10 christos 26 1.1 christos #include "sim-main.h" 27 1.10 christos #include "sim-signal.h" 28 1.1 christos 29 1.1 christos #define MEMOPS_DEFINE_INLINE 30 1.1 christos #include "cgen-mem.h" 31 1.1 christos 32 1.1 christos #define SEMOPS_DEFINE_INLINE 33 1.1 christos #include "cgen-ops.h" 34 1.1 christos 35 1.10 christos const char * const cgen_mode_names[] = { 36 1.1 christos "VOID", 37 1.1 christos "BI", 38 1.1 christos "QI", 39 1.1 christos "HI", 40 1.1 christos "SI", 41 1.1 christos "DI", 42 1.1 christos "UQI", 43 1.1 christos "UHI", 44 1.1 christos "USI", 45 1.1 christos "UDI", 46 1.1 christos "SF", 47 1.1 christos "DF", 48 1.1 christos "XF", 49 1.1 christos "TF", 50 1.1 christos 0, /* MODE_TARGET_MAX */ 51 1.1 christos "INT", 52 1.1 christos "UINT", 53 1.1 christos "PTR" 54 1.1 christos }; 55 1.1 christos 56 1.1 christos /* Opcode table for virtual insns used by the simulator. */ 57 1.1 christos 58 1.1 christos #define V CGEN_ATTR_MASK (CGEN_INSN_VIRTUAL) 59 1.1 christos 60 1.1 christos static const CGEN_IBASE virtual_insn_entries[] = 61 1.1 christos { 62 1.1 christos { 63 1.10 christos VIRTUAL_INSN_X_INVALID, "--invalid--", NULL, 0, { V, {} } 64 1.1 christos }, 65 1.1 christos { 66 1.10 christos VIRTUAL_INSN_X_BEFORE, "--before--", NULL, 0, { V, {} } 67 1.1 christos }, 68 1.1 christos { 69 1.10 christos VIRTUAL_INSN_X_AFTER, "--after--", NULL, 0, { V, {} } 70 1.1 christos }, 71 1.1 christos { 72 1.10 christos VIRTUAL_INSN_X_BEGIN, "--begin--", NULL, 0, { V, {} } 73 1.1 christos }, 74 1.1 christos { 75 1.10 christos VIRTUAL_INSN_X_CHAIN, "--chain--", NULL, 0, { V, {} } 76 1.1 christos }, 77 1.1 christos { 78 1.10 christos VIRTUAL_INSN_X_CTI_CHAIN, "--cti-chain--", NULL, 0, { V, {} } 79 1.1 christos } 80 1.1 christos }; 81 1.1 christos 82 1.1 christos #undef V 83 1.1 christos 84 1.1 christos const CGEN_INSN cgen_virtual_insn_table[] = 85 1.1 christos { 86 1.1 christos { & virtual_insn_entries[0] }, 87 1.1 christos { & virtual_insn_entries[1] }, 88 1.1 christos { & virtual_insn_entries[2] }, 89 1.1 christos { & virtual_insn_entries[3] }, 90 1.1 christos { & virtual_insn_entries[4] }, 91 1.1 christos { & virtual_insn_entries[5] } 92 1.1 christos }; 93 1.1 christos 94 1.1 christos /* Return the name of insn number I. */ 95 1.1 christos 96 1.1 christos const char * 97 1.1 christos cgen_insn_name (SIM_CPU *cpu, int i) 98 1.1 christos { 99 1.1 christos return CGEN_INSN_NAME ((* CPU_GET_IDATA (cpu)) ((cpu), (i))); 100 1.1 christos } 101 1.1 christos 102 1.1 christos /* Return the maximum number of extra bytes required for a SIM_CPU struct. */ 103 1.1 christos 104 1.1 christos int 105 1.10 christos cgen_cpu_max_extra_bytes (SIM_DESC sd) 106 1.1 christos { 107 1.10 christos const SIM_MACH * const *machp; 108 1.1 christos int extra = 0; 109 1.1 christos 110 1.10 christos SIM_ASSERT (STATE_MACHS (sd) != NULL); 111 1.10 christos 112 1.10 christos for (machp = STATE_MACHS (sd); *machp != NULL; ++machp) 113 1.1 christos { 114 1.10 christos int size = IMP_PROPS_SIM_CPU_SIZE (MACH_IMP_PROPS (*machp)); 115 1.1 christos if (size > extra) 116 1.1 christos extra = size; 117 1.1 christos } 118 1.1 christos return extra; 119 1.1 christos } 120 1.1 christos 121 1.1 christos #ifdef DI_FN_SUPPORT 123 1.1 christos 124 1.1 christos DI 125 1.1 christos ANDDI (a, b) 126 1.1 christos DI a, b; 127 1.1 christos { 128 1.1 christos SI ahi = GETHIDI (a); 129 1.1 christos SI alo = GETLODI (a); 130 1.1 christos SI bhi = GETHIDI (b); 131 1.1 christos SI blo = GETLODI (b); 132 1.1 christos return MAKEDI (ahi & bhi, alo & blo); 133 1.1 christos } 134 1.1 christos 135 1.1 christos DI 136 1.1 christos ORDI (a, b) 137 1.1 christos DI a, b; 138 1.1 christos { 139 1.1 christos SI ahi = GETHIDI (a); 140 1.1 christos SI alo = GETLODI (a); 141 1.1 christos SI bhi = GETHIDI (b); 142 1.1 christos SI blo = GETLODI (b); 143 1.1 christos return MAKEDI (ahi | bhi, alo | blo); 144 1.1 christos } 145 1.1 christos 146 1.1 christos DI 147 1.1 christos ADDDI (a, b) 148 1.1 christos DI a, b; 149 1.1 christos { 150 1.1 christos USI ahi = GETHIDI (a); 151 1.1 christos USI alo = GETLODI (a); 152 1.1 christos USI bhi = GETHIDI (b); 153 1.1 christos USI blo = GETLODI (b); 154 1.1 christos USI x = alo + blo; 155 1.1 christos return MAKEDI (ahi + bhi + (x < alo), x); 156 1.1 christos } 157 1.1 christos 158 1.1 christos DI 159 1.1 christos MULDI (a, b) 160 1.1 christos DI a, b; 161 1.1 christos { 162 1.1 christos USI ahi = GETHIDI (a); 163 1.1 christos USI alo = GETLODI (a); 164 1.1 christos USI bhi = GETHIDI (b); 165 1.1 christos USI blo = GETLODI (b); 166 1.1 christos USI rhi,rlo; 167 1.1 christos USI x0, x1, x2, x3; 168 1.1 christos 169 1.1 christos x0 = alo * blo; 170 1.1 christos x1 = alo * bhi; 171 1.1 christos x2 = ahi * blo; 172 1.1 christos x3 = ahi * bhi; 173 1.1 christos 174 1.1 christos #define SI_TYPE_SIZE 32 175 1.1 christos #define BITS4 (SI_TYPE_SIZE / 4) 176 1.1 christos #define ll_B (1L << (SI_TYPE_SIZE / 2)) 177 1.1 christos #define ll_lowpart(t) ((USI) (t) % ll_B) 178 1.1 christos #define ll_highpart(t) ((USI) (t) / ll_B) 179 1.1 christos x1 += ll_highpart (x0); /* this can't give carry */ 180 1.1 christos x1 += x2; /* but this indeed can */ 181 1.1 christos if (x1 < x2) /* did we get it? */ 182 1.1 christos x3 += ll_B; /* yes, add it in the proper pos. */ 183 1.1 christos 184 1.1 christos rhi = x3 + ll_highpart (x1); 185 1.1 christos rlo = ll_lowpart (x1) * ll_B + ll_lowpart (x0); 186 1.1 christos return MAKEDI (rhi + (alo * bhi) + (ahi * blo), rlo); 187 1.1 christos } 188 1.1 christos 189 1.1 christos DI 190 1.1 christos SHLDI (val, shift) 191 1.1 christos DI val; 192 1.1 christos SI shift; 193 1.1 christos { 194 1.1 christos USI hi = GETHIDI (val); 195 1.1 christos USI lo = GETLODI (val); 196 1.1 christos /* FIXME: Need to worry about shift < 0 || shift >= 32. */ 197 1.1 christos return MAKEDI ((hi << shift) | (lo >> (32 - shift)), lo << shift); 198 1.1 christos } 199 1.1 christos 200 1.1 christos DI 201 1.1 christos SLADI (val, shift) 202 1.1 christos DI val; 203 1.1 christos SI shift; 204 1.1 christos { 205 1.1 christos SI hi = GETHIDI (val); 206 1.1 christos USI lo = GETLODI (val); 207 1.1 christos /* FIXME: Need to worry about shift < 0 || shift >= 32. */ 208 1.1 christos return MAKEDI ((hi << shift) | (lo >> (32 - shift)), lo << shift); 209 1.1 christos } 210 1.1 christos 211 1.1 christos DI 212 1.1 christos SRADI (val, shift) 213 1.1 christos DI val; 214 1.1 christos SI shift; 215 1.1 christos { 216 1.1 christos SI hi = GETHIDI (val); 217 1.1 christos USI lo = GETLODI (val); 218 1.1 christos /* We use SRASI because the result is implementation defined if hi < 0. */ 219 1.1 christos /* FIXME: Need to worry about shift < 0 || shift >= 32. */ 220 1.1 christos return MAKEDI (SRASI (hi, shift), (hi << (32 - shift)) | (lo >> shift)); 221 1.1 christos } 222 1.1 christos 223 1.1 christos int 224 1.1 christos GEDI (a, b) 225 1.1 christos DI a, b; 226 1.1 christos { 227 1.1 christos SI ahi = GETHIDI (a); 228 1.1 christos USI alo = GETLODI (a); 229 1.1 christos SI bhi = GETHIDI (b); 230 1.1 christos USI blo = GETLODI (b); 231 1.1 christos if (ahi > bhi) 232 1.1 christos return 1; 233 1.1 christos if (ahi == bhi) 234 1.1 christos return alo >= blo; 235 1.1 christos return 0; 236 1.1 christos } 237 1.1 christos 238 1.1 christos int 239 1.1 christos LEDI (a, b) 240 1.1 christos DI a, b; 241 1.1 christos { 242 1.1 christos SI ahi = GETHIDI (a); 243 1.1 christos USI alo = GETLODI (a); 244 1.1 christos SI bhi = GETHIDI (b); 245 1.1 christos USI blo = GETLODI (b); 246 1.1 christos if (ahi < bhi) 247 1.1 christos return 1; 248 1.1 christos if (ahi == bhi) 249 1.1 christos return alo <= blo; 250 1.1 christos return 0; 251 1.1 christos } 252 1.1 christos 253 1.1 christos DI 254 1.1 christos CONVHIDI (val) 255 1.1 christos HI val; 256 1.1 christos { 257 1.1 christos if (val < 0) 258 1.1 christos return MAKEDI (-1, val); 259 1.1 christos else 260 1.1 christos return MAKEDI (0, val); 261 1.1 christos } 262 1.1 christos 263 1.1 christos DI 264 1.1 christos CONVSIDI (val) 265 1.1 christos SI val; 266 1.1 christos { 267 1.1 christos if (val < 0) 268 1.1 christos return MAKEDI (-1, val); 269 1.1 christos else 270 1.1 christos return MAKEDI (0, val); 271 1.1 christos } 272 1.1 christos 273 1.1 christos SI 274 1.1 christos CONVDISI (val) 275 1.1 christos DI val; 276 1.1 christos { 277 1.1 christos return GETLODI (val); 278 1.1 christos } 279 1.1 christos 280 1.1 christos #endif /* DI_FN_SUPPORT */ 281 1.1 christos 282 1.10 christos QI 284 1.1 christos RORQI (QI val, int shift) 285 1.1 christos { 286 1.1 christos if (shift != 0) 287 1.1 christos { 288 1.1 christos int remain = 8 - shift; 289 1.1 christos int mask = (1 << shift) - 1; 290 1.1 christos QI result = (val & mask) << remain; 291 1.1 christos mask = (1 << remain) - 1; 292 1.1 christos result |= (val >> shift) & mask; 293 1.1 christos return result; 294 1.1 christos } 295 1.1 christos return val; 296 1.1 christos } 297 1.10 christos 298 1.1 christos QI 299 1.1 christos ROLQI (QI val, int shift) 300 1.1 christos { 301 1.1 christos if (shift != 0) 302 1.1 christos { 303 1.1 christos int remain = 8 - shift; 304 1.1 christos int mask = (1 << remain) - 1; 305 1.1 christos QI result = (val & mask) << shift; 306 1.1 christos mask = (1 << shift) - 1; 307 1.1 christos result |= (val >> remain) & mask; 308 1.1 christos return result; 309 1.1 christos } 310 1.1 christos return val; 311 1.1 christos } 312 1.10 christos 313 1.1 christos HI 314 1.1 christos RORHI (HI val, int shift) 315 1.1 christos { 316 1.1 christos if (shift != 0) 317 1.1 christos { 318 1.1 christos int remain = 16 - shift; 319 1.1 christos int mask = (1 << shift) - 1; 320 1.1 christos HI result = (val & mask) << remain; 321 1.1 christos mask = (1 << remain) - 1; 322 1.1 christos result |= (val >> shift) & mask; 323 1.1 christos return result; 324 1.1 christos } 325 1.1 christos return val; 326 1.1 christos } 327 1.10 christos 328 1.1 christos HI 329 1.1 christos ROLHI (HI val, int shift) 330 1.1 christos { 331 1.1 christos if (shift != 0) 332 1.1 christos { 333 1.1 christos int remain = 16 - shift; 334 1.1 christos int mask = (1 << remain) - 1; 335 1.1 christos HI result = (val & mask) << shift; 336 1.1 christos mask = (1 << shift) - 1; 337 1.1 christos result |= (val >> remain) & mask; 338 1.1 christos return result; 339 1.1 christos } 340 1.1 christos return val; 341 1.1 christos } 342 1.10 christos 343 1.1 christos SI 344 1.1 christos RORSI (SI val, int shift) 345 1.1 christos { 346 1.1 christos if (shift != 0) 347 1.1 christos { 348 1.1 christos int remain = 32 - shift; 349 1.1 christos int mask = (1 << shift) - 1; 350 1.1 christos SI result = (val & mask) << remain; 351 1.1 christos mask = (1 << remain) - 1; 352 1.1 christos result |= (val >> shift) & mask; 353 1.1 christos return result; 354 1.1 christos } 355 1.1 christos return val; 356 1.1 christos } 357 1.10 christos 358 1.1 christos SI 359 1.1 christos ROLSI (SI val, int shift) 360 1.1 christos { 361 1.1 christos if (shift != 0) 362 1.1 christos { 363 1.1 christos int remain = 32 - shift; 364 1.1 christos int mask = (1 << remain) - 1; 365 1.1 christos SI result = (val & mask) << shift; 366 1.1 christos mask = (1 << shift) - 1; 367 1.1 christos result |= (val >> remain) & mask; 368 1.1 christos return result; 369 1.1 christos } 370 1.1 christos 371 1.1 christos return val; 372 1.1 christos } 373 1.1 christos 374 1.1 christos /* Emit an error message from CGEN RTL. */ 375 1.1 christos 376 1.1 christos void 377 1.1 christos cgen_rtx_error (SIM_CPU *cpu, const char * msg) 378 1.1 christos { 379 1.10 christos SIM_DESC sd = CPU_STATE (cpu); 380 1.1 christos 381 1.1 christos sim_io_printf (sd, "%s", msg); 382 1.5 christos sim_io_printf (sd, "\n"); 383 1.1 christos 384 sim_engine_halt (sd, cpu, NULL, CPU_PC_GET (cpu), sim_stopped, SIM_SIGTRAP); 385 } 386