home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume25 / trash / part02 / go.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-03-22  |  8.4 KB  |  447 lines

  1. #include    <stdio.h>
  2. #include    "register.h"
  3. #include    "symtab.h"
  4. #include    "diblock.h"
  5. #include    "instrn.h"
  6. #include    "process.h"
  7. #include    "nels.h"
  8.  
  9. #define    TWOTIMES(s)    s;s
  10. #define    FOURTIMES(s)    TWOTIMES(s);TWOTIMES(s)
  11. #define    EIGHTTIMES(s)    FOURTIMES(s);FOURTIMES(s)
  12. #define    SIXTEENTIMES(s)    EIGHTTIMES(s);EIGHTTIMES(s)
  13.  
  14. extern void        histo_log();
  15. extern void        hist_log();
  16. extern instrn        *getip();
  17. extern char        *say_pg_register();
  18.  
  19. extern FILE        *outfp;
  20. extern int        Bflag;
  21. extern int        Hflag;
  22. extern int        Iflag;
  23. extern int        Nflag;
  24. extern unsigned long    instruction_count;
  25. extern unsigned long    instruction_count_since_last_syscall;
  26. extern int        hist_length;
  27.  
  28. static instrn        *ip;
  29. static unsigned long    i;
  30.  
  31. int            compile_ok;
  32.  
  33. void
  34. unrecognised(dipc)
  35. dinstrn    *dipc;
  36. {
  37.     GLOBALdipc = dipc;
  38.     vcouldnot("execute unrecognised instruction: <0x%x> \"%s\" [p.%s]", i, ip->i_name, ip->i_pageno);
  39. }
  40.  
  41. /*
  42.  * Execute the next instruction.
  43.  */
  44. static
  45. dinstrn    *
  46. i_execute(dipc)
  47. dinstrn    *dipc;
  48. {
  49.     unsigned long    opcodesPC;
  50.     unsigned int    rs;
  51.     unsigned int    rt;
  52.     unsigned int    immediate;
  53.     unsigned long    target;
  54.     unsigned int    rd;
  55.     unsigned int    shamt;
  56.     unsigned int    funct;
  57.     unsigned int    fmt;
  58.     unsigned int    ft;
  59.     unsigned int    fs;
  60.     unsigned int    fd;
  61.  
  62.     /*
  63.      * Signals to be delivered?
  64.      */
  65.     if (sigs_pending > 0)
  66.     {
  67.         dipc = deliver_signal(dipc);
  68.  
  69.         return dipc;
  70.     }
  71.  
  72.     /*
  73.      * Get the current pc.
  74.      */
  75.     opcodesPC = dipc->di_addr;
  76.  
  77.     /*
  78.      * Check for an unaligned pc.
  79.      */
  80.     if ((opcodesPC % 4) != 0)
  81.     {
  82.         GLOBALdipc = dipc;
  83.         vcouldnot("fetch instruction at unaligned address");
  84.         return dipc;
  85.     }
  86.  
  87.     if (Hflag)
  88.         histo_log(opcodesPC);
  89.  
  90.     if (hist_length > 0)
  91.         hist_log(opcodesPC);
  92.  
  93.     /*
  94.      * Put into 'i' the instruction word found
  95.      * at address 'opcodesPC' in the address space of
  96.      * process 'P' and make 'ip' point to
  97.      * a description of that instruction.
  98.      */
  99.     if (procmget(dipc, opcodesPC, (unsigned char *)&i, sizeof(i)) == -1)
  100.         return dipc;
  101.  
  102.     if ((ip = getip(i)) == (instrn *)0)
  103.         return dipc;
  104.  
  105.     /*
  106.      * Now,
  107.      * 'i'  contains a copy of the current instruction,
  108.      * 'ip' points to a description of the current instruction
  109.      *    and
  110.      * 'pc' contains the address of the first byte of the
  111.      *      next instruction.
  112.      */
  113.  
  114.     if (Iflag)
  115.         fprintf(outfp, "\t%s:\t%s\t", proc_text_address(opcodesPC), ip->i_name);
  116.  
  117.     switch (ip->i_format)
  118.     {
  119.     case IF_I:
  120.         /*
  121.          * Immediate.
  122.          */
  123.         rs = i_to_rs(i);
  124.         rt = i_to_rt(i);
  125.         immediate = i_to_immediate(i);
  126.         if (Iflag)
  127.         {
  128.             fprintf(outfp, "rs=%s,", say_pg_register(rs));
  129.             fprintf(outfp, "rt=%s,", say_pg_register(rt));
  130.             fprintf(outfp, "immediate=%d", immediate);
  131.             if (Bflag)
  132.                 fprintf(outfp, "\t[p.%s]", ip->i_pageno);
  133.             fprintf(outfp, "\n");
  134.         }
  135.         dipc = (*(ip->i_handler))(dipc, rs, rt, (short)immediate);
  136.         break;
  137.  
  138.     case IF_I1:
  139.         /*
  140.          * Immediate (cop1).
  141.          */
  142.         immediate = i_to_immediate(i);
  143.         if (Iflag)
  144.         {
  145.             fprintf(outfp, "immediate=%d", immediate);
  146.             if (Bflag)
  147.                 fprintf(outfp, "\t[p.%s]", ip->i_pageno);
  148.             fprintf(outfp, "\n");
  149.         }
  150.         dipc = (*(ip->i_handler))(dipc, (short)immediate);
  151.         break;
  152.  
  153.     case IF_J:
  154.         /*
  155.          * Jump.
  156.          */
  157.         target = i_to_target(i);
  158.         if (Iflag)
  159.         {
  160.             fprintf(outfp, "target=%s", proc_text_address((opcodesPC & 0xF0000000) | (target << 2)));
  161.  
  162.             if (Bflag)
  163.                 fprintf(outfp, "\t[p.%s]", ip->i_pageno);
  164.             fprintf(outfp, "\n");
  165.         }
  166.         dipc = (*(ip->i_handler))(dipc, target);
  167.         break;
  168.  
  169.     case IF_M1:
  170.         /*
  171.          * Move (cop1).
  172.          */
  173.         rt = i_to_rt(i);
  174.         fs = i_to_fs(i);
  175.         if (Iflag)
  176.         {
  177.             fprintf(outfp, "rt=%s,", say_pg_register(rt));
  178.             fprintf(outfp, "fs=%s", say_fg_register(fs));
  179.             if (Bflag)
  180.                 fprintf(outfp, "\t[p.%s]", ip->i_pageno);
  181.             fprintf(outfp, "\n");
  182.         }
  183.         dipc = (*(ip->i_handler))(dipc, rt, fs);
  184.         break;
  185.  
  186.     case IF_C1:
  187.         /*
  188.          * Control (cop1).
  189.          */
  190.         rt = i_to_rt(i);
  191.         fs = i_to_fs(i);
  192.         if (Iflag)
  193.         {
  194.             fprintf(outfp, "rt=%s,", say_pg_register(rt));
  195.             fprintf(outfp, "fs=%s", say_fc_register(fs));
  196.             if (Bflag)
  197.                 fprintf(outfp, "\t[p.%s]", ip->i_pageno);
  198.             fprintf(outfp, "\n");
  199.         }
  200.         dipc = (*(ip->i_handler))(dipc, rt, fs);
  201.         break;
  202.  
  203.     case IF_R:
  204.         /*
  205.          * Register.
  206.          */
  207.         rs = i_to_rs(i);
  208.         rt = i_to_rt(i);
  209.         rd = i_to_rd(i);
  210.         shamt = i_to_shamt(i);
  211.         funct = i_to_funct(i);
  212.         if (Iflag)
  213.         {
  214.             fprintf(outfp, "rs=%s,", say_pg_register(rs));
  215.             fprintf(outfp, "rt=%s,", say_pg_register(rt));
  216.             fprintf(outfp, "rd=%s,", say_pg_register(rd));
  217.             fprintf(outfp, "shamt=%d,funct=%d", shamt, funct);
  218.             if (Bflag)
  219.                 fprintf(outfp, "\t[p.%s]", ip->i_pageno);
  220.             fprintf(outfp, "\n");
  221.         }
  222.         dipc = (*(ip->i_handler))(dipc, rs, rt, rd, shamt, funct);
  223.         break;
  224.  
  225.     case IF_R1:
  226.         /*
  227.          * Register (cop1).
  228.          */
  229.         fmt = i_to_fmt(i);
  230.         ft = i_to_ft(i);
  231.         fs = i_to_fs(i);
  232.         fd = i_to_fd(i);
  233.         if (Iflag)
  234.         {
  235.             fprintf(outfp, "fmt=%d,", fmt);
  236.             fprintf(outfp, "ft=%s,", say_fg_register(ft));
  237.             fprintf(outfp, "fs=%s,", say_fg_register(fs));
  238.             fprintf(outfp, "fd=%s", say_fg_register(fd));
  239.             if (Bflag)
  240.                 fprintf(outfp, "\t[p.%s]", ip->i_pageno);
  241.             fprintf(outfp, "\n");
  242.         }
  243.         dipc = (*(ip->i_handler))(dipc, fmt, ft, fs, fd);
  244.         break;
  245.  
  246.     case IF_U:
  247.     default:
  248.         /*
  249.          * Undefined.
  250.          */
  251.         if (Iflag)
  252.             fprintf(outfp, "\n");
  253.         unrecognised(dipc);
  254.         break;
  255.     }
  256.  
  257.     if (Nflag)
  258.     {
  259.         instruction_count++;
  260.         instruction_count_since_last_syscall++;
  261.     }
  262.  
  263.     return dipc;
  264. }
  265.  
  266. static
  267. dinstrn    *
  268. i_end_of_block(dipc)
  269. dinstrn    *dipc;
  270. {
  271.     dinstrn    *olddipc;
  272.     int    saved_compile_ok;
  273.  
  274.     olddipc = dipc;
  275.  
  276.     saved_compile_ok = compile_ok;
  277.     compile_ok = 0;
  278.  
  279.     dipc = i_execute(dipc);
  280.  
  281.     compile_ok = saved_compile_ok;
  282.  
  283.     if (dipc == olddipc)
  284.     {
  285.         dipc = addr_to_decoded_instrnp(dipc, dipc->di_addr + sizeof(unsigned long));
  286.  
  287.         dipc--;
  288.     }
  289.  
  290.     return dipc;
  291. }
  292.  
  293. static unsigned long    lastpageno;
  294. static unsigned long    lastaddr;
  295. static dinstrn        *lastresult;
  296.  
  297. dinstrn    *
  298. addr_to_decoded_instrnp(dipc, addr)
  299. dinstrn        *dipc;
  300. unsigned long    addr;
  301. {
  302.     unsigned long    pageno;
  303.     diblock        *bp;
  304.  
  305.     if ((pageno = addr / SIMULATED_PAGE_SIZE) == lastpageno)
  306.         return lastresult + ((long)addr - (long)lastaddr) / sizeof(unsigned long);
  307.  
  308.     lastpageno = pageno;
  309.     lastaddr = addr;
  310.  
  311.     if ((bp = addr_to_decoded_block(dipc, addr)) == (diblock *)0)
  312.         return (dinstrn *)0;
  313.  
  314.     if (bp->dib_want_init)
  315.     {
  316.         int        i;
  317.         unsigned long    a;
  318.  
  319.         bp->dib_want_init = 0;
  320.  
  321.         for (i = 0, a = bp->dib_first_addr; i < nels(bp->dib_instrn) - 1; i++, a += sizeof(unsigned long))
  322.         {
  323.             bp->dib_instrn[i].di_handler = i_execute;
  324.             bp->dib_instrn[i].di_addr = a;
  325.         }
  326.  
  327.         bp->dib_instrn[nels(bp->dib_instrn) - 1].di_handler = i_end_of_block;
  328.         bp->dib_instrn[nels(bp->dib_instrn) - 1].di_addr = a;
  329.     }
  330.  
  331.     return lastresult = &bp->dib_instrn[(addr - bp->dib_first_addr) / sizeof(unsigned long)];
  332. }
  333.  
  334. int
  335. clear_decoded_page(dipc, addr, remainderp)
  336. dinstrn        *dipc;
  337. unsigned long    addr;
  338. int        *remainderp;
  339. {
  340.     unsigned long    pageno;
  341.     diblock        *bp;
  342.  
  343.     if ((pageno = addr / SIMULATED_PAGE_SIZE) == lastpageno)
  344.         lastpageno = 0;
  345.  
  346.     if ((bp = addr_to_decoded_block(dipc, addr)) == (diblock *)0)
  347.         return -1;
  348.  
  349.     bp->dib_want_init = 1;
  350.  
  351.     *remainderp = bp->dib_first_addr + SIMULATED_PAGE_SIZE - addr;
  352.  
  353.     return 0;
  354. }
  355.  
  356. int
  357. compile_known_delayed_branch(dipc, target)
  358. dinstrn        *dipc;
  359. unsigned long    target;
  360. {
  361.     dinstrn    *dp;
  362.  
  363.     if ((dp = addr_to_decoded_instrnp(dipc, dipc->di_addr + sizeof(unsigned long))) == (dinstrn *)0)
  364.         return -1;
  365.  
  366.     dipc->di_2 = (unsigned long *)dp;
  367.  
  368.     if ((dipc->di_3 = (unsigned long *)addr_to_decoded_instrnp(dipc, target)) == (unsigned long *)0)
  369.         return -1;
  370.  
  371.     dipc->di_3 = (unsigned long *)(((dinstrn *)dipc->di_3) - 1);
  372.  
  373.     return 0;
  374. }
  375.  
  376. int
  377. compile_unknown_delayed_branch(dipc)
  378. dinstrn    *dipc;
  379. {
  380.     dinstrn    *dp;
  381.  
  382.     if ((dp = addr_to_decoded_instrnp(dipc, dipc->di_addr + sizeof(unsigned long))) == (dinstrn *)0)
  383.         return -1;
  384.  
  385.     dipc->di_1 = (unsigned long *)dp;
  386.  
  387.     return 0;
  388. }
  389.  
  390. dinstrn    *
  391. do_delayed_branch(dipc, target)
  392. dinstrn        *dipc;
  393. unsigned long    target;
  394. {
  395.     dipc = addr_to_decoded_instrnp(dipc, dipc->di_addr + sizeof(unsigned long));
  396.  
  397.     (void)(*dipc->di_handler)(dipc);
  398.  
  399.     dipc = addr_to_decoded_instrnp(dipc, target);
  400.  
  401.     dipc--;
  402.  
  403.     return dipc;
  404. }
  405.  
  406. #if    0
  407. #define    DIPC_TRACE    1
  408. #endif    /* 0 */
  409.  
  410. static
  411. void
  412. interpret(dipc)
  413. dinstrn    *dipc;
  414. {
  415.     for (;;)
  416.     {
  417. #if    DIPC_TRACE
  418. printf("0x%08x: ", dipc);
  419. fflush(stdout);
  420. printf("0x%08x\n", dipc->di_handler);
  421. fflush(stdout);
  422.         dipc = (*dipc->di_handler)(dipc) + 1;
  423. #else    /* DIPC_TRACE */
  424.         SIXTEENTIMES(dipc = (*dipc->di_handler)(dipc) + 1);
  425. #endif    /* DIPC_TRACE */
  426.     }
  427. }
  428.  
  429. /*
  430.  * Commence simulation of the process.
  431.  */
  432. int
  433. go()
  434. {
  435.     dinstrn    *idipc;
  436.  
  437.     if (hist_length > 0 || Bflag || Hflag || Iflag || Mflag || Nflag || Rflag)
  438.         compile_ok = 0;
  439.     else
  440.         compile_ok = 1;
  441.  
  442.     if ((idipc = addr_to_decoded_instrnp((dinstrn *)0, P.p_entry_point)) == (dinstrn *)0)
  443.         return -1;
  444.  
  445.     interpret(idipc);
  446. }
  447.