1c5dff60aSchristos /* Support code for various pieces of CGEN simulators. 2*48596154Schristos Copyright (C) 1996-2013 Free Software Foundation, Inc. 3c5dff60aSchristos Contributed by Cygnus Support. 4c5dff60aSchristos 5c5dff60aSchristos This file is part of GDB, the GNU debugger. 6c5dff60aSchristos 7c5dff60aSchristos This program is free software; you can redistribute it and/or modify 8c5dff60aSchristos it under the terms of the GNU General Public License as published by 9c5dff60aSchristos the Free Software Foundation; either version 3 of the License, or 10c5dff60aSchristos (at your option) any later version. 11c5dff60aSchristos 12c5dff60aSchristos This program is distributed in the hope that it will be useful, 13c5dff60aSchristos but WITHOUT ANY WARRANTY; without even the implied warranty of 14c5dff60aSchristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15c5dff60aSchristos GNU General Public License for more details. 16c5dff60aSchristos 17c5dff60aSchristos You should have received a copy of the GNU General Public License 18c5dff60aSchristos along with this program. If not, see <http://www.gnu.org/licenses/>. */ 19c5dff60aSchristos 20*48596154Schristos #include "config.h" 21c5dff60aSchristos #include "bfd.h" 22c5dff60aSchristos #include "sim-main.h" 23c5dff60aSchristos #include "dis-asm.h" 24c5dff60aSchristos 25c5dff60aSchristos #define MEMOPS_DEFINE_INLINE 26c5dff60aSchristos #include "cgen-mem.h" 27c5dff60aSchristos 28c5dff60aSchristos #define SEMOPS_DEFINE_INLINE 29c5dff60aSchristos #include "cgen-ops.h" 30c5dff60aSchristos 31c5dff60aSchristos #undef min 32c5dff60aSchristos #define min(a,b) ((a) < (b) ? (a) : (b)) 33c5dff60aSchristos 34c5dff60aSchristos const char *mode_names[] = { 35c5dff60aSchristos "VOID", 36c5dff60aSchristos "BI", 37c5dff60aSchristos "QI", 38c5dff60aSchristos "HI", 39c5dff60aSchristos "SI", 40c5dff60aSchristos "DI", 41c5dff60aSchristos "UQI", 42c5dff60aSchristos "UHI", 43c5dff60aSchristos "USI", 44c5dff60aSchristos "UDI", 45c5dff60aSchristos "SF", 46c5dff60aSchristos "DF", 47c5dff60aSchristos "XF", 48c5dff60aSchristos "TF", 49c5dff60aSchristos 0, /* MODE_TARGET_MAX */ 50c5dff60aSchristos "INT", 51c5dff60aSchristos "UINT", 52c5dff60aSchristos "PTR" 53c5dff60aSchristos }; 54c5dff60aSchristos 55c5dff60aSchristos /* Opcode table for virtual insns used by the simulator. */ 56c5dff60aSchristos 57c5dff60aSchristos #define V CGEN_ATTR_MASK (CGEN_INSN_VIRTUAL) 58c5dff60aSchristos 59c5dff60aSchristos static const CGEN_IBASE virtual_insn_entries[] = 60c5dff60aSchristos { 61c5dff60aSchristos { 62c5dff60aSchristos VIRTUAL_INSN_X_INVALID, "--invalid--", NULL, 0, { V, { 0 } } 63c5dff60aSchristos }, 64c5dff60aSchristos { 65c5dff60aSchristos VIRTUAL_INSN_X_BEFORE, "--before--", NULL, 0, { V, { 0 } } 66c5dff60aSchristos }, 67c5dff60aSchristos { 68c5dff60aSchristos VIRTUAL_INSN_X_AFTER, "--after--", NULL, 0, { V, { 0 } } 69c5dff60aSchristos }, 70c5dff60aSchristos { 71c5dff60aSchristos VIRTUAL_INSN_X_BEGIN, "--begin--", NULL, 0, { V, { 0 } } 72c5dff60aSchristos }, 73c5dff60aSchristos { 74c5dff60aSchristos VIRTUAL_INSN_X_CHAIN, "--chain--", NULL, 0, { V, { 0 } } 75c5dff60aSchristos }, 76c5dff60aSchristos { 77c5dff60aSchristos VIRTUAL_INSN_X_CTI_CHAIN, "--cti-chain--", NULL, 0, { V, { 0 } } 78c5dff60aSchristos } 79c5dff60aSchristos }; 80c5dff60aSchristos 81c5dff60aSchristos #undef V 82c5dff60aSchristos 83c5dff60aSchristos const CGEN_INSN cgen_virtual_insn_table[] = 84c5dff60aSchristos { 85c5dff60aSchristos { & virtual_insn_entries[0] }, 86c5dff60aSchristos { & virtual_insn_entries[1] }, 87c5dff60aSchristos { & virtual_insn_entries[2] }, 88c5dff60aSchristos { & virtual_insn_entries[3] }, 89c5dff60aSchristos { & virtual_insn_entries[4] }, 90c5dff60aSchristos { & virtual_insn_entries[5] } 91c5dff60aSchristos }; 92c5dff60aSchristos 93c5dff60aSchristos /* Initialize cgen things. 94c5dff60aSchristos This is called after sim_post_argv_init. */ 95c5dff60aSchristos 96c5dff60aSchristos void 97c5dff60aSchristos cgen_init (SIM_DESC sd) 98c5dff60aSchristos { 99c5dff60aSchristos int i, c; 100c5dff60aSchristos 101c5dff60aSchristos /* If no profiling or tracing has been enabled, run in fast mode. */ 102c5dff60aSchristos { 103c5dff60aSchristos int run_fast_p = 1; 104c5dff60aSchristos 105c5dff60aSchristos for (c = 0; c < MAX_NR_PROCESSORS; ++c) 106c5dff60aSchristos { 107c5dff60aSchristos SIM_CPU *cpu = STATE_CPU (sd, c); 108c5dff60aSchristos 109c5dff60aSchristos for (i = 0; i < MAX_PROFILE_VALUES; ++i) 110c5dff60aSchristos if (CPU_PROFILE_FLAGS (cpu) [i]) 111c5dff60aSchristos { 112c5dff60aSchristos run_fast_p = 0; 113c5dff60aSchristos break; 114c5dff60aSchristos } 115c5dff60aSchristos for (i = 0; i < MAX_TRACE_VALUES; ++i) 116c5dff60aSchristos if (CPU_TRACE_FLAGS (cpu) [i]) 117c5dff60aSchristos { 118c5dff60aSchristos run_fast_p = 0; 119c5dff60aSchristos break; 120c5dff60aSchristos } 121c5dff60aSchristos if (! run_fast_p) 122c5dff60aSchristos break; 123c5dff60aSchristos } 124c5dff60aSchristos STATE_RUN_FAST_P (sd) = run_fast_p; 125c5dff60aSchristos } 126c5dff60aSchristos } 127c5dff60aSchristos 128c5dff60aSchristos /* Return the name of insn number I. */ 129c5dff60aSchristos 130c5dff60aSchristos const char * 131c5dff60aSchristos cgen_insn_name (SIM_CPU *cpu, int i) 132c5dff60aSchristos { 133c5dff60aSchristos return CGEN_INSN_NAME ((* CPU_GET_IDATA (cpu)) ((cpu), (i))); 134c5dff60aSchristos } 135c5dff60aSchristos 136c5dff60aSchristos /* Return the maximum number of extra bytes required for a SIM_CPU struct. */ 137c5dff60aSchristos 138c5dff60aSchristos int 139c5dff60aSchristos cgen_cpu_max_extra_bytes (void) 140c5dff60aSchristos { 141c5dff60aSchristos int i; 142c5dff60aSchristos int extra = 0; 143c5dff60aSchristos 144c5dff60aSchristos for (i = 0; sim_machs[i] != 0; ++i) 145c5dff60aSchristos { 146c5dff60aSchristos int size = IMP_PROPS_SIM_CPU_SIZE (MACH_IMP_PROPS (sim_machs[i])); 147c5dff60aSchristos if (size > extra) 148c5dff60aSchristos extra = size; 149c5dff60aSchristos } 150c5dff60aSchristos return extra; 151c5dff60aSchristos } 152c5dff60aSchristos 153c5dff60aSchristos #ifdef DI_FN_SUPPORT 154c5dff60aSchristos 155c5dff60aSchristos DI 156c5dff60aSchristos make_struct_di (hi, lo) 157c5dff60aSchristos SI hi, lo; 158c5dff60aSchristos { 159c5dff60aSchristos DI result; 160c5dff60aSchristos 161c5dff60aSchristos result.hi = hi; 162c5dff60aSchristos result.lo = lo; 163c5dff60aSchristos return result; 164c5dff60aSchristos } 165c5dff60aSchristos 166c5dff60aSchristos DI 167c5dff60aSchristos ANDDI (a, b) 168c5dff60aSchristos DI a, b; 169c5dff60aSchristos { 170c5dff60aSchristos SI ahi = GETHIDI (a); 171c5dff60aSchristos SI alo = GETLODI (a); 172c5dff60aSchristos SI bhi = GETHIDI (b); 173c5dff60aSchristos SI blo = GETLODI (b); 174c5dff60aSchristos return MAKEDI (ahi & bhi, alo & blo); 175c5dff60aSchristos } 176c5dff60aSchristos 177c5dff60aSchristos DI 178c5dff60aSchristos ORDI (a, b) 179c5dff60aSchristos DI a, b; 180c5dff60aSchristos { 181c5dff60aSchristos SI ahi = GETHIDI (a); 182c5dff60aSchristos SI alo = GETLODI (a); 183c5dff60aSchristos SI bhi = GETHIDI (b); 184c5dff60aSchristos SI blo = GETLODI (b); 185c5dff60aSchristos return MAKEDI (ahi | bhi, alo | blo); 186c5dff60aSchristos } 187c5dff60aSchristos 188c5dff60aSchristos DI 189c5dff60aSchristos ADDDI (a, b) 190c5dff60aSchristos DI a, b; 191c5dff60aSchristos { 192c5dff60aSchristos USI ahi = GETHIDI (a); 193c5dff60aSchristos USI alo = GETLODI (a); 194c5dff60aSchristos USI bhi = GETHIDI (b); 195c5dff60aSchristos USI blo = GETLODI (b); 196c5dff60aSchristos USI x = alo + blo; 197c5dff60aSchristos return MAKEDI (ahi + bhi + (x < alo), x); 198c5dff60aSchristos } 199c5dff60aSchristos 200c5dff60aSchristos DI 201c5dff60aSchristos MULDI (a, b) 202c5dff60aSchristos DI a, b; 203c5dff60aSchristos { 204c5dff60aSchristos USI ahi = GETHIDI (a); 205c5dff60aSchristos USI alo = GETLODI (a); 206c5dff60aSchristos USI bhi = GETHIDI (b); 207c5dff60aSchristos USI blo = GETLODI (b); 208c5dff60aSchristos USI rhi,rlo; 209c5dff60aSchristos USI x0, x1, x2, x3; 210c5dff60aSchristos 211c5dff60aSchristos x0 = alo * blo; 212c5dff60aSchristos x1 = alo * bhi; 213c5dff60aSchristos x2 = ahi * blo; 214c5dff60aSchristos x3 = ahi * bhi; 215c5dff60aSchristos 216c5dff60aSchristos #define SI_TYPE_SIZE 32 217c5dff60aSchristos #define BITS4 (SI_TYPE_SIZE / 4) 218c5dff60aSchristos #define ll_B (1L << (SI_TYPE_SIZE / 2)) 219c5dff60aSchristos #define ll_lowpart(t) ((USI) (t) % ll_B) 220c5dff60aSchristos #define ll_highpart(t) ((USI) (t) / ll_B) 221c5dff60aSchristos x1 += ll_highpart (x0); /* this can't give carry */ 222c5dff60aSchristos x1 += x2; /* but this indeed can */ 223c5dff60aSchristos if (x1 < x2) /* did we get it? */ 224c5dff60aSchristos x3 += ll_B; /* yes, add it in the proper pos. */ 225c5dff60aSchristos 226c5dff60aSchristos rhi = x3 + ll_highpart (x1); 227c5dff60aSchristos rlo = ll_lowpart (x1) * ll_B + ll_lowpart (x0); 228c5dff60aSchristos return MAKEDI (rhi + (alo * bhi) + (ahi * blo), rlo); 229c5dff60aSchristos } 230c5dff60aSchristos 231c5dff60aSchristos DI 232c5dff60aSchristos SHLDI (val, shift) 233c5dff60aSchristos DI val; 234c5dff60aSchristos SI shift; 235c5dff60aSchristos { 236c5dff60aSchristos USI hi = GETHIDI (val); 237c5dff60aSchristos USI lo = GETLODI (val); 238c5dff60aSchristos /* FIXME: Need to worry about shift < 0 || shift >= 32. */ 239c5dff60aSchristos return MAKEDI ((hi << shift) | (lo >> (32 - shift)), lo << shift); 240c5dff60aSchristos } 241c5dff60aSchristos 242c5dff60aSchristos DI 243c5dff60aSchristos SLADI (val, shift) 244c5dff60aSchristos DI val; 245c5dff60aSchristos SI shift; 246c5dff60aSchristos { 247c5dff60aSchristos SI hi = GETHIDI (val); 248c5dff60aSchristos USI lo = GETLODI (val); 249c5dff60aSchristos /* FIXME: Need to worry about shift < 0 || shift >= 32. */ 250c5dff60aSchristos return MAKEDI ((hi << shift) | (lo >> (32 - shift)), lo << shift); 251c5dff60aSchristos } 252c5dff60aSchristos 253c5dff60aSchristos DI 254c5dff60aSchristos SRADI (val, shift) 255c5dff60aSchristos DI val; 256c5dff60aSchristos SI shift; 257c5dff60aSchristos { 258c5dff60aSchristos SI hi = GETHIDI (val); 259c5dff60aSchristos USI lo = GETLODI (val); 260c5dff60aSchristos /* We use SRASI because the result is implementation defined if hi < 0. */ 261c5dff60aSchristos /* FIXME: Need to worry about shift < 0 || shift >= 32. */ 262c5dff60aSchristos return MAKEDI (SRASI (hi, shift), (hi << (32 - shift)) | (lo >> shift)); 263c5dff60aSchristos } 264c5dff60aSchristos 265c5dff60aSchristos int 266c5dff60aSchristos GEDI (a, b) 267c5dff60aSchristos DI a, b; 268c5dff60aSchristos { 269c5dff60aSchristos SI ahi = GETHIDI (a); 270c5dff60aSchristos USI alo = GETLODI (a); 271c5dff60aSchristos SI bhi = GETHIDI (b); 272c5dff60aSchristos USI blo = GETLODI (b); 273c5dff60aSchristos if (ahi > bhi) 274c5dff60aSchristos return 1; 275c5dff60aSchristos if (ahi == bhi) 276c5dff60aSchristos return alo >= blo; 277c5dff60aSchristos return 0; 278c5dff60aSchristos } 279c5dff60aSchristos 280c5dff60aSchristos int 281c5dff60aSchristos LEDI (a, b) 282c5dff60aSchristos DI a, b; 283c5dff60aSchristos { 284c5dff60aSchristos SI ahi = GETHIDI (a); 285c5dff60aSchristos USI alo = GETLODI (a); 286c5dff60aSchristos SI bhi = GETHIDI (b); 287c5dff60aSchristos USI blo = GETLODI (b); 288c5dff60aSchristos if (ahi < bhi) 289c5dff60aSchristos return 1; 290c5dff60aSchristos if (ahi == bhi) 291c5dff60aSchristos return alo <= blo; 292c5dff60aSchristos return 0; 293c5dff60aSchristos } 294c5dff60aSchristos 295c5dff60aSchristos DI 296c5dff60aSchristos CONVHIDI (val) 297c5dff60aSchristos HI val; 298c5dff60aSchristos { 299c5dff60aSchristos if (val < 0) 300c5dff60aSchristos return MAKEDI (-1, val); 301c5dff60aSchristos else 302c5dff60aSchristos return MAKEDI (0, val); 303c5dff60aSchristos } 304c5dff60aSchristos 305c5dff60aSchristos DI 306c5dff60aSchristos CONVSIDI (val) 307c5dff60aSchristos SI val; 308c5dff60aSchristos { 309c5dff60aSchristos if (val < 0) 310c5dff60aSchristos return MAKEDI (-1, val); 311c5dff60aSchristos else 312c5dff60aSchristos return MAKEDI (0, val); 313c5dff60aSchristos } 314c5dff60aSchristos 315c5dff60aSchristos SI 316c5dff60aSchristos CONVDISI (val) 317c5dff60aSchristos DI val; 318c5dff60aSchristos { 319c5dff60aSchristos return GETLODI (val); 320c5dff60aSchristos } 321c5dff60aSchristos 322c5dff60aSchristos #endif /* DI_FN_SUPPORT */ 323c5dff60aSchristos 324c5dff60aSchristos QI 325c5dff60aSchristos RORQI (val, shift) 326c5dff60aSchristos QI val; 327c5dff60aSchristos int shift; 328c5dff60aSchristos { 329c5dff60aSchristos if (shift != 0) 330c5dff60aSchristos { 331c5dff60aSchristos int remain = 8 - shift; 332c5dff60aSchristos int mask = (1 << shift) - 1; 333c5dff60aSchristos QI result = (val & mask) << remain; 334c5dff60aSchristos mask = (1 << remain) - 1; 335c5dff60aSchristos result |= (val >> shift) & mask; 336c5dff60aSchristos return result; 337c5dff60aSchristos } 338c5dff60aSchristos return val; 339c5dff60aSchristos } 340c5dff60aSchristos 341c5dff60aSchristos QI 342c5dff60aSchristos ROLQI (val, shift) 343c5dff60aSchristos QI val; 344c5dff60aSchristos int shift; 345c5dff60aSchristos { 346c5dff60aSchristos if (shift != 0) 347c5dff60aSchristos { 348c5dff60aSchristos int remain = 8 - shift; 349c5dff60aSchristos int mask = (1 << remain) - 1; 350c5dff60aSchristos QI result = (val & mask) << shift; 351c5dff60aSchristos mask = (1 << shift) - 1; 352c5dff60aSchristos result |= (val >> remain) & mask; 353c5dff60aSchristos return result; 354c5dff60aSchristos } 355c5dff60aSchristos return val; 356c5dff60aSchristos } 357c5dff60aSchristos 358c5dff60aSchristos HI 359c5dff60aSchristos RORHI (val, shift) 360c5dff60aSchristos HI val; 361c5dff60aSchristos int shift; 362c5dff60aSchristos { 363c5dff60aSchristos if (shift != 0) 364c5dff60aSchristos { 365c5dff60aSchristos int remain = 16 - shift; 366c5dff60aSchristos int mask = (1 << shift) - 1; 367c5dff60aSchristos HI result = (val & mask) << remain; 368c5dff60aSchristos mask = (1 << remain) - 1; 369c5dff60aSchristos result |= (val >> shift) & mask; 370c5dff60aSchristos return result; 371c5dff60aSchristos } 372c5dff60aSchristos return val; 373c5dff60aSchristos } 374c5dff60aSchristos 375c5dff60aSchristos HI 376c5dff60aSchristos ROLHI (val, shift) 377c5dff60aSchristos HI val; 378c5dff60aSchristos int shift; 379c5dff60aSchristos { 380c5dff60aSchristos if (shift != 0) 381c5dff60aSchristos { 382c5dff60aSchristos int remain = 16 - shift; 383c5dff60aSchristos int mask = (1 << remain) - 1; 384c5dff60aSchristos HI result = (val & mask) << shift; 385c5dff60aSchristos mask = (1 << shift) - 1; 386c5dff60aSchristos result |= (val >> remain) & mask; 387c5dff60aSchristos return result; 388c5dff60aSchristos } 389c5dff60aSchristos return val; 390c5dff60aSchristos } 391c5dff60aSchristos 392c5dff60aSchristos SI 393c5dff60aSchristos RORSI (val, shift) 394c5dff60aSchristos SI val; 395c5dff60aSchristos int shift; 396c5dff60aSchristos { 397c5dff60aSchristos if (shift != 0) 398c5dff60aSchristos { 399c5dff60aSchristos int remain = 32 - shift; 400c5dff60aSchristos int mask = (1 << shift) - 1; 401c5dff60aSchristos SI result = (val & mask) << remain; 402c5dff60aSchristos mask = (1 << remain) - 1; 403c5dff60aSchristos result |= (val >> shift) & mask; 404c5dff60aSchristos return result; 405c5dff60aSchristos } 406c5dff60aSchristos return val; 407c5dff60aSchristos } 408c5dff60aSchristos 409c5dff60aSchristos SI 410c5dff60aSchristos ROLSI (val, shift) 411c5dff60aSchristos SI val; 412c5dff60aSchristos int shift; 413c5dff60aSchristos { 414c5dff60aSchristos if (shift != 0) 415c5dff60aSchristos { 416c5dff60aSchristos int remain = 32 - shift; 417c5dff60aSchristos int mask = (1 << remain) - 1; 418c5dff60aSchristos SI result = (val & mask) << shift; 419c5dff60aSchristos mask = (1 << shift) - 1; 420c5dff60aSchristos result |= (val >> remain) & mask; 421c5dff60aSchristos return result; 422c5dff60aSchristos } 423c5dff60aSchristos 424c5dff60aSchristos return val; 425c5dff60aSchristos } 426c5dff60aSchristos 427c5dff60aSchristos /* Emit an error message from CGEN RTL. */ 428c5dff60aSchristos 429c5dff60aSchristos void 430c5dff60aSchristos cgen_rtx_error (SIM_CPU *cpu, const char * msg) 431c5dff60aSchristos { 432c5dff60aSchristos SIM_DESC sd = CPU_STATE (cpu); 433c5dff60aSchristos 434c5dff60aSchristos sim_io_printf (sd, msg); 435c5dff60aSchristos sim_io_printf (sd, "\n"); 436c5dff60aSchristos 437c5dff60aSchristos sim_engine_halt (sd, cpu, NULL, CIA_GET (cpu), sim_stopped, SIM_SIGTRAP); 438c5dff60aSchristos } 439