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

  1. #include    "register.h"
  2. #include    "symtab.h"
  3. #include    "diblock.h"
  4. #include    "instrn.h"
  5. #include    "process.h"
  6. #include    "wcache.h"
  7.  
  8. /*
  9.  * TODO -- big-endian v. little-endian.
  10.  */
  11.  
  12. #define    quiet_procmput_word(dipc,offset,w,n,S) \
  13. { \
  14.     int        i; \
  15.     unsigned long    *wp; \
  16.  \
  17.     if ((i = offset - P.p_data_region_min) >= 0) \
  18.     { \
  19.         if (n == sizeof(int)) \
  20.         { \
  21.             if (offset <= P.p_data_region_wlimit) \
  22.             { \
  23.                 wp = (unsigned long *)&P.p_data_region[i]; \
  24.                 *wp = w; \
  25.                 S; \
  26.                 return dipc; \
  27.             } \
  28.         } \
  29.         else if (n == sizeof(short)) \
  30.         { \
  31.             if (offset <= P.p_data_region_limit + 1 - n) \
  32.             { \
  33.                 *(unsigned short *)&P.p_data_region[i] = w; \
  34.                 return dipc; \
  35.             } \
  36.         } \
  37.         else \
  38.         { \
  39.             if (offset <= P.p_data_region_limit) \
  40.             { \
  41.                 *(unsigned char *)&P.p_data_region[i] = w; \
  42.                 return dipc; \
  43.             } \
  44.         } \
  45.  \
  46.         if (offset <= STACK_WMAX) \
  47.         { \
  48.             if ((i = offset - P.p_stack_region_min) < 0) \
  49.             { \
  50.                 (void)proc_grow_stack(dipc, offset); \
  51.  \
  52.                 i = offset - P.p_stack_region_min; \
  53.             } \
  54.  \
  55.             if (n == sizeof(int)) \
  56.             { \
  57.                 wp = (unsigned long *)&P.p_stack_region[i]; \
  58.                 *wp = w; \
  59.                 S; \
  60.             } \
  61.             else if (n == sizeof(short)) \
  62.                 *(unsigned short *)&P.p_stack_region[i] = w; \
  63.             else \
  64.                 *(unsigned char *)&P.p_stack_region[i] = w; \
  65.  \
  66.             return dipc; \
  67.         } \
  68.     } \
  69.  \
  70.     (void)quiet_procmput(dipc, offset, (unsigned char *)&w, n); \
  71.     return dipc; \
  72. }
  73.  
  74. static
  75. dinstrn    *
  76. c_sb(dipc)
  77. dinstrn    *dipc;
  78. {
  79.     unsigned long    addr;
  80.     unsigned char    c;
  81.  
  82.     addr = *dipc->di_1 + (long)dipc->di_2;
  83.     c = *dipc->di_0;
  84.  
  85.     quiet_procmput_word(dipc, addr, c, sizeof(c), ;);
  86. }
  87.  
  88. dinstrn    *
  89. i_sb(dipc, base, rt, offset)
  90. dinstrn    *dipc;
  91. int    base;
  92. int    rt;
  93. short    offset;
  94. {
  95.     unsigned long    b;
  96.     unsigned long    t;
  97.     unsigned char    c;
  98.  
  99.     if (compile_ok)
  100.     {
  101.         dipc->di_handler = c_sb;
  102.         dipc->di_0 = &P.p_state[rt];
  103.         dipc->di_1 = &P.p_state[base];
  104.         dipc->di_2 = (unsigned long *)(long)offset;
  105.  
  106.         return (*dipc->di_handler)(dipc);
  107.     }
  108.  
  109.     procsget(base, b);
  110.  
  111.     procsget(rt, t);
  112.  
  113.     c = t;
  114.  
  115.     (void)procmput(dipc, b + (long)offset, (char *)&c, sizeof(c));
  116.  
  117.     return dipc;
  118. }
  119.  
  120. static
  121. dinstrn    *
  122. c_sh(dipc)
  123. dinstrn    *dipc;
  124. {
  125.     unsigned long    addr;
  126.     unsigned short    h;
  127.  
  128.     addr = *dipc->di_1 + (long)dipc->di_2;
  129.     h = *dipc->di_0;
  130.  
  131.     check_halfword_align(dipc, addr);
  132.  
  133.     quiet_procmput_word(dipc, addr, h, sizeof(h), ;);
  134. }
  135.  
  136. dinstrn    *
  137. i_sh(dipc, base, rt, offset)
  138. dinstrn    *dipc;
  139. int    base;
  140. int    rt;
  141. short    offset;
  142. {
  143.     unsigned long    b;
  144.     unsigned long    addr;
  145.     unsigned long    t;
  146.     unsigned short    h;
  147.  
  148.     if (compile_ok)
  149.     {
  150.         dipc->di_handler = c_sh;
  151.         dipc->di_0 = &P.p_state[rt];
  152.         dipc->di_1 = &P.p_state[base];
  153.         dipc->di_2 = (unsigned long *)(long)offset;
  154.  
  155.         return (*dipc->di_handler)(dipc);
  156.     }
  157.  
  158.     procsget(base, b);
  159.  
  160.     addr = b + offset;
  161.  
  162.     check_halfword_align(dipc, addr);
  163.  
  164.     procsget(rt, t);
  165.  
  166.     h = t;
  167.  
  168.     (void)procmput(dipc, addr, (char *)&h, sizeof(h));
  169.  
  170.     return dipc;
  171. }
  172.  
  173. static
  174. dinstrn    *
  175. c_sll(dipc)
  176. dinstrn    *dipc;
  177. {
  178.     *dipc->di_0 = *dipc->di_1 << (int)dipc->di_2;
  179.  
  180.     return dipc;
  181. }
  182.  
  183. dinstrn    *
  184. i_sll(dipc, rs, rt, rd, shamt, funct)
  185. dinstrn    *dipc;
  186. int    rs;
  187. int    rt;
  188. int    rd;
  189. int    shamt;
  190. int    funct;
  191. {
  192.     unsigned long    t;
  193.  
  194.     if (compile_ok)
  195.     {
  196.         if (rd == R_0)
  197.             dipc->di_handler = c_noop;
  198.         else
  199.         {
  200.             dipc->di_handler = c_sll;
  201.             dipc->di_0 = &P.p_state[rd];
  202.             dipc->di_1 = &P.p_state[rt];
  203.             dipc->di_2 = (unsigned long *)shamt;
  204.         }
  205.  
  206.         return (*dipc->di_handler)(dipc);
  207.     }
  208.  
  209.     procsget(rt, t);
  210.  
  211.     procsput(rd, t << shamt);
  212.  
  213.     return dipc;
  214. }
  215.  
  216. dinstrn    *
  217. i_sllv(dipc, rs, rt, rd, shamt, funct)
  218. dinstrn    *dipc;
  219. int    rs;
  220. int    rt;
  221. int    rd;
  222. int    shamt;
  223. int    funct;
  224. {
  225.     unsigned long    t;
  226.     unsigned long    s;
  227.  
  228.     procsget(rt, t);
  229.  
  230.     procsget(rs, s);
  231.  
  232.     procsput(rd, t << (s & 0x1F));
  233.  
  234.     return dipc;
  235. }
  236.  
  237. static
  238. dinstrn    *
  239. c_slt(dipc)
  240. dinstrn    *dipc;
  241. {
  242.     *dipc->di_0 = ((long)*dipc->di_1 < (long)*dipc->di_2) ? 1 : 0;
  243.  
  244.     return dipc;
  245. }
  246.  
  247. dinstrn    *
  248. i_slt(dipc, rs, rt, rd, shamt, funct)
  249. dinstrn    *dipc;
  250. int    rs;
  251. int    rt;
  252. int    rd;
  253. int    shamt;
  254. int    funct;
  255. {
  256.     long    s;
  257.     long    t;
  258.  
  259.     if (compile_ok)
  260.     {
  261.         if (rd == R_0)
  262.             dipc->di_handler = c_noop;
  263.         else
  264.         {
  265.             dipc->di_handler = c_slt;
  266.             dipc->di_0 = &P.p_state[rd];
  267.             dipc->di_1 = &P.p_state[rs];
  268.             dipc->di_2 = &P.p_state[rt];
  269.         }
  270.  
  271.         return (*dipc->di_handler)(dipc);
  272.     }
  273.  
  274.     procsget(rs, *(unsigned long *)&s);
  275.  
  276.     procsget(rt, *(unsigned long *)&t);
  277.  
  278.     procsput(rd, (s < t) ? 1 : 0);
  279.  
  280.     return dipc;
  281. }
  282.  
  283. dinstrn    *
  284. i_slti(dipc, rs, rt, immediate)
  285. dinstrn    *dipc;
  286. int    rs;
  287. int    rt;
  288. short    immediate;
  289. {
  290.     long    s;
  291.  
  292.     procsget(rs, *(unsigned long *)&s);
  293.  
  294.     procsput(rt, (s < (long)immediate) ? 1 : 0);
  295.  
  296.     return dipc;
  297. }
  298.  
  299. static
  300. dinstrn    *
  301. c_sltiu(dipc)
  302. dinstrn    *dipc;
  303. {
  304.     *dipc->di_0 = (*dipc->di_1 < (unsigned long)dipc->di_2) ? 1 : 0;
  305.  
  306.     return dipc;
  307. }
  308.  
  309. dinstrn    *
  310. i_sltiu(dipc, rs, rt, immediate)
  311. dinstrn    *dipc;
  312. int    rs;
  313. int    rt;
  314. short    immediate;
  315. {
  316.     unsigned long    s;
  317.     long        i;
  318.     unsigned long    ui;
  319.  
  320.     i = immediate;
  321.     ui = i;
  322.  
  323.     if (compile_ok)
  324.     {
  325.         if (rt == R_0)
  326.             dipc->di_handler = c_noop;
  327.         else
  328.         {
  329.             dipc->di_handler = c_sltiu;
  330.             dipc->di_0 = &P.p_state[rt];
  331.             dipc->di_1 = &P.p_state[rs];
  332.             dipc->di_2 = (unsigned long *)ui;
  333.         }
  334.  
  335.         return (*dipc->di_handler)(dipc);
  336.     }
  337.  
  338.     procsget(rs, s);
  339.  
  340.     procsput(rt, (s < ui) ? 1 : 0);
  341.  
  342.     return dipc;
  343. }
  344.  
  345. static
  346. dinstrn    *
  347. c_sltu(dipc)
  348. dinstrn    *dipc;
  349. {
  350.     *dipc->di_0 = (*dipc->di_1 < *dipc->di_2) ? 1 : 0;
  351.  
  352.     return dipc;
  353. }
  354.  
  355. dinstrn    *
  356. i_sltu(dipc, rs, rt, rd, shamt, funct)
  357. dinstrn    *dipc;
  358. int    rs;
  359. int    rt;
  360. int    rd;
  361. int    shamt;
  362. int    funct;
  363. {
  364.     unsigned long    s;
  365.     unsigned long    t;
  366.  
  367.     if (compile_ok)
  368.     {
  369.         if (rd == R_0)
  370.             dipc->di_handler = c_noop;
  371.         else
  372.         {
  373.             dipc->di_handler = c_sltu;
  374.             dipc->di_0 = &P.p_state[rd];
  375.             dipc->di_1 = &P.p_state[rs];
  376.             dipc->di_2 = &P.p_state[rt];
  377.         }
  378.  
  379.         return (*dipc->di_handler)(dipc);
  380.     }
  381.  
  382.     procsget(rs, s);
  383.  
  384.     procsget(rt, t);
  385.  
  386.     procsput(rd, (s < t) ? 1 : 0);
  387.  
  388.     return dipc;
  389. }
  390.  
  391. static
  392. dinstrn    *
  393. c_sra(dipc)
  394. dinstrn    *dipc;
  395. {
  396.     *dipc->di_0 = (unsigned long)(((long)*dipc->di_2) >> (int)dipc->di_1);
  397.  
  398.     return dipc;
  399. }
  400.  
  401. dinstrn    *
  402. i_sra(dipc, rs, rt, rd, shamt, funct)
  403. dinstrn    *dipc;
  404. int    rs;
  405. int    rt;
  406. int    rd;
  407. int    shamt;
  408. int    funct;
  409. {
  410.     long    t;
  411.  
  412.     if (compile_ok)
  413.     {
  414.         if (rd == R_0)
  415.             dipc->di_handler = c_noop;
  416.         else
  417.         {
  418.             dipc->di_handler = c_sra;
  419.             dipc->di_0 = &P.p_state[rd];
  420.             dipc->di_1 = (unsigned long *)shamt;
  421.             dipc->di_2 = &P.p_state[rt];
  422.         }
  423.  
  424.         return (*dipc->di_handler)(dipc);
  425.     }
  426.  
  427.     procsget(rt, *(unsigned long *)&t);
  428.  
  429.     procsput(rd, t >> shamt);
  430.  
  431.     return dipc;
  432. }
  433.  
  434. dinstrn    *
  435. i_srav(dipc, rs, rt, rd, shamt, funct)
  436. dinstrn    *dipc;
  437. int    rs;
  438. int    rt;
  439. int    rd;
  440. int    shamt;
  441. int    funct;
  442. {
  443.     long        t;
  444.     unsigned long    s;
  445.  
  446.     procsget(rt, *(unsigned long *)&t);
  447.  
  448.     procsget(rs, s);
  449.  
  450.     procsput(rd, t >> (s & 0x1F));
  451.  
  452.     return dipc;
  453. }
  454.  
  455. dinstrn    *
  456. i_srl(dipc, rs, rt, rd, shamt, funct)
  457. dinstrn    *dipc;
  458. int    rs;
  459. int    rt;
  460. int    rd;
  461. int    shamt;
  462. int    funct;
  463. {
  464.     unsigned long    t;
  465.  
  466.     procsget(rt, t);
  467.  
  468.     procsput(rd, t >> shamt);
  469.  
  470.     return dipc;
  471. }
  472.  
  473. dinstrn    *
  474. i_srlv(dipc, rs, rt, rd, shamt, funct)
  475. dinstrn    *dipc;
  476. int    rs;
  477. int    rt;
  478. int    rd;
  479. int    shamt;
  480. int    funct;
  481. {
  482.     unsigned long    t;
  483.     unsigned long    s;
  484.  
  485.     procsget(rt, t);
  486.  
  487.     procsget(rs, s);
  488.  
  489.     procsput(rd, t >> (s & 0x1F));
  490.  
  491.     return dipc;
  492. }
  493.  
  494. dinstrn    *
  495. i_sub(dipc, rs, rt, rd, shamt, funct)
  496. dinstrn    *dipc;
  497. int    rs;
  498. int    rt;
  499. int    rd;
  500. int    shamt;
  501. int    funct;
  502. {
  503.     unsigned long    s;
  504.     unsigned long    t;
  505.  
  506.     procsget(rs, s);
  507.  
  508.     procsget(rt, t);
  509.  
  510.     /*
  511.      * TODO -- overflow exception.
  512.      */
  513.     procsput(rd, s - t);
  514.  
  515.     return dipc;
  516. }
  517.  
  518. dinstrn    *
  519. i_subfmt(dipc, fmt, ft, fs, fd)
  520. dinstrn    *dipc;
  521. int    fmt;
  522. int    ft;
  523. int    fs;
  524. int    fd;
  525. {
  526.     float        singles;
  527.     float        singlet;
  528.     float        singled;
  529.     double        doubles;
  530.     double        doublet;
  531.     double        doubled;
  532.     unsigned long    l[2];
  533.  
  534.     switch (fmt)
  535.     {
  536.     case FMT_SINGLE:
  537.         procsget(CP1G(fs), *(unsigned long *)&singles);
  538.  
  539.         procsget(CP1G(ft), *(unsigned long *)&singlet);
  540.  
  541.         singled = singles - singlet;
  542.  
  543.         procsput(CP1G(fd), *(unsigned long *)&singled);
  544.  
  545.         break;
  546.  
  547.     case FMT_DOUBLE:
  548.         /*
  549.          * Note apparent reversal of words within
  550.          * doubles here -- no idea why.
  551.          */
  552.         procsget(CP1G(fs), *((unsigned long *)&doubles + 1));
  553.  
  554.         procsget(CP1G(fs) + 1, *(unsigned long *)&doubles);
  555.  
  556.         procsget(CP1G(ft), *((unsigned long *)&doublet + 1));
  557.  
  558.         procsget(CP1G(ft) + 1, *(unsigned long *)&doublet);
  559.  
  560.         doubled = doubles - doublet;
  561.  
  562.         procsput(CP1G(fd), *((unsigned long *)&doubled + 1));
  563.  
  564.         procsput(CP1G(fd) + 1, *(unsigned long *)&doubled);
  565.         break;
  566.  
  567.     default:
  568.         unrecognised(dipc);
  569.         break;
  570.     }
  571.  
  572.     return dipc;
  573. }
  574.  
  575. static
  576. dinstrn    *
  577. c_subu(dipc)
  578. dinstrn    *dipc;
  579. {
  580.     *dipc->di_0 = *dipc->di_1 - *dipc->di_2;
  581.  
  582.     return dipc;
  583. }
  584.  
  585. dinstrn    *
  586. i_subu(dipc, rs, rt, rd, shamt, funct)
  587. dinstrn    *dipc;
  588. int    rs;
  589. int    rt;
  590. int    rd;
  591. int    shamt;
  592. int    funct;
  593. {
  594.     unsigned long    s;
  595.     unsigned long    t;
  596.  
  597.     if (compile_ok)
  598.     {
  599.         if (rd == R_0)
  600.             dipc->di_handler = c_noop;
  601.         else
  602.         {
  603.             dipc->di_handler = c_subu;
  604.             dipc->di_0 = &P.p_state[rd];
  605.             dipc->di_1 = &P.p_state[rs];
  606.             dipc->di_2 = &P.p_state[rt];
  607.         }
  608.  
  609.         return (*dipc->di_handler)(dipc);
  610.     }
  611.  
  612.     procsget(rs, s);
  613.  
  614.     procsget(rt, t);
  615.  
  616.     procsput(rd, s - t);
  617.  
  618.     return dipc;
  619. }
  620.  
  621. static
  622. dinstrn    *
  623. c_sw0(dipc)
  624. dinstrn    *dipc;
  625. {
  626.     unsigned long    addr;
  627.     unsigned long    l;
  628.     cent        *cap;
  629.  
  630.     addr = *dipc->di_1;
  631.     l = *dipc->di_0;
  632.  
  633.     if ((cap = &wcache[addr % CACHEZ])->c_addr == addr)
  634.     {
  635.         *cap->c_ptr = l;
  636.         return dipc;
  637.     }
  638.  
  639.     check_word_align(dipc, addr);
  640.  
  641.     quiet_procmput_word(dipc, addr, l, sizeof(l), cap->c_ptr = wp; cap->c_addr = addr);
  642. }
  643.  
  644. static
  645. dinstrn    *
  646. c_sw4(dipc)
  647. dinstrn    *dipc;
  648. {
  649.     unsigned long    addr;
  650.     unsigned long    l;
  651.     cent        *cap;
  652.  
  653.     addr = *dipc->di_1 + 4;
  654.     l = *dipc->di_0;
  655.  
  656.     if ((cap = &wcache[addr % CACHEZ])->c_addr == addr)
  657.     {
  658.         *cap->c_ptr = l;
  659.         return dipc;
  660.     }
  661.  
  662.     check_word_align(dipc, addr);
  663.  
  664.     quiet_procmput_word(dipc, addr, l, sizeof(l), cap->c_ptr = wp; cap->c_addr = addr);
  665. }
  666.  
  667. static
  668. dinstrn    *
  669. c_sw(dipc)
  670. dinstrn    *dipc;
  671. {
  672.     unsigned long    addr;
  673.     unsigned long    l;
  674.     cent        *cap;
  675.  
  676.     addr = *dipc->di_1 + (long)dipc->di_2;
  677.     l = *dipc->di_0;
  678.  
  679.     if ((cap = &wcache[addr % CACHEZ])->c_addr == addr)
  680.     {
  681.         *cap->c_ptr = l;
  682.         return dipc;
  683.     }
  684.  
  685.     check_word_align(dipc, addr);
  686.  
  687.     quiet_procmput_word(dipc, addr, l, sizeof(l), cap->c_ptr = wp; cap->c_addr = addr);
  688. }
  689.  
  690. dinstrn    *
  691. i_sw(dipc, base, rt, offset)
  692. dinstrn    *dipc;
  693. int    base;
  694. int    rt;
  695. short    offset;
  696. {
  697.     unsigned long    b;
  698.     unsigned long    addr;
  699.     unsigned long    t;
  700.  
  701.     if (compile_ok)
  702.     {
  703.         switch (offset)
  704.         {
  705.         case 0:
  706.             dipc->di_handler = c_sw0;
  707.             break;
  708.  
  709.         case 4:
  710.             dipc->di_handler = c_sw4;
  711.             break;
  712.  
  713.         default:
  714.             dipc->di_handler = c_sw;
  715.             break;
  716.         }
  717.         dipc->di_0 = &P.p_state[rt];
  718.         dipc->di_1 = &P.p_state[base];
  719.         dipc->di_2 = (unsigned long *)(long)offset;
  720.  
  721.         return (*dipc->di_handler)(dipc);
  722.     }
  723.  
  724.     procsget(base, b);
  725.  
  726.     addr = b + (long)offset;
  727.  
  728.     check_word_align(dipc, addr);
  729.  
  730.     procsget(rt, t);
  731.  
  732.     (void)procmput(dipc, addr, (char *)&t, sizeof(t));
  733.  
  734.     return dipc;
  735. }
  736.  
  737. dinstrn    *
  738. i_swc1(dipc, base, rt, offset)
  739. dinstrn    *dipc;
  740. int    base;
  741. int    rt;
  742. short    offset;
  743. {
  744.     unsigned long    b;
  745.     unsigned long    addr;
  746.     unsigned long    t;
  747.  
  748.     procsget(base, b);
  749.  
  750.     addr = b + (long)offset;
  751.  
  752.     check_word_align(dipc, addr);
  753.  
  754.     procsget(CP1G(rt), t);
  755.  
  756.     (void)procmput(dipc, addr, (char *)&t, sizeof(t));
  757.  
  758.     return dipc;
  759. }
  760.  
  761. dinstrn    *
  762. i_swl(dipc, base, rt, offset)
  763. dinstrn    *dipc;
  764. int    base;
  765. int    rt;
  766. short    offset;
  767. {
  768.     unsigned long    b;
  769.     unsigned long    addr;
  770.     unsigned long    t;
  771.     int        length;
  772.  
  773.     procsget(base, b);
  774.  
  775.     addr = b + (long)offset;
  776.  
  777.     procsget(rt, t);
  778.  
  779.     length = sizeof(t) - (addr - (addr & ~0x3));
  780.  
  781.     (void)procmput(dipc, addr, (char *)&t, length);
  782.  
  783.     return dipc;
  784. }
  785.  
  786. dinstrn    *
  787. i_swr(dipc, base, rt, offset)
  788. dinstrn    *dipc;
  789. int    base;
  790. int    rt;
  791. short    offset;
  792. {
  793.     unsigned long    b;
  794.     unsigned long    addr;
  795.     unsigned long    t;
  796.     int        length;
  797.  
  798.     procsget(base, b);
  799.  
  800.     addr = b + (long)offset;
  801.  
  802.     procsget(rt, t);
  803.  
  804.     length = (addr - (addr & ~0x3)) + 1;
  805.  
  806.     (void)procmput(dipc, addr & ~0x3, ((char *)&t) + (sizeof(t) - length), length);
  807.  
  808.     return dipc;
  809. }
  810.