1 /* Simulator for the FT32 processor 2 3 Copyright (C) 2008-2024 Free Software Foundation, Inc. 4 Contributed by FTDI <support@ftdichip.com> 5 6 This file is part of simulators. 7 8 This program is free software; you can redistribute it and/or modify 9 it under the terms of the GNU General Public License as published by 10 the Free Software Foundation; either version 3 of the License, or 11 (at your option) any later version. 12 13 This program is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU General Public License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 20 21 /* This must come before any other includes. */ 22 #include "defs.h" 23 24 #include <fcntl.h> 25 #include <signal.h> 26 #include <stdlib.h> 27 #include <stdint.h> 28 29 #include "bfd.h" 30 #include "sim/callback.h" 31 #include "libiberty.h" 32 #include "sim/sim.h" 33 34 #include "sim-main.h" 35 #include "sim-options.h" 36 #include "sim-signal.h" 37 38 #include "opcode/ft32.h" 39 40 #include "ft32-sim.h" 41 42 /* 43 * FT32 is a Harvard architecture: RAM and code occupy 44 * different address spaces. 45 * 46 * sim and gdb model FT32 memory by adding 0x800000 to RAM 47 * addresses. This means that sim/gdb can treat all addresses 48 * similarly. 49 * 50 * The address space looks like: 51 * 52 * 00000 start of code memory 53 * 3ffff end of code memory 54 * 800000 start of RAM 55 * 80ffff end of RAM 56 */ 57 58 #define RAM_BIAS 0x800000 /* Bias added to RAM addresses. */ 59 60 static unsigned long 61 ft32_extract_unsigned_integer (const unsigned char *addr, int len) 62 { 63 unsigned long retval; 64 unsigned char *p; 65 unsigned char *startaddr = (unsigned char *) addr; 66 unsigned char *endaddr = startaddr + len; 67 68 /* Start at the most significant end of the integer, and work towards 69 the least significant. */ 70 retval = 0; 71 72 for (p = endaddr; p > startaddr;) 73 retval = (retval << 8) | * -- p; 74 75 return retval; 76 } 77 78 static void 79 ft32_store_unsigned_integer (unsigned char *addr, int len, unsigned long val) 80 { 81 unsigned char *p; 82 unsigned char *startaddr = (unsigned char *)addr; 83 unsigned char *endaddr = startaddr + len; 84 85 for (p = startaddr; p < endaddr; p++) 86 { 87 *p = val & 0xff; 88 val >>= 8; 89 } 90 } 91 92 /* 93 * Align EA according to its size DW. 94 * The FT32 ignores the low bit of a 16-bit addresss, 95 * and the low two bits of a 32-bit address. 96 */ 97 static uint32_t ft32_align (uint32_t dw, uint32_t ea) 98 { 99 switch (dw) 100 { 101 case 1: 102 ea &= ~1; 103 break; 104 case 2: 105 ea &= ~3; 106 break; 107 default: 108 break; 109 } 110 return ea; 111 } 112 113 /* Read an item from memory address EA, sized DW. */ 114 static uint32_t 115 ft32_read_item (SIM_DESC sd, int dw, uint32_t ea) 116 { 117 sim_cpu *cpu = STATE_CPU (sd, 0); 118 address_word cia = CPU_PC_GET (cpu); 119 120 ea = ft32_align (dw, ea); 121 122 switch (dw) { 123 case 0: 124 return sim_core_read_aligned_1 (cpu, cia, read_map, ea); 125 case 1: 126 return sim_core_read_aligned_2 (cpu, cia, read_map, ea); 127 case 2: 128 return sim_core_read_aligned_4 (cpu, cia, read_map, ea); 129 default: 130 abort (); 131 } 132 } 133 134 /* Write item V to memory address EA, sized DW. */ 135 static void 136 ft32_write_item (SIM_DESC sd, int dw, uint32_t ea, uint32_t v) 137 { 138 sim_cpu *cpu = STATE_CPU (sd, 0); 139 address_word cia = CPU_PC_GET (cpu); 140 141 ea = ft32_align (dw, ea); 142 143 switch (dw) { 144 case 0: 145 sim_core_write_aligned_1 (cpu, cia, write_map, ea, v); 146 break; 147 case 1: 148 sim_core_write_aligned_2 (cpu, cia, write_map, ea, v); 149 break; 150 case 2: 151 sim_core_write_aligned_4 (cpu, cia, write_map, ea, v); 152 break; 153 default: 154 abort (); 155 } 156 } 157 158 #define ILLEGAL() \ 159 sim_engine_halt (sd, cpu, NULL, insnpc, sim_signalled, SIM_SIGILL) 160 161 static uint32_t cpu_mem_read (SIM_DESC sd, uint32_t dw, uint32_t ea) 162 { 163 sim_cpu *cpu = STATE_CPU (sd, 0); 164 struct ft32_cpu_state *ft32_cpu = FT32_SIM_CPU (cpu); 165 uint32_t insnpc = ft32_cpu->pc; 166 167 ea &= 0x1ffff; 168 if (ea & ~0xffff) 169 { 170 /* Simulate some IO devices */ 171 switch (ea) 172 { 173 case 0x10000: 174 return getchar (); 175 case 0x1fff4: 176 /* Read the simulator cycle timer. */ 177 return ft32_cpu->cycles / 100; 178 default: 179 sim_io_eprintf (sd, "Illegal IO read address %08x, pc %#x\n", 180 ea, insnpc); 181 ILLEGAL (); 182 } 183 } 184 return ft32_read_item (sd, dw, RAM_BIAS + ea); 185 } 186 187 static void cpu_mem_write (SIM_DESC sd, uint32_t dw, uint32_t ea, uint32_t d) 188 { 189 sim_cpu *cpu = STATE_CPU (sd, 0); 190 struct ft32_cpu_state *ft32_cpu = FT32_SIM_CPU (cpu); 191 ea &= 0x1ffff; 192 if (ea & 0x10000) 193 { 194 /* Simulate some IO devices */ 195 switch (ea) 196 { 197 case 0x10000: 198 /* Console output */ 199 putchar (d & 0xff); 200 break; 201 case 0x1fc80: 202 /* Unlock the PM write port */ 203 ft32_cpu->pm_unlock = (d == 0x1337f7d1); 204 break; 205 case 0x1fc84: 206 /* Set the PM write address register */ 207 ft32_cpu->pm_addr = d; 208 break; 209 case 0x1fc88: 210 if (ft32_cpu->pm_unlock) 211 { 212 /* Write to PM. */ 213 ft32_write_item (sd, dw, ft32_cpu->pm_addr, d); 214 ft32_cpu->pm_addr += 4; 215 } 216 break; 217 case 0x1fffc: 218 /* Normal exit. */ 219 sim_engine_halt (sd, cpu, NULL, ft32_cpu->pc, sim_exited, ft32_cpu->regs[0]); 220 break; 221 case 0x1fff8: 222 sim_io_printf (sd, "Debug write %08x\n", d); 223 break; 224 default: 225 sim_io_eprintf (sd, "Unknown IO write %08x to to %08x\n", d, ea); 226 } 227 } 228 else 229 ft32_write_item (sd, dw, RAM_BIAS + ea, d); 230 } 231 232 #define GET_BYTE(ea) cpu_mem_read (sd, 0, (ea)) 233 #define PUT_BYTE(ea, d) cpu_mem_write (sd, 0, (ea), (d)) 234 235 /* LSBS (n) is a mask of the least significant N bits. */ 236 #define LSBS(n) ((1U << (n)) - 1) 237 238 static void ft32_push (SIM_DESC sd, uint32_t v) 239 { 240 sim_cpu *cpu = STATE_CPU (sd, 0); 241 struct ft32_cpu_state *ft32_cpu = FT32_SIM_CPU (cpu); 242 ft32_cpu->regs[FT32_HARD_SP] -= 4; 243 ft32_cpu->regs[FT32_HARD_SP] &= 0xffff; 244 cpu_mem_write (sd, 2, ft32_cpu->regs[FT32_HARD_SP], v); 245 } 246 247 static uint32_t ft32_pop (SIM_DESC sd) 248 { 249 sim_cpu *cpu = STATE_CPU (sd, 0); 250 struct ft32_cpu_state *ft32_cpu = FT32_SIM_CPU (cpu); 251 uint32_t r = cpu_mem_read (sd, 2, ft32_cpu->regs[FT32_HARD_SP]); 252 ft32_cpu->regs[FT32_HARD_SP] += 4; 253 ft32_cpu->regs[FT32_HARD_SP] &= 0xffff; 254 return r; 255 } 256 257 /* Extract the low SIZ bits of N as an unsigned number. */ 258 static int nunsigned (int siz, int n) 259 { 260 return n & LSBS (siz); 261 } 262 263 /* Extract the low SIZ bits of N as a signed number. */ 264 static int nsigned (int siz, int n) 265 { 266 int shift = (sizeof (int) * 8) - siz; 267 return (n << shift) >> shift; 268 } 269 270 /* Signed division N / D, matching hw behavior for (MIN_INT, -1). */ 271 static uint32_t ft32sdiv (uint32_t n, uint32_t d) 272 { 273 if (n == 0x80000000UL && d == 0xffffffffUL) 274 return 0x80000000UL; 275 else 276 return (uint32_t)((int)n / (int)d); 277 } 278 279 /* Signed modulus N % D, matching hw behavior for (MIN_INT, -1). */ 280 static uint32_t ft32smod (uint32_t n, uint32_t d) 281 { 282 if (n == 0x80000000UL && d == 0xffffffffUL) 283 return 0; 284 else 285 return (uint32_t)((int)n % (int)d); 286 } 287 288 /* Circular rotate right N by B bits. */ 289 static uint32_t ror (uint32_t n, uint32_t b) 290 { 291 b &= 31; 292 return (n >> b) | (n << (32 - b)); 293 } 294 295 /* Implement the BINS machine instruction. 296 See FT32 Programmer's Reference for details. */ 297 static uint32_t bins (uint32_t d, uint32_t f, uint32_t len, uint32_t pos) 298 { 299 uint32_t bitmask = LSBS (len) << pos; 300 return (d & ~bitmask) | ((f << pos) & bitmask); 301 } 302 303 /* Implement the FLIP machine instruction. 304 See FT32 Programmer's Reference for details. */ 305 static uint32_t flip (uint32_t x, uint32_t b) 306 { 307 if (b & 1) 308 x = (x & 0x55555555) << 1 | (x & 0xAAAAAAAA) >> 1; 309 if (b & 2) 310 x = (x & 0x33333333) << 2 | (x & 0xCCCCCCCC) >> 2; 311 if (b & 4) 312 x = (x & 0x0F0F0F0F) << 4 | (x & 0xF0F0F0F0) >> 4; 313 if (b & 8) 314 x = (x & 0x00FF00FF) << 8 | (x & 0xFF00FF00) >> 8; 315 if (b & 16) 316 x = (x & 0x0000FFFF) << 16 | (x & 0xFFFF0000) >> 16; 317 return x; 318 } 319 320 static void 321 step_once (SIM_DESC sd) 322 { 323 sim_cpu *cpu = STATE_CPU (sd, 0); 324 struct ft32_cpu_state *ft32_cpu = FT32_SIM_CPU (cpu); 325 uint32_t inst; 326 uint32_t dw; 327 uint32_t cb; 328 uint32_t r_d; 329 uint32_t cr; 330 uint32_t cv; 331 uint32_t bt; 332 uint32_t r_1; 333 uint32_t rimm; 334 uint32_t r_2; 335 uint32_t k20; 336 uint32_t pa; 337 uint32_t aa; 338 uint32_t k16; 339 uint32_t k15; 340 uint32_t al; 341 uint32_t r_1v; 342 uint32_t rimmv; 343 uint32_t bit_pos; 344 uint32_t bit_len; 345 uint32_t upper; 346 uint32_t insnpc; 347 unsigned int sc[2]; 348 int isize; 349 350 inst = ft32_read_item (sd, 2, ft32_cpu->pc); 351 ft32_cpu->cycles += 1; 352 353 if ((STATE_ARCHITECTURE (sd)->mach == bfd_mach_ft32b) 354 && ft32_decode_shortcode (ft32_cpu->pc, inst, sc)) 355 { 356 if ((ft32_cpu->pc & 3) == 0) 357 inst = sc[0]; 358 else 359 inst = sc[1]; 360 isize = 2; 361 } 362 else 363 isize = 4; 364 365 /* Handle "call 8" (which is FT32's "break" equivalent) here. */ 366 if (inst == 0x00340002) 367 { 368 sim_engine_halt (sd, cpu, NULL, 369 ft32_cpu->pc, 370 sim_stopped, SIM_SIGTRAP); 371 goto escape; 372 } 373 374 dw = (inst >> FT32_FLD_DW_BIT) & LSBS (FT32_FLD_DW_SIZ); 375 cb = (inst >> FT32_FLD_CB_BIT) & LSBS (FT32_FLD_CB_SIZ); 376 r_d = (inst >> FT32_FLD_R_D_BIT) & LSBS (FT32_FLD_R_D_SIZ); 377 cr = (inst >> FT32_FLD_CR_BIT) & LSBS (FT32_FLD_CR_SIZ); 378 cv = (inst >> FT32_FLD_CV_BIT) & LSBS (FT32_FLD_CV_SIZ); 379 bt = (inst >> FT32_FLD_BT_BIT) & LSBS (FT32_FLD_BT_SIZ); 380 r_1 = (inst >> FT32_FLD_R_1_BIT) & LSBS (FT32_FLD_R_1_SIZ); 381 rimm = (inst >> FT32_FLD_RIMM_BIT) & LSBS (FT32_FLD_RIMM_SIZ); 382 r_2 = (inst >> FT32_FLD_R_2_BIT) & LSBS (FT32_FLD_R_2_SIZ); 383 k20 = nsigned (20, (inst >> FT32_FLD_K20_BIT) & LSBS (FT32_FLD_K20_SIZ)); 384 pa = (inst >> FT32_FLD_PA_BIT) & LSBS (FT32_FLD_PA_SIZ); 385 aa = (inst >> FT32_FLD_AA_BIT) & LSBS (FT32_FLD_AA_SIZ); 386 k16 = (inst >> FT32_FLD_K16_BIT) & LSBS (FT32_FLD_K16_SIZ); 387 k15 = (inst >> FT32_FLD_K15_BIT) & LSBS (FT32_FLD_K15_SIZ); 388 if (k15 & 0x80) 389 k15 ^= 0x7f00; 390 if (k15 & 0x4000) 391 k15 -= 0x8000; 392 al = (inst >> FT32_FLD_AL_BIT) & LSBS (FT32_FLD_AL_SIZ); 393 394 r_1v = ft32_cpu->regs[r_1]; 395 rimmv = (rimm & 0x400) ? nsigned (10, rimm) : ft32_cpu->regs[rimm & 0x1f]; 396 397 bit_pos = rimmv & 31; 398 bit_len = 0xf & (rimmv >> 5); 399 if (bit_len == 0) 400 bit_len = 16; 401 402 upper = (inst >> 27); 403 404 insnpc = ft32_cpu->pc; 405 ft32_cpu->pc += isize; 406 switch (upper) 407 { 408 case FT32_PAT_TOC: 409 case FT32_PAT_TOCI: 410 { 411 int take = (cr == 3) || ((1 & (ft32_cpu->regs[28 + cr] >> cb)) == cv); 412 if (take) 413 { 414 ft32_cpu->cycles += 1; 415 if (bt) 416 ft32_push (sd, ft32_cpu->pc); /* this is a call. */ 417 if (upper == FT32_PAT_TOC) 418 ft32_cpu->pc = pa << 2; 419 else 420 ft32_cpu->pc = ft32_cpu->regs[r_2]; 421 if (ft32_cpu->pc == 0x8) 422 goto escape; 423 } 424 } 425 break; 426 427 case FT32_PAT_ALUOP: 428 case FT32_PAT_CMPOP: 429 { 430 uint32_t result; 431 switch (al) 432 { 433 case 0x0: result = r_1v + rimmv; break; 434 case 0x1: result = ror (r_1v, rimmv); break; 435 case 0x2: result = r_1v - rimmv; break; 436 case 0x3: result = (r_1v << 10) | (1023 & rimmv); break; 437 case 0x4: result = r_1v & rimmv; break; 438 case 0x5: result = r_1v | rimmv; break; 439 case 0x6: result = r_1v ^ rimmv; break; 440 case 0x7: result = ~(r_1v ^ rimmv); break; 441 case 0x8: result = r_1v << rimmv; break; 442 case 0x9: result = r_1v >> rimmv; break; 443 case 0xa: result = (int32_t)r_1v >> rimmv; break; 444 case 0xb: result = bins (r_1v, rimmv >> 10, bit_len, bit_pos); break; 445 case 0xc: result = nsigned (bit_len, r_1v >> bit_pos); break; 446 case 0xd: result = nunsigned (bit_len, r_1v >> bit_pos); break; 447 case 0xe: result = flip (r_1v, rimmv); break; 448 default: 449 sim_io_eprintf (sd, "Unhandled alu %#x\n", al); 450 ILLEGAL (); 451 } 452 if (upper == FT32_PAT_ALUOP) 453 ft32_cpu->regs[r_d] = result; 454 else 455 { 456 uint32_t dwmask = 0; 457 int dwsiz = 0; 458 int zero; 459 int sign; 460 int ahi; 461 int bhi; 462 int overflow; 463 int carry; 464 int bit; 465 uint64_t ra; 466 uint64_t rb; 467 int above; 468 int greater; 469 int greatereq; 470 471 switch (dw) 472 { 473 case 0: dwsiz = 7; dwmask = 0xffU; break; 474 case 1: dwsiz = 15; dwmask = 0xffffU; break; 475 case 2: dwsiz = 31; dwmask = 0xffffffffU; break; 476 } 477 478 zero = (0 == (result & dwmask)); 479 sign = 1 & (result >> dwsiz); 480 ahi = 1 & (r_1v >> dwsiz); 481 bhi = 1 & (rimmv >> dwsiz); 482 overflow = (sign != ahi) & (ahi == !bhi); 483 bit = (dwsiz + 1); 484 ra = r_1v & dwmask; 485 rb = rimmv & dwmask; 486 switch (al) 487 { 488 case 0x0: carry = 1 & ((ra + rb) >> bit); break; 489 case 0x2: carry = 1 & ((ra - rb) >> bit); break; 490 default: carry = 0; break; 491 } 492 above = (!carry & !zero); 493 greater = (sign == overflow) & !zero; 494 greatereq = (sign == overflow); 495 496 ft32_cpu->regs[r_d] = ( 497 (above << 6) | 498 (greater << 5) | 499 (greatereq << 4) | 500 (sign << 3) | 501 (overflow << 2) | 502 (carry << 1) | 503 (zero << 0)); 504 } 505 } 506 break; 507 508 case FT32_PAT_LDK: 509 ft32_cpu->regs[r_d] = k20; 510 break; 511 512 case FT32_PAT_LPM: 513 ft32_cpu->regs[r_d] = ft32_read_item (sd, dw, pa << 2); 514 ft32_cpu->cycles += 1; 515 break; 516 517 case FT32_PAT_LPMI: 518 ft32_cpu->regs[r_d] = ft32_read_item (sd, dw, ft32_cpu->regs[r_1] + k15); 519 ft32_cpu->cycles += 1; 520 break; 521 522 case FT32_PAT_STA: 523 cpu_mem_write (sd, dw, aa, ft32_cpu->regs[r_d]); 524 break; 525 526 case FT32_PAT_STI: 527 cpu_mem_write (sd, dw, ft32_cpu->regs[r_d] + k15, ft32_cpu->regs[r_1]); 528 break; 529 530 case FT32_PAT_LDA: 531 ft32_cpu->regs[r_d] = cpu_mem_read (sd, dw, aa); 532 ft32_cpu->cycles += 1; 533 break; 534 535 case FT32_PAT_LDI: 536 ft32_cpu->regs[r_d] = cpu_mem_read (sd, dw, ft32_cpu->regs[r_1] + k15); 537 ft32_cpu->cycles += 1; 538 break; 539 540 case FT32_PAT_EXA: 541 { 542 uint32_t tmp; 543 tmp = cpu_mem_read (sd, dw, aa); 544 cpu_mem_write (sd, dw, aa, ft32_cpu->regs[r_d]); 545 ft32_cpu->regs[r_d] = tmp; 546 ft32_cpu->cycles += 1; 547 } 548 break; 549 550 case FT32_PAT_EXI: 551 { 552 uint32_t tmp; 553 tmp = cpu_mem_read (sd, dw, ft32_cpu->regs[r_1] + k15); 554 cpu_mem_write (sd, dw, ft32_cpu->regs[r_1] + k15, ft32_cpu->regs[r_d]); 555 ft32_cpu->regs[r_d] = tmp; 556 ft32_cpu->cycles += 1; 557 } 558 break; 559 560 case FT32_PAT_PUSH: 561 ft32_push (sd, r_1v); 562 break; 563 564 case FT32_PAT_LINK: 565 ft32_push (sd, ft32_cpu->regs[r_d]); 566 ft32_cpu->regs[r_d] = ft32_cpu->regs[FT32_HARD_SP]; 567 ft32_cpu->regs[FT32_HARD_SP] -= k16; 568 ft32_cpu->regs[FT32_HARD_SP] &= 0xffff; 569 break; 570 571 case FT32_PAT_UNLINK: 572 ft32_cpu->regs[FT32_HARD_SP] = ft32_cpu->regs[r_d]; 573 ft32_cpu->regs[FT32_HARD_SP] &= 0xffff; 574 ft32_cpu->regs[r_d] = ft32_pop (sd); 575 break; 576 577 case FT32_PAT_POP: 578 ft32_cpu->cycles += 1; 579 ft32_cpu->regs[r_d] = ft32_pop (sd); 580 break; 581 582 case FT32_PAT_RETURN: 583 ft32_cpu->pc = ft32_pop (sd); 584 break; 585 586 case FT32_PAT_FFUOP: 587 switch (al) 588 { 589 case 0x0: 590 ft32_cpu->regs[r_d] = r_1v / rimmv; 591 break; 592 case 0x1: 593 ft32_cpu->regs[r_d] = r_1v % rimmv; 594 break; 595 case 0x2: 596 ft32_cpu->regs[r_d] = ft32sdiv (r_1v, rimmv); 597 break; 598 case 0x3: 599 ft32_cpu->regs[r_d] = ft32smod (r_1v, rimmv); 600 break; 601 602 case 0x4: 603 { 604 /* strcmp instruction. */ 605 uint32_t a = r_1v; 606 uint32_t b = rimmv; 607 uint32_t i = 0; 608 while ((GET_BYTE (a + i) != 0) && 609 (GET_BYTE (a + i) == GET_BYTE (b + i))) 610 i++; 611 ft32_cpu->regs[r_d] = GET_BYTE (a + i) - GET_BYTE (b + i); 612 } 613 break; 614 615 case 0x5: 616 { 617 /* memcpy instruction. */ 618 uint32_t src = r_1v; 619 uint32_t dst = ft32_cpu->regs[r_d]; 620 uint32_t i; 621 for (i = 0; i < (rimmv & 0x7fff); i++) 622 PUT_BYTE (dst + i, GET_BYTE (src + i)); 623 } 624 break; 625 case 0x6: 626 { 627 /* strlen instruction. */ 628 uint32_t src = r_1v; 629 uint32_t i; 630 for (i = 0; GET_BYTE (src + i) != 0; i++) 631 ; 632 ft32_cpu->regs[r_d] = i; 633 } 634 break; 635 case 0x7: 636 { 637 /* memset instruction. */ 638 uint32_t dst = ft32_cpu->regs[r_d]; 639 uint32_t i; 640 for (i = 0; i < (rimmv & 0x7fff); i++) 641 PUT_BYTE (dst + i, r_1v); 642 } 643 break; 644 case 0x8: 645 ft32_cpu->regs[r_d] = r_1v * rimmv; 646 break; 647 case 0x9: 648 ft32_cpu->regs[r_d] = ((uint64_t)r_1v * (uint64_t)rimmv) >> 32; 649 break; 650 case 0xa: 651 { 652 /* stpcpy instruction. */ 653 uint32_t src = r_1v; 654 uint32_t dst = ft32_cpu->regs[r_d]; 655 uint32_t i; 656 for (i = 0; GET_BYTE (src + i) != 0; i++) 657 PUT_BYTE (dst + i, GET_BYTE (src + i)); 658 PUT_BYTE (dst + i, 0); 659 ft32_cpu->regs[r_d] = dst + i; 660 } 661 break; 662 case 0xe: 663 { 664 /* streamout instruction. */ 665 uint32_t i; 666 uint32_t src = ft32_cpu->regs[r_1]; 667 for (i = 0; i < rimmv; i += (1 << dw)) 668 { 669 cpu_mem_write (sd, 670 dw, 671 ft32_cpu->regs[r_d], 672 cpu_mem_read (sd, dw, src)); 673 src += (1 << dw); 674 } 675 } 676 break; 677 default: 678 sim_io_eprintf (sd, "Unhandled ffu %#x at %08x\n", al, insnpc); 679 ILLEGAL (); 680 } 681 break; 682 683 default: 684 sim_io_eprintf (sd, "Unhandled pattern %d at %08x\n", upper, insnpc); 685 ILLEGAL (); 686 } 687 ft32_cpu->num_i++; 688 689 escape: 690 ; 691 } 692 693 void 694 sim_engine_run (SIM_DESC sd, 695 int next_cpu_nr, /* ignore */ 696 int nr_cpus, /* ignore */ 697 int siggnal) /* ignore */ 698 { 699 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); 700 701 while (1) 702 { 703 step_once (sd); 704 if (sim_events_tick (sd)) 705 sim_events_process (sd); 706 } 707 } 708 709 static uint32_t * 710 ft32_lookup_register (SIM_CPU *cpu, int nr) 711 { 712 /* Handle the register number translation here. 713 * Sim registers are 0-31. 714 * Other tools (gcc, gdb) use: 715 * 0 - fp 716 * 1 - sp 717 * 2 - r0 718 * 31 - cc 719 */ 720 721 struct ft32_cpu_state *ft32_cpu = FT32_SIM_CPU (cpu); 722 723 if ((nr < 0) || (nr > 32)) 724 { 725 sim_io_eprintf (CPU_STATE (cpu), "unknown register %i\n", nr); 726 abort (); 727 } 728 729 switch (nr) 730 { 731 case FT32_FP_REGNUM: 732 return &ft32_cpu->regs[FT32_HARD_FP]; 733 case FT32_SP_REGNUM: 734 return &ft32_cpu->regs[FT32_HARD_SP]; 735 case FT32_CC_REGNUM: 736 return &ft32_cpu->regs[FT32_HARD_CC]; 737 case FT32_PC_REGNUM: 738 return &ft32_cpu->pc; 739 default: 740 return &ft32_cpu->regs[nr - 2]; 741 } 742 } 743 744 static int 745 ft32_reg_store (SIM_CPU *cpu, 746 int rn, 747 const void *memory, 748 int length) 749 { 750 if (0 <= rn && rn <= 32) 751 { 752 if (length == 4) 753 *ft32_lookup_register (cpu, rn) = ft32_extract_unsigned_integer (memory, 4); 754 755 return 4; 756 } 757 else 758 return 0; 759 } 760 761 static int 762 ft32_reg_fetch (SIM_CPU *cpu, 763 int rn, 764 void *memory, 765 int length) 766 { 767 if (0 <= rn && rn <= 32) 768 { 769 if (length == 4) 770 ft32_store_unsigned_integer (memory, 4, *ft32_lookup_register (cpu, rn)); 771 772 return 4; 773 } 774 else 775 return 0; 776 } 777 778 static sim_cia 779 ft32_pc_get (SIM_CPU *cpu) 780 { 781 return FT32_SIM_CPU (cpu)->pc; 782 } 783 784 static void 785 ft32_pc_set (SIM_CPU *cpu, sim_cia newpc) 786 { 787 FT32_SIM_CPU (cpu)->pc = newpc; 788 } 789 790 /* Cover function of sim_state_free to free the cpu buffers as well. */ 791 792 static void 793 free_state (SIM_DESC sd) 794 { 795 if (STATE_MODULES (sd) != NULL) 796 sim_module_uninstall (sd); 797 sim_cpu_free_all (sd); 798 sim_state_free (sd); 799 } 800 801 SIM_DESC 802 sim_open (SIM_OPEN_KIND kind, 803 host_callback *cb, 804 struct bfd *abfd, 805 char * const *argv) 806 { 807 char c; 808 size_t i; 809 SIM_DESC sd = sim_state_alloc (kind, cb); 810 811 /* Set default options before parsing user options. */ 812 current_alignment = STRICT_ALIGNMENT; 813 current_target_byte_order = BFD_ENDIAN_LITTLE; 814 815 /* The cpu data is kept in a separately allocated chunk of memory. */ 816 if (sim_cpu_alloc_all_extra (sd, 0, sizeof (struct ft32_cpu_state)) 817 != SIM_RC_OK) 818 { 819 free_state (sd); 820 return 0; 821 } 822 823 if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK) 824 { 825 free_state (sd); 826 return 0; 827 } 828 829 /* The parser will print an error message for us, so we silently return. */ 830 if (sim_parse_args (sd, argv) != SIM_RC_OK) 831 { 832 free_state (sd); 833 return 0; 834 } 835 836 /* Allocate external memory if none specified by user. 837 Use address 4 here in case the user wanted address 0 unmapped. */ 838 if (sim_core_read_buffer (sd, NULL, read_map, &c, 4, 1) == 0) 839 { 840 sim_do_command (sd, "memory region 0x00000000,0x40000"); 841 sim_do_command (sd, "memory region 0x800000,0x10000"); 842 } 843 844 /* Check for/establish the reference program image. */ 845 if (sim_analyze_program (sd, STATE_PROG_FILE (sd), abfd) != SIM_RC_OK) 846 { 847 free_state (sd); 848 return 0; 849 } 850 851 /* Configure/verify the target byte order and other runtime 852 configuration options. */ 853 if (sim_config (sd) != SIM_RC_OK) 854 { 855 free_state (sd); 856 return 0; 857 } 858 859 if (sim_post_argv_init (sd) != SIM_RC_OK) 860 { 861 free_state (sd); 862 return 0; 863 } 864 865 /* CPU specific initialization. */ 866 for (i = 0; i < MAX_NR_PROCESSORS; ++i) 867 { 868 SIM_CPU *cpu = STATE_CPU (sd, i); 869 870 CPU_REG_FETCH (cpu) = ft32_reg_fetch; 871 CPU_REG_STORE (cpu) = ft32_reg_store; 872 CPU_PC_FETCH (cpu) = ft32_pc_get; 873 CPU_PC_STORE (cpu) = ft32_pc_set; 874 } 875 876 return sd; 877 } 878 879 SIM_RC 880 sim_create_inferior (SIM_DESC sd, 881 struct bfd *abfd, 882 char * const *argv, 883 char * const *env) 884 { 885 uint32_t addr; 886 sim_cpu *cpu = STATE_CPU (sd, 0); 887 struct ft32_cpu_state *ft32_cpu = FT32_SIM_CPU (cpu); 888 host_callback *cb = STATE_CALLBACK (sd); 889 890 /* Set the PC. */ 891 if (abfd != NULL) 892 addr = bfd_get_start_address (abfd); 893 else 894 addr = 0; 895 896 /* Standalone mode (i.e. `run`) will take care of the argv for us in 897 sim_open() -> sim_parse_args(). But in debug mode (i.e. 'target sim' 898 with `gdb`), we need to handle it because the user can change the 899 argv on the fly via gdb's 'run'. */ 900 if (STATE_PROG_ARGV (sd) != argv) 901 { 902 freeargv (STATE_PROG_ARGV (sd)); 903 STATE_PROG_ARGV (sd) = dupargv (argv); 904 } 905 906 if (STATE_PROG_ENVP (sd) != env) 907 { 908 freeargv (STATE_PROG_ENVP (sd)); 909 STATE_PROG_ENVP (sd) = dupargv (env); 910 } 911 912 cb->argv = STATE_PROG_ARGV (sd); 913 cb->envp = STATE_PROG_ENVP (sd); 914 915 ft32_cpu->regs[FT32_HARD_SP] = addr; 916 ft32_cpu->num_i = 0; 917 ft32_cpu->cycles = 0; 918 ft32_cpu->next_tick_cycle = 100000; 919 920 return SIM_RC_OK; 921 } 922