1 /* Simulator for the moxie processor 2 Copyright (C) 2008-2015 Free Software Foundation, Inc. 3 Contributed by Anthony Green 4 5 This file is part of GDB, the GNU debugger. 6 7 This program is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 3 of the License, or 10 (at your option) any later version. 11 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 19 20 #include "config.h" 21 #include <fcntl.h> 22 #include <signal.h> 23 #include <stdlib.h> 24 #include "sysdep.h" 25 #include <sys/times.h> 26 #include <sys/param.h> 27 #include <netinet/in.h> /* for byte ordering macros */ 28 #include "bfd.h" 29 #include "gdb/callback.h" 30 #include "libiberty.h" 31 #include "gdb/remote-sim.h" 32 33 #include "sim-main.h" 34 #include "sim-base.h" 35 36 typedef int word; 37 typedef unsigned int uword; 38 39 host_callback * callback; 40 41 FILE *tracefile; 42 43 /* Extract the signed 10-bit offset from a 16-bit branch 44 instruction. */ 45 #define INST2OFFSET(o) ((((signed short)((o & ((1<<10)-1))<<6))>>6)<<1) 46 47 #define EXTRACT_WORD(addr) \ 48 ((sim_core_read_aligned_1 (scpu, cia, read_map, addr) << 24) \ 49 + (sim_core_read_aligned_1 (scpu, cia, read_map, addr+1) << 16) \ 50 + (sim_core_read_aligned_1 (scpu, cia, read_map, addr+2) << 8) \ 51 + (sim_core_read_aligned_1 (scpu, cia, read_map, addr+3))) 52 53 #define EXTRACT_OFFSET(addr) \ 54 (unsigned int) \ 55 (((signed short) \ 56 ((sim_core_read_aligned_1 (scpu, cia, read_map, addr) << 8) \ 57 + (sim_core_read_aligned_1 (scpu, cia, read_map, addr+1))) << 16) >> 16) 58 59 unsigned long 60 moxie_extract_unsigned_integer (addr, len) 61 unsigned char * addr; 62 int len; 63 { 64 unsigned long retval; 65 unsigned char * p; 66 unsigned char * startaddr = (unsigned char *)addr; 67 unsigned char * endaddr = startaddr + len; 68 69 if (len > (int) sizeof (unsigned long)) 70 printf ("That operation is not available on integers of more than %d bytes.", 71 sizeof (unsigned long)); 72 73 /* Start at the most significant end of the integer, and work towards 74 the least significant. */ 75 retval = 0; 76 77 for (p = endaddr; p > startaddr;) 78 retval = (retval << 8) | * -- p; 79 80 return retval; 81 } 82 83 void 84 moxie_store_unsigned_integer (addr, len, val) 85 unsigned char * addr; 86 int len; 87 unsigned long val; 88 { 89 unsigned char * p; 90 unsigned char * startaddr = (unsigned char *)addr; 91 unsigned char * endaddr = startaddr + len; 92 93 for (p = endaddr; p > startaddr;) 94 { 95 * -- p = val & 0xff; 96 val >>= 8; 97 } 98 } 99 100 /* moxie register names. */ 101 static const char *reg_names[16] = 102 { "$fp", "$sp", "$r0", "$r1", "$r2", "$r3", "$r4", "$r5", 103 "$r6", "$r7", "$r8", "$r9", "$r10", "$r11", "$r12", "$r13" }; 104 105 /* The machine state. 106 107 This state is maintained in host byte order. The fetch/store 108 register functions must translate between host byte order and the 109 target processor byte order. Keeping this data in target byte 110 order simplifies the register read/write functions. Keeping this 111 data in native order improves the performance of the simulator. 112 Simulation speed is deemed more important. */ 113 114 #define NUM_MOXIE_REGS 17 /* Including PC */ 115 #define NUM_MOXIE_SREGS 256 /* The special registers */ 116 #define PC_REGNO 16 117 118 /* The ordering of the moxie_regset structure is matched in the 119 gdb/config/moxie/tm-moxie.h file in the REGISTER_NAMES macro. */ 120 struct moxie_regset 121 { 122 word regs[NUM_MOXIE_REGS + 1]; /* primary registers */ 123 word sregs[256]; /* special registers */ 124 word cc; /* the condition code reg */ 125 int exception; 126 unsigned long long insts; /* instruction counter */ 127 }; 128 129 #define CC_GT 1<<0 130 #define CC_LT 1<<1 131 #define CC_EQ 1<<2 132 #define CC_GTU 1<<3 133 #define CC_LTU 1<<4 134 135 union 136 { 137 struct moxie_regset asregs; 138 word asints [1]; /* but accessed larger... */ 139 } cpu; 140 141 static char *myname; 142 static SIM_OPEN_KIND sim_kind; 143 static int issue_messages = 0; 144 145 void 146 sim_size (int s) 147 { 148 } 149 150 static void 151 set_initial_gprs () 152 { 153 int i; 154 long space; 155 156 /* Set up machine just out of reset. */ 157 cpu.asregs.regs[PC_REGNO] = 0; 158 159 /* Clean out the register contents. */ 160 for (i = 0; i < NUM_MOXIE_REGS; i++) 161 cpu.asregs.regs[i] = 0; 162 for (i = 0; i < NUM_MOXIE_SREGS; i++) 163 cpu.asregs.sregs[i] = 0; 164 } 165 166 /* Write a 1 byte value to memory. */ 167 168 static void INLINE 169 wbat (sim_cpu *scpu, word pc, word x, word v) 170 { 171 address_word cia = CIA_GET (scpu); 172 173 sim_core_write_aligned_1 (scpu, cia, write_map, x, v); 174 } 175 176 /* Write a 2 byte value to memory. */ 177 178 static void INLINE 179 wsat (sim_cpu *scpu, word pc, word x, word v) 180 { 181 address_word cia = CIA_GET (scpu); 182 183 sim_core_write_aligned_2 (scpu, cia, write_map, x, v); 184 } 185 186 /* Write a 4 byte value to memory. */ 187 188 static void INLINE 189 wlat (sim_cpu *scpu, word pc, word x, word v) 190 { 191 address_word cia = CIA_GET (scpu); 192 193 sim_core_write_aligned_4 (scpu, cia, write_map, x, v); 194 } 195 196 /* Read 2 bytes from memory. */ 197 198 static int INLINE 199 rsat (sim_cpu *scpu, word pc, word x) 200 { 201 address_word cia = CIA_GET (scpu); 202 203 return (sim_core_read_aligned_2 (scpu, cia, read_map, x)); 204 } 205 206 /* Read 1 byte from memory. */ 207 208 static int INLINE 209 rbat (sim_cpu *scpu, word pc, word x) 210 { 211 address_word cia = CIA_GET (scpu); 212 213 return (sim_core_read_aligned_1 (scpu, cia, read_map, x)); 214 } 215 216 /* Read 4 bytes from memory. */ 217 218 static int INLINE 219 rlat (sim_cpu *scpu, word pc, word x) 220 { 221 address_word cia = CIA_GET (scpu); 222 223 return (sim_core_read_aligned_4 (scpu, cia, read_map, x)); 224 } 225 226 #define CHECK_FLAG(T,H) if (tflags & T) { hflags |= H; tflags ^= T; } 227 228 unsigned int 229 convert_target_flags (unsigned int tflags) 230 { 231 unsigned int hflags = 0x0; 232 233 CHECK_FLAG(0x0001, O_WRONLY); 234 CHECK_FLAG(0x0002, O_RDWR); 235 CHECK_FLAG(0x0008, O_APPEND); 236 CHECK_FLAG(0x0200, O_CREAT); 237 CHECK_FLAG(0x0400, O_TRUNC); 238 CHECK_FLAG(0x0800, O_EXCL); 239 CHECK_FLAG(0x2000, O_SYNC); 240 241 if (tflags != 0x0) 242 fprintf (stderr, 243 "Simulator Error: problem converting target open flags for host. 0x%x\n", 244 tflags); 245 246 return hflags; 247 } 248 249 #define TRACE(str) if (tracing) fprintf(tracefile,"0x%08x, %s, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x\n", opc, str, cpu.asregs.regs[0], cpu.asregs.regs[1], cpu.asregs.regs[2], cpu.asregs.regs[3], cpu.asregs.regs[4], cpu.asregs.regs[5], cpu.asregs.regs[6], cpu.asregs.regs[7], cpu.asregs.regs[8], cpu.asregs.regs[9], cpu.asregs.regs[10], cpu.asregs.regs[11], cpu.asregs.regs[12], cpu.asregs.regs[13], cpu.asregs.regs[14], cpu.asregs.regs[15]); 250 251 static int tracing = 0; 252 253 void 254 sim_resume (sd, step, siggnal) 255 SIM_DESC sd; 256 int step, siggnal; 257 { 258 word pc, opc; 259 unsigned long long insts; 260 unsigned short inst; 261 sim_cpu *scpu = STATE_CPU (sd, 0); /* FIXME */ 262 address_word cia = CIA_GET (scpu); 263 264 cpu.asregs.exception = step ? SIGTRAP: 0; 265 pc = cpu.asregs.regs[PC_REGNO]; 266 insts = cpu.asregs.insts; 267 268 /* Run instructions here. */ 269 do 270 { 271 opc = pc; 272 273 /* Fetch the instruction at pc. */ 274 inst = (sim_core_read_aligned_1 (scpu, cia, read_map, pc) << 8) 275 + sim_core_read_aligned_1 (scpu, cia, read_map, pc+1); 276 277 /* Decode instruction. */ 278 if (inst & (1 << 15)) 279 { 280 if (inst & (1 << 14)) 281 { 282 /* This is a Form 3 instruction. */ 283 int opcode = (inst >> 10 & 0xf); 284 285 switch (opcode) 286 { 287 case 0x00: /* beq */ 288 { 289 TRACE("beq"); 290 if (cpu.asregs.cc & CC_EQ) 291 pc += INST2OFFSET(inst); 292 } 293 break; 294 case 0x01: /* bne */ 295 { 296 TRACE("bne"); 297 if (! (cpu.asregs.cc & CC_EQ)) 298 pc += INST2OFFSET(inst); 299 } 300 break; 301 case 0x02: /* blt */ 302 { 303 TRACE("blt"); 304 if (cpu.asregs.cc & CC_LT) 305 pc += INST2OFFSET(inst); 306 } break; 307 case 0x03: /* bgt */ 308 { 309 TRACE("bgt"); 310 if (cpu.asregs.cc & CC_GT) 311 pc += INST2OFFSET(inst); 312 } 313 break; 314 case 0x04: /* bltu */ 315 { 316 TRACE("bltu"); 317 if (cpu.asregs.cc & CC_LTU) 318 pc += INST2OFFSET(inst); 319 } 320 break; 321 case 0x05: /* bgtu */ 322 { 323 TRACE("bgtu"); 324 if (cpu.asregs.cc & CC_GTU) 325 pc += INST2OFFSET(inst); 326 } 327 break; 328 case 0x06: /* bge */ 329 { 330 TRACE("bge"); 331 if (cpu.asregs.cc & (CC_GT | CC_EQ)) 332 pc += INST2OFFSET(inst); 333 } 334 break; 335 case 0x07: /* ble */ 336 { 337 TRACE("ble"); 338 if (cpu.asregs.cc & (CC_LT | CC_EQ)) 339 pc += INST2OFFSET(inst); 340 } 341 break; 342 case 0x08: /* bgeu */ 343 { 344 TRACE("bgeu"); 345 if (cpu.asregs.cc & (CC_GTU | CC_EQ)) 346 pc += INST2OFFSET(inst); 347 } 348 break; 349 case 0x09: /* bleu */ 350 { 351 TRACE("bleu"); 352 if (cpu.asregs.cc & (CC_LTU | CC_EQ)) 353 pc += INST2OFFSET(inst); 354 } 355 break; 356 default: 357 { 358 TRACE("SIGILL3"); 359 cpu.asregs.exception = SIGILL; 360 break; 361 } 362 } 363 } 364 else 365 { 366 /* This is a Form 2 instruction. */ 367 int opcode = (inst >> 12 & 0x3); 368 switch (opcode) 369 { 370 case 0x00: /* inc */ 371 { 372 int a = (inst >> 8) & 0xf; 373 unsigned av = cpu.asregs.regs[a]; 374 unsigned v = (inst & 0xff); 375 376 TRACE("inc"); 377 cpu.asregs.regs[a] = av + v; 378 } 379 break; 380 case 0x01: /* dec */ 381 { 382 int a = (inst >> 8) & 0xf; 383 unsigned av = cpu.asregs.regs[a]; 384 unsigned v = (inst & 0xff); 385 386 TRACE("dec"); 387 cpu.asregs.regs[a] = av - v; 388 } 389 break; 390 case 0x02: /* gsr */ 391 { 392 int a = (inst >> 8) & 0xf; 393 unsigned v = (inst & 0xff); 394 395 TRACE("gsr"); 396 cpu.asregs.regs[a] = cpu.asregs.sregs[v]; 397 } 398 break; 399 case 0x03: /* ssr */ 400 { 401 int a = (inst >> 8) & 0xf; 402 unsigned v = (inst & 0xff); 403 404 TRACE("ssr"); 405 cpu.asregs.sregs[v] = cpu.asregs.regs[a]; 406 } 407 break; 408 default: 409 TRACE("SIGILL2"); 410 cpu.asregs.exception = SIGILL; 411 break; 412 } 413 } 414 } 415 else 416 { 417 /* This is a Form 1 instruction. */ 418 int opcode = inst >> 8; 419 switch (opcode) 420 { 421 case 0x00: /* bad */ 422 opc = opcode; 423 TRACE("SIGILL0"); 424 cpu.asregs.exception = SIGILL; 425 break; 426 case 0x01: /* ldi.l (immediate) */ 427 { 428 int reg = (inst >> 4) & 0xf; 429 430 TRACE("ldi.l"); 431 unsigned int val = EXTRACT_WORD(pc+2); 432 cpu.asregs.regs[reg] = val; 433 pc += 4; 434 } 435 break; 436 case 0x02: /* mov (register-to-register) */ 437 { 438 int dest = (inst >> 4) & 0xf; 439 int src = (inst ) & 0xf; 440 441 TRACE("mov"); 442 cpu.asregs.regs[dest] = cpu.asregs.regs[src]; 443 } 444 break; 445 case 0x03: /* jsra */ 446 { 447 unsigned int fn = EXTRACT_WORD(pc+2); 448 unsigned int sp = cpu.asregs.regs[1]; 449 450 TRACE("jsra"); 451 /* Save a slot for the static chain. */ 452 sp -= 4; 453 454 /* Push the return address. */ 455 sp -= 4; 456 wlat (scpu, opc, sp, pc + 6); 457 458 /* Push the current frame pointer. */ 459 sp -= 4; 460 wlat (scpu, opc, sp, cpu.asregs.regs[0]); 461 462 /* Uncache the stack pointer and set the pc and $fp. */ 463 cpu.asregs.regs[1] = sp; 464 cpu.asregs.regs[0] = sp; 465 pc = fn - 2; 466 } 467 break; 468 case 0x04: /* ret */ 469 { 470 unsigned int sp = cpu.asregs.regs[0]; 471 472 TRACE("ret"); 473 474 /* Pop the frame pointer. */ 475 cpu.asregs.regs[0] = rlat (scpu, opc, sp); 476 sp += 4; 477 478 /* Pop the return address. */ 479 pc = rlat (scpu, opc, sp) - 2; 480 sp += 4; 481 482 /* Skip over the static chain slot. */ 483 sp += 4; 484 485 /* Uncache the stack pointer. */ 486 cpu.asregs.regs[1] = sp; 487 } 488 break; 489 case 0x05: /* add.l */ 490 { 491 int a = (inst >> 4) & 0xf; 492 int b = inst & 0xf; 493 unsigned av = cpu.asregs.regs[a]; 494 unsigned bv = cpu.asregs.regs[b]; 495 496 TRACE("add.l"); 497 cpu.asregs.regs[a] = av + bv; 498 } 499 break; 500 case 0x06: /* push */ 501 { 502 int a = (inst >> 4) & 0xf; 503 int b = inst & 0xf; 504 int sp = cpu.asregs.regs[a] - 4; 505 506 TRACE("push"); 507 wlat (scpu, opc, sp, cpu.asregs.regs[b]); 508 cpu.asregs.regs[a] = sp; 509 } 510 break; 511 case 0x07: /* pop */ 512 { 513 int a = (inst >> 4) & 0xf; 514 int b = inst & 0xf; 515 int sp = cpu.asregs.regs[a]; 516 517 TRACE("pop"); 518 cpu.asregs.regs[b] = rlat (scpu, opc, sp); 519 cpu.asregs.regs[a] = sp + 4; 520 } 521 break; 522 case 0x08: /* lda.l */ 523 { 524 int reg = (inst >> 4) & 0xf; 525 unsigned int addr = EXTRACT_WORD(pc+2); 526 527 TRACE("lda.l"); 528 cpu.asregs.regs[reg] = rlat (scpu, opc, addr); 529 pc += 4; 530 } 531 break; 532 case 0x09: /* sta.l */ 533 { 534 int reg = (inst >> 4) & 0xf; 535 unsigned int addr = EXTRACT_WORD(pc+2); 536 537 TRACE("sta.l"); 538 wlat (scpu, opc, addr, cpu.asregs.regs[reg]); 539 pc += 4; 540 } 541 break; 542 case 0x0a: /* ld.l (register indirect) */ 543 { 544 int src = inst & 0xf; 545 int dest = (inst >> 4) & 0xf; 546 int xv; 547 548 TRACE("ld.l"); 549 xv = cpu.asregs.regs[src]; 550 cpu.asregs.regs[dest] = rlat (scpu, opc, xv); 551 } 552 break; 553 case 0x0b: /* st.l */ 554 { 555 int dest = (inst >> 4) & 0xf; 556 int val = inst & 0xf; 557 558 TRACE("st.l"); 559 wlat (scpu, opc, cpu.asregs.regs[dest], cpu.asregs.regs[val]); 560 } 561 break; 562 case 0x0c: /* ldo.l */ 563 { 564 unsigned int addr = EXTRACT_OFFSET(pc+2); 565 int a = (inst >> 4) & 0xf; 566 int b = inst & 0xf; 567 568 TRACE("ldo.l"); 569 addr += cpu.asregs.regs[b]; 570 cpu.asregs.regs[a] = rlat (scpu, opc, addr); 571 pc += 2; 572 } 573 break; 574 case 0x0d: /* sto.l */ 575 { 576 unsigned int addr = EXTRACT_OFFSET(pc+2); 577 int a = (inst >> 4) & 0xf; 578 int b = inst & 0xf; 579 580 TRACE("sto.l"); 581 addr += cpu.asregs.regs[a]; 582 wlat (scpu, opc, addr, cpu.asregs.regs[b]); 583 pc += 2; 584 } 585 break; 586 case 0x0e: /* cmp */ 587 { 588 int a = (inst >> 4) & 0xf; 589 int b = inst & 0xf; 590 int cc = 0; 591 int va = cpu.asregs.regs[a]; 592 int vb = cpu.asregs.regs[b]; 593 594 TRACE("cmp"); 595 if (va == vb) 596 cc = CC_EQ; 597 else 598 { 599 cc |= (va < vb ? CC_LT : 0); 600 cc |= (va > vb ? CC_GT : 0); 601 cc |= ((unsigned int) va < (unsigned int) vb ? CC_LTU : 0); 602 cc |= ((unsigned int) va > (unsigned int) vb ? CC_GTU : 0); 603 } 604 605 cpu.asregs.cc = cc; 606 } 607 break; 608 case 0x0f: /* nop */ 609 break; 610 case 0x10: /* sex.b */ 611 { 612 int a = (inst >> 4) & 0xf; 613 int b = inst & 0xf; 614 signed char bv = cpu.asregs.regs[b]; 615 616 TRACE("sex.b"); 617 cpu.asregs.regs[a] = (int) bv; 618 } 619 break; 620 case 0x11: /* sex.s */ 621 { 622 int a = (inst >> 4) & 0xf; 623 int b = inst & 0xf; 624 signed short bv = cpu.asregs.regs[b]; 625 626 TRACE("sex.s"); 627 cpu.asregs.regs[a] = (int) bv; 628 } 629 break; 630 case 0x12: /* zex.b */ 631 { 632 int a = (inst >> 4) & 0xf; 633 int b = inst & 0xf; 634 signed char bv = cpu.asregs.regs[b]; 635 636 TRACE("zex.b"); 637 cpu.asregs.regs[a] = (int) bv & 0xff; 638 } 639 break; 640 case 0x13: /* zex.s */ 641 { 642 int a = (inst >> 4) & 0xf; 643 int b = inst & 0xf; 644 signed short bv = cpu.asregs.regs[b]; 645 646 TRACE("zex.s"); 647 cpu.asregs.regs[a] = (int) bv & 0xffff; 648 } 649 break; 650 case 0x14: /* umul.x */ 651 { 652 int a = (inst >> 4) & 0xf; 653 int b = inst & 0xf; 654 unsigned av = cpu.asregs.regs[a]; 655 unsigned bv = cpu.asregs.regs[b]; 656 unsigned long long r = 657 (unsigned long long) av * (unsigned long long) bv; 658 659 TRACE("umul.x"); 660 cpu.asregs.regs[a] = r >> 32; 661 } 662 break; 663 case 0x15: /* mul.x */ 664 { 665 int a = (inst >> 4) & 0xf; 666 int b = inst & 0xf; 667 unsigned av = cpu.asregs.regs[a]; 668 unsigned bv = cpu.asregs.regs[b]; 669 signed long long r = 670 (signed long long) av * (signed long long) bv; 671 672 TRACE("mul.x"); 673 cpu.asregs.regs[a] = r >> 32; 674 } 675 break; 676 case 0x16: /* bad */ 677 case 0x17: /* bad */ 678 case 0x18: /* bad */ 679 { 680 opc = opcode; 681 TRACE("SIGILL0"); 682 cpu.asregs.exception = SIGILL; 683 break; 684 } 685 case 0x19: /* jsr */ 686 { 687 unsigned int fn = cpu.asregs.regs[(inst >> 4) & 0xf]; 688 unsigned int sp = cpu.asregs.regs[1]; 689 690 TRACE("jsr"); 691 692 /* Save a slot for the static chain. */ 693 sp -= 4; 694 695 /* Push the return address. */ 696 sp -= 4; 697 wlat (scpu, opc, sp, pc + 2); 698 699 /* Push the current frame pointer. */ 700 sp -= 4; 701 wlat (scpu, opc, sp, cpu.asregs.regs[0]); 702 703 /* Uncache the stack pointer and set the fp & pc. */ 704 cpu.asregs.regs[1] = sp; 705 cpu.asregs.regs[0] = sp; 706 pc = fn - 2; 707 } 708 break; 709 case 0x1a: /* jmpa */ 710 { 711 unsigned int tgt = EXTRACT_WORD(pc+2); 712 713 TRACE("jmpa"); 714 pc = tgt - 2; 715 } 716 break; 717 case 0x1b: /* ldi.b (immediate) */ 718 { 719 int reg = (inst >> 4) & 0xf; 720 unsigned int val = EXTRACT_WORD(pc+2); 721 722 TRACE("ldi.b"); 723 cpu.asregs.regs[reg] = val; 724 pc += 4; 725 } 726 break; 727 case 0x1c: /* ld.b (register indirect) */ 728 { 729 int src = inst & 0xf; 730 int dest = (inst >> 4) & 0xf; 731 int xv; 732 733 TRACE("ld.b"); 734 xv = cpu.asregs.regs[src]; 735 cpu.asregs.regs[dest] = rbat (scpu, opc, xv); 736 } 737 break; 738 case 0x1d: /* lda.b */ 739 { 740 int reg = (inst >> 4) & 0xf; 741 unsigned int addr = EXTRACT_WORD(pc+2); 742 743 TRACE("lda.b"); 744 cpu.asregs.regs[reg] = rbat (scpu, opc, addr); 745 pc += 4; 746 } 747 break; 748 case 0x1e: /* st.b */ 749 { 750 int dest = (inst >> 4) & 0xf; 751 int val = inst & 0xf; 752 753 TRACE("st.b"); 754 wbat (scpu, opc, cpu.asregs.regs[dest], cpu.asregs.regs[val]); 755 } 756 break; 757 case 0x1f: /* sta.b */ 758 { 759 int reg = (inst >> 4) & 0xf; 760 unsigned int addr = EXTRACT_WORD(pc+2); 761 762 TRACE("sta.b"); 763 wbat (scpu, opc, addr, cpu.asregs.regs[reg]); 764 pc += 4; 765 } 766 break; 767 case 0x20: /* ldi.s (immediate) */ 768 { 769 int reg = (inst >> 4) & 0xf; 770 771 unsigned int val = EXTRACT_WORD(pc+2); 772 773 TRACE("ldi.s"); 774 cpu.asregs.regs[reg] = val; 775 pc += 4; 776 } 777 break; 778 case 0x21: /* ld.s (register indirect) */ 779 { 780 int src = inst & 0xf; 781 int dest = (inst >> 4) & 0xf; 782 int xv; 783 784 TRACE("ld.s"); 785 xv = cpu.asregs.regs[src]; 786 cpu.asregs.regs[dest] = rsat (scpu, opc, xv); 787 } 788 break; 789 case 0x22: /* lda.s */ 790 { 791 int reg = (inst >> 4) & 0xf; 792 unsigned int addr = EXTRACT_WORD(pc+2); 793 794 TRACE("lda.s"); 795 cpu.asregs.regs[reg] = rsat (scpu, opc, addr); 796 pc += 4; 797 } 798 break; 799 case 0x23: /* st.s */ 800 { 801 int dest = (inst >> 4) & 0xf; 802 int val = inst & 0xf; 803 804 TRACE("st.s"); 805 wsat (scpu, opc, cpu.asregs.regs[dest], cpu.asregs.regs[val]); 806 } 807 break; 808 case 0x24: /* sta.s */ 809 { 810 int reg = (inst >> 4) & 0xf; 811 unsigned int addr = EXTRACT_WORD(pc+2); 812 813 TRACE("sta.s"); 814 wsat (scpu, opc, addr, cpu.asregs.regs[reg]); 815 pc += 4; 816 } 817 break; 818 case 0x25: /* jmp */ 819 { 820 int reg = (inst >> 4) & 0xf; 821 822 TRACE("jmp"); 823 pc = cpu.asregs.regs[reg] - 2; 824 } 825 break; 826 case 0x26: /* and */ 827 { 828 int a = (inst >> 4) & 0xf; 829 int b = inst & 0xf; 830 int av, bv; 831 832 TRACE("and"); 833 av = cpu.asregs.regs[a]; 834 bv = cpu.asregs.regs[b]; 835 cpu.asregs.regs[a] = av & bv; 836 } 837 break; 838 case 0x27: /* lshr */ 839 { 840 int a = (inst >> 4) & 0xf; 841 int b = inst & 0xf; 842 int av = cpu.asregs.regs[a]; 843 int bv = cpu.asregs.regs[b]; 844 845 TRACE("lshr"); 846 cpu.asregs.regs[a] = (unsigned) ((unsigned) av >> bv); 847 } 848 break; 849 case 0x28: /* ashl */ 850 { 851 int a = (inst >> 4) & 0xf; 852 int b = inst & 0xf; 853 int av = cpu.asregs.regs[a]; 854 int bv = cpu.asregs.regs[b]; 855 856 TRACE("ashl"); 857 cpu.asregs.regs[a] = av << bv; 858 } 859 break; 860 case 0x29: /* sub.l */ 861 { 862 int a = (inst >> 4) & 0xf; 863 int b = inst & 0xf; 864 unsigned av = cpu.asregs.regs[a]; 865 unsigned bv = cpu.asregs.regs[b]; 866 867 TRACE("sub.l"); 868 cpu.asregs.regs[a] = av - bv; 869 } 870 break; 871 case 0x2a: /* neg */ 872 { 873 int a = (inst >> 4) & 0xf; 874 int b = inst & 0xf; 875 int bv = cpu.asregs.regs[b]; 876 877 TRACE("neg"); 878 cpu.asregs.regs[a] = - bv; 879 } 880 break; 881 case 0x2b: /* or */ 882 { 883 int a = (inst >> 4) & 0xf; 884 int b = inst & 0xf; 885 int av, bv; 886 887 TRACE("or"); 888 av = cpu.asregs.regs[a]; 889 bv = cpu.asregs.regs[b]; 890 cpu.asregs.regs[a] = av | bv; 891 } 892 break; 893 case 0x2c: /* not */ 894 { 895 int a = (inst >> 4) & 0xf; 896 int b = inst & 0xf; 897 int bv = cpu.asregs.regs[b]; 898 899 TRACE("not"); 900 cpu.asregs.regs[a] = 0xffffffff ^ bv; 901 } 902 break; 903 case 0x2d: /* ashr */ 904 { 905 int a = (inst >> 4) & 0xf; 906 int b = inst & 0xf; 907 int av = cpu.asregs.regs[a]; 908 int bv = cpu.asregs.regs[b]; 909 910 TRACE("ashr"); 911 cpu.asregs.regs[a] = av >> bv; 912 } 913 break; 914 case 0x2e: /* xor */ 915 { 916 int a = (inst >> 4) & 0xf; 917 int b = inst & 0xf; 918 int av, bv; 919 920 TRACE("xor"); 921 av = cpu.asregs.regs[a]; 922 bv = cpu.asregs.regs[b]; 923 cpu.asregs.regs[a] = av ^ bv; 924 } 925 break; 926 case 0x2f: /* mul.l */ 927 { 928 int a = (inst >> 4) & 0xf; 929 int b = inst & 0xf; 930 unsigned av = cpu.asregs.regs[a]; 931 unsigned bv = cpu.asregs.regs[b]; 932 933 TRACE("mul.l"); 934 cpu.asregs.regs[a] = av * bv; 935 } 936 break; 937 case 0x30: /* swi */ 938 { 939 unsigned int inum = EXTRACT_WORD(pc+2); 940 941 TRACE("swi"); 942 /* Set the special registers appropriately. */ 943 cpu.asregs.sregs[2] = 3; /* MOXIE_EX_SWI */ 944 cpu.asregs.sregs[3] = inum; 945 switch (inum) 946 { 947 case 0x1: /* SYS_exit */ 948 { 949 cpu.asregs.exception = SIGQUIT; 950 break; 951 } 952 case 0x2: /* SYS_open */ 953 { 954 char fname[1024]; 955 int mode = (int) convert_target_flags ((unsigned) cpu.asregs.regs[3]); 956 int perm = (int) cpu.asregs.regs[4]; 957 int fd = open (fname, mode, perm); 958 sim_core_read_buffer (sd, scpu, read_map, fname, 959 cpu.asregs.regs[2], 1024); 960 /* FIXME - set errno */ 961 cpu.asregs.regs[2] = fd; 962 break; 963 } 964 case 0x4: /* SYS_read */ 965 { 966 int fd = cpu.asregs.regs[2]; 967 unsigned len = (unsigned) cpu.asregs.regs[4]; 968 char *buf = malloc (len); 969 cpu.asregs.regs[2] = read (fd, buf, len); 970 sim_core_write_buffer (sd, scpu, write_map, buf, 971 cpu.asregs.regs[3], len); 972 free (buf); 973 break; 974 } 975 case 0x5: /* SYS_write */ 976 { 977 char *str; 978 /* String length is at 0x12($fp) */ 979 unsigned count, len = (unsigned) cpu.asregs.regs[4]; 980 str = malloc (len); 981 sim_core_read_buffer (sd, scpu, read_map, str, 982 cpu.asregs.regs[3], len); 983 count = write (cpu.asregs.regs[2], str, len); 984 free (str); 985 cpu.asregs.regs[2] = count; 986 break; 987 } 988 case 0xffffffff: /* Linux System Call */ 989 { 990 unsigned int handler = cpu.asregs.sregs[1]; 991 unsigned int sp = cpu.asregs.regs[1]; 992 993 /* Save a slot for the static chain. */ 994 sp -= 4; 995 996 /* Push the return address. */ 997 sp -= 4; 998 wlat (scpu, opc, sp, pc + 6); 999 1000 /* Push the current frame pointer. */ 1001 sp -= 4; 1002 wlat (scpu, opc, sp, cpu.asregs.regs[0]); 1003 1004 /* Uncache the stack pointer and set the fp & pc. */ 1005 cpu.asregs.regs[1] = sp; 1006 cpu.asregs.regs[0] = sp; 1007 pc = handler - 6; 1008 } 1009 default: 1010 break; 1011 } 1012 pc += 4; 1013 } 1014 break; 1015 case 0x31: /* div.l */ 1016 { 1017 int a = (inst >> 4) & 0xf; 1018 int b = inst & 0xf; 1019 int av = cpu.asregs.regs[a]; 1020 int bv = cpu.asregs.regs[b]; 1021 1022 TRACE("div.l"); 1023 cpu.asregs.regs[a] = av / bv; 1024 } 1025 break; 1026 case 0x32: /* udiv.l */ 1027 { 1028 int a = (inst >> 4) & 0xf; 1029 int b = inst & 0xf; 1030 unsigned int av = cpu.asregs.regs[a]; 1031 unsigned int bv = cpu.asregs.regs[b]; 1032 1033 TRACE("udiv.l"); 1034 cpu.asregs.regs[a] = (av / bv); 1035 } 1036 break; 1037 case 0x33: /* mod.l */ 1038 { 1039 int a = (inst >> 4) & 0xf; 1040 int b = inst & 0xf; 1041 int av = cpu.asregs.regs[a]; 1042 int bv = cpu.asregs.regs[b]; 1043 1044 TRACE("mod.l"); 1045 cpu.asregs.regs[a] = av % bv; 1046 } 1047 break; 1048 case 0x34: /* umod.l */ 1049 { 1050 int a = (inst >> 4) & 0xf; 1051 int b = inst & 0xf; 1052 unsigned int av = cpu.asregs.regs[a]; 1053 unsigned int bv = cpu.asregs.regs[b]; 1054 1055 TRACE("umod.l"); 1056 cpu.asregs.regs[a] = (av % bv); 1057 } 1058 break; 1059 case 0x35: /* brk */ 1060 TRACE("brk"); 1061 cpu.asregs.exception = SIGTRAP; 1062 pc -= 2; /* Adjust pc */ 1063 break; 1064 case 0x36: /* ldo.b */ 1065 { 1066 unsigned int addr = EXTRACT_OFFSET(pc+2); 1067 int a = (inst >> 4) & 0xf; 1068 int b = inst & 0xf; 1069 1070 TRACE("ldo.b"); 1071 addr += cpu.asregs.regs[b]; 1072 cpu.asregs.regs[a] = rbat (scpu, opc, addr); 1073 pc += 2; 1074 } 1075 break; 1076 case 0x37: /* sto.b */ 1077 { 1078 unsigned int addr = EXTRACT_OFFSET(pc+2); 1079 int a = (inst >> 4) & 0xf; 1080 int b = inst & 0xf; 1081 1082 TRACE("sto.b"); 1083 addr += cpu.asregs.regs[a]; 1084 wbat (scpu, opc, addr, cpu.asregs.regs[b]); 1085 pc += 2; 1086 } 1087 break; 1088 case 0x38: /* ldo.s */ 1089 { 1090 unsigned int addr = EXTRACT_OFFSET(pc+2); 1091 int a = (inst >> 4) & 0xf; 1092 int b = inst & 0xf; 1093 1094 TRACE("ldo.s"); 1095 addr += cpu.asregs.regs[b]; 1096 cpu.asregs.regs[a] = rsat (scpu, opc, addr); 1097 pc += 2; 1098 } 1099 break; 1100 case 0x39: /* sto.s */ 1101 { 1102 unsigned int addr = EXTRACT_OFFSET(pc+2); 1103 int a = (inst >> 4) & 0xf; 1104 int b = inst & 0xf; 1105 1106 TRACE("sto.s"); 1107 addr += cpu.asregs.regs[a]; 1108 wsat (scpu, opc, addr, cpu.asregs.regs[b]); 1109 pc += 2; 1110 } 1111 break; 1112 default: 1113 opc = opcode; 1114 TRACE("SIGILL1"); 1115 cpu.asregs.exception = SIGILL; 1116 break; 1117 } 1118 } 1119 1120 insts++; 1121 pc += 2; 1122 1123 } while (!cpu.asregs.exception); 1124 1125 /* Hide away the things we've cached while executing. */ 1126 cpu.asregs.regs[PC_REGNO] = pc; 1127 cpu.asregs.insts += insts; /* instructions done ... */ 1128 } 1129 1130 int 1131 sim_write (sd, addr, buffer, size) 1132 SIM_DESC sd; 1133 SIM_ADDR addr; 1134 const unsigned char * buffer; 1135 int size; 1136 { 1137 sim_cpu *scpu = STATE_CPU (sd, 0); /* FIXME */ 1138 1139 sim_core_write_buffer (sd, scpu, write_map, buffer, addr, size); 1140 1141 return size; 1142 } 1143 1144 int 1145 sim_read (sd, addr, buffer, size) 1146 SIM_DESC sd; 1147 SIM_ADDR addr; 1148 unsigned char * buffer; 1149 int size; 1150 { 1151 sim_cpu *scpu = STATE_CPU (sd, 0); /* FIXME */ 1152 1153 sim_core_read_buffer (sd, scpu, read_map, buffer, addr, size); 1154 1155 return size; 1156 } 1157 1158 1159 int 1160 sim_store_register (sd, rn, memory, length) 1161 SIM_DESC sd; 1162 int rn; 1163 unsigned char * memory; 1164 int length; 1165 { 1166 if (rn < NUM_MOXIE_REGS && rn >= 0) 1167 { 1168 if (length == 4) 1169 { 1170 long ival; 1171 1172 /* misalignment safe */ 1173 ival = moxie_extract_unsigned_integer (memory, 4); 1174 cpu.asints[rn] = ival; 1175 } 1176 1177 return 4; 1178 } 1179 else 1180 return 0; 1181 } 1182 1183 int 1184 sim_fetch_register (sd, rn, memory, length) 1185 SIM_DESC sd; 1186 int rn; 1187 unsigned char * memory; 1188 int length; 1189 { 1190 if (rn < NUM_MOXIE_REGS && rn >= 0) 1191 { 1192 if (length == 4) 1193 { 1194 long ival = cpu.asints[rn]; 1195 1196 /* misalignment-safe */ 1197 moxie_store_unsigned_integer (memory, 4, ival); 1198 } 1199 1200 return 4; 1201 } 1202 else 1203 return 0; 1204 } 1205 1206 1207 int 1208 sim_trace (sd) 1209 SIM_DESC sd; 1210 { 1211 if (tracefile == 0) 1212 tracefile = fopen("trace.csv", "wb"); 1213 1214 tracing = 1; 1215 1216 sim_resume (sd, 0, 0); 1217 1218 tracing = 0; 1219 1220 return 1; 1221 } 1222 1223 void 1224 sim_stop_reason (sd, reason, sigrc) 1225 SIM_DESC sd; 1226 enum sim_stop * reason; 1227 int * sigrc; 1228 { 1229 if (cpu.asregs.exception == SIGQUIT) 1230 { 1231 * reason = sim_exited; 1232 * sigrc = cpu.asregs.regs[2]; 1233 } 1234 else 1235 { 1236 * reason = sim_stopped; 1237 * sigrc = cpu.asregs.exception; 1238 } 1239 } 1240 1241 1242 int 1243 sim_stop (sd) 1244 SIM_DESC sd; 1245 { 1246 cpu.asregs.exception = SIGINT; 1247 return 1; 1248 } 1249 1250 1251 void 1252 sim_info (sd, verbose) 1253 SIM_DESC sd; 1254 int verbose; 1255 { 1256 callback->printf_filtered (callback, "\n\n# instructions executed %llu\n", 1257 cpu.asregs.insts); 1258 } 1259 1260 1261 SIM_DESC 1262 sim_open (kind, cb, abfd, argv) 1263 SIM_OPEN_KIND kind; 1264 host_callback * cb; 1265 struct bfd * abfd; 1266 char ** argv; 1267 { 1268 SIM_DESC sd = sim_state_alloc (kind, cb); 1269 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); 1270 1271 if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK) 1272 return 0; 1273 1274 sim_do_command(sd," memory region 0x00000000,0x4000000") ; 1275 sim_do_command(sd," memory region 0xE0000000,0x10000") ; 1276 1277 myname = argv[0]; 1278 callback = cb; 1279 1280 if (kind == SIM_OPEN_STANDALONE) 1281 issue_messages = 1; 1282 1283 set_initial_gprs (); /* Reset the GPR registers. */ 1284 1285 /* Configure/verify the target byte order and other runtime 1286 configuration options. */ 1287 if (sim_config (sd) != SIM_RC_OK) 1288 { 1289 sim_module_uninstall (sd); 1290 return 0; 1291 } 1292 1293 if (sim_post_argv_init (sd) != SIM_RC_OK) 1294 { 1295 /* Uninstall the modules to avoid memory leaks, 1296 file descriptor leaks, etc. */ 1297 sim_module_uninstall (sd); 1298 return 0; 1299 } 1300 1301 return sd; 1302 } 1303 1304 void 1305 sim_close (sd, quitting) 1306 SIM_DESC sd; 1307 int quitting; 1308 { 1309 /* nothing to do */ 1310 } 1311 1312 1313 /* Load the device tree blob. */ 1314 1315 static void 1316 load_dtb (SIM_DESC sd, const char *filename) 1317 { 1318 int size = 0; 1319 FILE *f = fopen (filename, "rb"); 1320 char *buf; 1321 sim_cpu *scpu = STATE_CPU (sd, 0); /* FIXME */ 1322 if (f == NULL) 1323 { 1324 printf ("WARNING: ``%s'' could not be opened.\n", filename); 1325 return; 1326 } 1327 fseek (f, 0, SEEK_END); 1328 size = ftell(f); 1329 fseek (f, 0, SEEK_SET); 1330 buf = alloca (size); 1331 if (size != fread (buf, 1, size, f)) 1332 { 1333 printf ("ERROR: error reading ``%s''.\n", filename); 1334 return; 1335 } 1336 sim_core_write_buffer (sd, scpu, write_map, buf, 0xE0000000, size); 1337 cpu.asregs.sregs[9] = 0xE0000000; 1338 fclose (f); 1339 } 1340 1341 SIM_RC 1342 sim_load (sd, prog, abfd, from_tty) 1343 SIM_DESC sd; 1344 const char * prog; 1345 bfd * abfd; 1346 int from_tty; 1347 { 1348 1349 /* Do the right thing for ELF executables; this turns out to be 1350 just about the right thing for any object format that: 1351 - we crack using BFD routines 1352 - follows the traditional UNIX text/data/bss layout 1353 - calls the bss section ".bss". */ 1354 1355 extern bfd * sim_load_file (); /* ??? Don't know where this should live. */ 1356 bfd * prog_bfd; 1357 1358 { 1359 bfd * handle; 1360 handle = bfd_openr (prog, 0); /* could be "moxie" */ 1361 1362 if (!handle) 1363 { 1364 printf("``%s'' could not be opened.\n", prog); 1365 return SIM_RC_FAIL; 1366 } 1367 1368 /* Makes sure that we have an object file, also cleans gets the 1369 section headers in place. */ 1370 if (!bfd_check_format (handle, bfd_object)) 1371 { 1372 /* wasn't an object file */ 1373 bfd_close (handle); 1374 printf ("``%s'' is not appropriate object file.\n", prog); 1375 return SIM_RC_FAIL; 1376 } 1377 1378 /* Clean up after ourselves. */ 1379 bfd_close (handle); 1380 } 1381 1382 /* from sh -- dac */ 1383 prog_bfd = sim_load_file (sd, myname, callback, prog, abfd, 1384 sim_kind == SIM_OPEN_DEBUG, 1385 0, sim_write); 1386 if (prog_bfd == NULL) 1387 return SIM_RC_FAIL; 1388 1389 if (abfd == NULL) 1390 bfd_close (prog_bfd); 1391 1392 return SIM_RC_OK; 1393 } 1394 1395 SIM_RC 1396 sim_create_inferior (sd, prog_bfd, argv, env) 1397 SIM_DESC sd; 1398 struct bfd * prog_bfd; 1399 char ** argv; 1400 char ** env; 1401 { 1402 char ** avp; 1403 int l, argc, i, tp; 1404 sim_cpu *scpu = STATE_CPU (sd, 0); /* FIXME */ 1405 1406 /* Set the initial register set. */ 1407 l = issue_messages; 1408 issue_messages = 0; 1409 set_initial_gprs (); 1410 issue_messages = l; 1411 1412 if (prog_bfd != NULL) 1413 cpu.asregs.regs[PC_REGNO] = bfd_get_start_address (prog_bfd); 1414 1415 /* Copy args into target memory. */ 1416 avp = argv; 1417 for (argc = 0; avp && *avp; avp++) 1418 argc++; 1419 1420 /* Target memory looks like this: 1421 0x00000000 zero word 1422 0x00000004 argc word 1423 0x00000008 start of argv 1424 . 1425 0x0000???? end of argv 1426 0x0000???? zero word 1427 0x0000???? start of data pointed to by argv */ 1428 1429 wlat (scpu, 0, 0, 0); 1430 wlat (scpu, 0, 4, argc); 1431 1432 /* tp is the offset of our first argv data. */ 1433 tp = 4 + 4 + argc * 4 + 4; 1434 1435 for (i = 0; i < argc; i++) 1436 { 1437 /* Set the argv value. */ 1438 wlat (scpu, 0, 4 + 4 + i * 4, tp); 1439 1440 /* Store the string. */ 1441 sim_core_write_buffer (sd, scpu, write_map, argv[i], 1442 tp, strlen(argv[i])+1); 1443 tp += strlen (argv[i]) + 1; 1444 } 1445 1446 wlat (scpu, 0, 4 + 4 + i * 4, 0); 1447 1448 load_dtb (sd, DTB); 1449 1450 return SIM_RC_OK; 1451 } 1452 1453 void 1454 sim_kill (sd) 1455 SIM_DESC sd; 1456 { 1457 if (tracefile) 1458 fclose(tracefile); 1459 } 1460 1461 void 1462 sim_do_command (sd, cmd) 1463 SIM_DESC sd; 1464 const char *cmd; 1465 { 1466 if (sim_args_command (sd, cmd) != SIM_RC_OK) 1467 sim_io_printf (sd, 1468 "Error: \"%s\" is not a valid moxie simulator command.\n", 1469 cmd); 1470 } 1471 1472 void 1473 sim_set_callbacks (ptr) 1474 host_callback * ptr; 1475 { 1476 callback = ptr; 1477 } 1478