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