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