home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume35 / dis / part02 / arithmetic.c next >
Encoding:
C/C++ Source or Header  |  1993-02-04  |  7.2 KB  |  312 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include "formats.h"
  5. #include "arithmetic.h"
  6.  
  7. /*
  8.  * Decode integer arithmetic, logical, and shift instructions.
  9.  * Assume pre-allocated buffer "buf" can be filled with text
  10.  * describing the instruction.
  11.  */
  12.  
  13. void
  14. arithmetic(instr, buf)
  15.     unsigned long   instr;
  16.     char           *buf;
  17. {
  18.     struct format3a instr3a;
  19.     struct format3b instr3b;
  20.  
  21.     int             op3_5_4, op3_3_0;
  22.     int             immediate;
  23.     char           *opcode_ptr;
  24.  
  25.     char           *user_mode();
  26.  
  27.  
  28.  
  29.     bcopy((char *) &instr, (char *) &instr3a, 4);
  30.  
  31.     /* trim off op3 <5:4> */
  32.     op3_5_4 = (instr3a.op3 & 0x30) >> 4;
  33.     /* trim off op3 <3:0> */
  34.     op3_3_0 = (instr3a.op3 & 0x0f);
  35.  
  36.     opcode_ptr = table_f_3[op3_3_0][op3_5_4];
  37.  
  38.     if (immediate = instr3a.i)
  39.         bcopy((char *) &instr, (char *) &instr3b, 4);
  40.  
  41.     /* many different output formats: use switch */
  42.     switch (instr3a.op3) {
  43.     case 0x30:
  44.         /* WRASR, WRY */
  45.         if (instr3a.rd) {
  46.             /* WRASR */
  47.             if (immediate) {
  48.                 sprintf(buf, "wr %s, %d, %s ! WRASR", user_mode(instr3a.rs1),
  49.                     SIGN_EXT13(instr3b.simm13),
  50.                     user_mode(instr3a.rd));
  51.             } else {
  52.                 sprintf(buf, "wr %s, %s, %s ! WRASR", user_mode(instr3a.rs1),
  53.                     user_mode(instr3a.rs2), user_mode(instr3a.rd));
  54.             }
  55.         } else {
  56.             /* WRY */
  57.             if (immediate) {
  58.                 sprintf(buf, "wr %s, %d, %%y ! WRY", user_mode(instr3a.rs1),
  59.                     SIGN_EXT13(instr3b.simm13));
  60.  
  61.             } else {
  62.                 sprintf(buf, "wr %s, %s, %%y ! WRY", user_mode(instr3a.rs1),
  63.                     user_mode(instr3a.rs2));
  64.             }
  65.         }
  66.         break;
  67.  
  68.     case 0x31:
  69.         /* WRPSR */
  70.         if (immediate) {
  71.             sprintf(buf, "wr %s, %d, %%psr ! WRPSR", user_mode(instr3a.rs1),
  72.                 SIGN_EXT13(instr3b.simm13));
  73.  
  74.         } else {
  75.             sprintf(buf, "wr %s, %s, %%psr ! WRPSR", user_mode(instr3a.rs1),
  76.                 user_mode(instr3a.rs2));
  77.         }
  78.         break;
  79.  
  80.     case 0x32:
  81.         /* WRWIM */
  82.         if (immediate) {
  83.             sprintf(buf, "wr %s, %d, %%wim ! WRWIM", user_mode(instr3a.rs1),
  84.                 SIGN_EXT13(instr3b.simm13));
  85.  
  86.         } else {
  87.             sprintf(buf, "wr %s, %s, %%wim ! WRWIM", user_mode(instr3a.rs1),
  88.                 user_mode(instr3a.rs2));
  89.         }
  90.         break;
  91.  
  92.     case 0x33:
  93.         /* WRTBR */
  94.         if (immediate) {
  95.             sprintf(buf, "wr %s, %d, %%tbr ! WRTBR", user_mode(instr3a.rs1),
  96.                 SIGN_EXT13(instr3b.simm13));
  97.  
  98.         } else {
  99.             sprintf(buf, "wr %s, %s, %%tbr ! WRTBR", user_mode(instr3a.rs1),
  100.                 user_mode(instr3a.rs2));
  101.         }
  102.         break;
  103.  
  104.     case 0x28:
  105.         /* RDASR, RDY, STBAR */
  106.         if (instr3a.rs1) {
  107.             if (instr3a.rs1 == 15 && instr3a.rd == 0) {
  108.                 strcpy(buf, "stbar");
  109.             } else {
  110.                 sprintf(buf, "rd %s, %s ! RDASR", user_mode(instr3a.rs1),
  111.                     user_mode(instr3a.rd));
  112.             }
  113.         } else {
  114.             sprintf(buf, "rd %%y, %s ! RDY", user_mode(instr3a.rd));
  115.         }
  116.         break;
  117.  
  118.     case 0x29:
  119.         /* RDPSR */
  120.         sprintf(buf, "rd %%psr, %s ! RDPSR", user_mode(instr3a.rd));
  121.         break;
  122.  
  123.     case 0x2a:
  124.         /* RDWIM */
  125.         sprintf(buf, "rd %%wim, %s ! RDWIM", user_mode(instr3a.rd));
  126.         break;
  127.  
  128.     case 0x2b:
  129.         /* RDTBR */
  130.         sprintf(buf, "rd %%tbr, %s ! RDWIM", user_mode(instr3a.rd));
  131.         break;
  132.  
  133.     case 0x38:
  134.         /* JMPL */
  135.         if (immediate) {
  136.             if (instr3a.rs1 > 0) {
  137.                 sprintf(buf, "%s [%s + %d], %s",
  138.                     opcode_ptr, user_mode(instr3a.rs1),
  139.                     SIGN_EXT13(instr3b.simm13),
  140.                     user_mode(instr3a.rd));
  141.             } else {
  142.                 /* %g0 is rs1: ignore it for clarity */
  143.                 sprintf(buf, "%s [%d], %s", opcode_ptr,
  144.                     SIGN_EXT13(instr3b.simm13),
  145.                     user_mode(instr3a.rd));
  146.             }
  147.         } else {
  148.             sprintf(buf, "%s [%s + %s], %s",
  149.                 opcode_ptr, user_mode(instr3a.rs1),
  150.                 user_mode(instr3a.rs2),
  151.                 user_mode(instr3a.rd));
  152.         }
  153.         break;
  154.  
  155.     case 0x39:
  156.         /* RETT */
  157.         if (immediate) {
  158.             if (instr3a.rs1 > 0) {
  159.                 sprintf(buf, "%s [%s + %d]",
  160.                     opcode_ptr, user_mode(instr3a.rs1),
  161.                     SIGN_EXT13(instr3b.simm13));
  162.             } else {
  163.                 /* %g0 is rs1: ignore it for clarity */
  164.                 sprintf(buf, "%s [%d]", opcode_ptr,
  165.                     SIGN_EXT13(instr3b.simm13));
  166.             }
  167.         } else {
  168.             sprintf(buf, "%s [%s + %s]",
  169.                 opcode_ptr, user_mode(instr3a.rs1),
  170.                 user_mode(instr3a.rs2));
  171.         }
  172.         break;
  173.  
  174.     case 0x3b:
  175.         /* FLUSH */
  176.         if (immediate) {
  177.             if (instr3a.rs1 > 0) {
  178.                 sprintf(buf, "%s [%s + %d]",
  179.                     opcode_ptr, user_mode(instr3a.rs1),
  180.                     SIGN_EXT13(instr3b.simm13));
  181.             } else {
  182.                 /* %g0 is rs1: ignore it for clarity */
  183.                 sprintf(buf, "%s [%d]", opcode_ptr,
  184.                     SIGN_EXT13(instr3b.simm13));
  185.             }
  186.         } else {
  187.             sprintf(buf, "%s [%s + %s]",
  188.                 opcode_ptr, user_mode(instr3a.rs1),
  189.                 user_mode(instr3a.rs2));
  190.         }
  191.         break;
  192.  
  193.     case 0x3a:
  194.         /* Ticc */
  195.         opcode_ptr = traps[instr3a.rd & 0x0f];
  196.         if (immediate) {
  197.             if (instr3a.rs1 > 0) {
  198.                 sprintf(buf, "%s %s + %d",
  199.                     opcode_ptr, user_mode(instr3b.rs1),
  200.                     SIGN_EXT13(instr3b.simm13));
  201.             } else {
  202.                 sprintf(buf, "%s %d", opcode_ptr, SIGN_EXT13(instr3b.simm13));
  203.             }
  204.         } else {
  205.             sprintf(buf, "%s %s + %s",
  206.                 opcode_ptr, user_mode(instr3a.rs1),
  207.                 user_mode(instr3a.rs2));
  208.         }
  209.         break;
  210.  
  211.     /* invalid ops or stuff I haven't covered 
  212.      * (floating point and co-processor) */
  213.     case 0x34:
  214.     case 0x35:
  215.     case 0x36:
  216.     case 0x37:
  217.     case 0x09:
  218.     case 0x19:
  219.     case 0x2c:
  220.     case 0x0d:
  221.     case 0x1d:
  222.     case 0x2d:
  223.     case 0x2e:
  224.     case 0x2f:
  225.     case 0x3e:
  226.     case 0x3f:
  227.         strcpy(buf, opcode_ptr);
  228.         break;
  229.  
  230.     default:
  231.         /* most of arithmetic, logical and shift instructions */
  232.  
  233.         /* I am really proud of the nifty use of the "?:" tertiary
  234.          * operator in the next two or three sprintf()s, but lint
  235.          * hates it. */
  236. #ifndef NOSYNTHETIC
  237.         /* some "synthetic" instructions: special cases where %g0 is in it */
  238.         if (instr3a.rd == 0 && instr3a.op3 == 0x14) {
  239.             /* subcc becoming "cmp" */
  240.             sprintf(buf, immediate?"cmp %s, %d":"cmp %s, %s",
  241.                 user_mode(instr3a.rs1),
  242.                 immediate?SIGN_EXT13(instr3b.simm13):user_mode(instr3a.rs2));
  243.             break;
  244.         }
  245.         if (instr3a.rs1 == 0 && instr3a.op3 == 0x02) {
  246.             if (!immediate && instr3a.rs2 == 0) {
  247.                 /* or %g0,%g0,rd becomes clr rd */
  248.                 sprintf(buf, "clr %s", user_mode(instr3a.rd));
  249.             } else {
  250.                 /* or %g0,something,r[rd] turns into mov something, r[rd] */
  251.                 sprintf(buf, immediate?"mov %d, %s":"mov %s, %s",
  252.                     immediate?SIGN_EXT13(instr3b.simm13):user_mode(instr3a.rs2),
  253.                     user_mode(instr3a.rd));
  254.             }
  255.             break;
  256.         }
  257.         /* add rd,simm13,rd becomes inc something,rd */
  258.         if (instr3a.op3 == 0x00
  259.             && immediate 
  260.             && instr3a.rs1 == instr3a.rd) {
  261.             if (instr3b.simm13 == 0x01) {
  262.                 sprintf(buf, "inc %s", user_mode(instr3a.rd));
  263.             } else {
  264.                 sprintf(buf, "inc %d, %s", instr3b.simm13, user_mode(instr3a.rd));
  265.             }
  266.             break;
  267.         }
  268.  
  269.         /* sub rd,simm13,rd becomes dec something,rd */
  270.         if (instr3a.op3 == 0x04
  271.             && immediate 
  272.             && instr3a.rs1 == instr3a.rd) {
  273.             if (instr3b.simm13 == 0x01) {
  274.                 sprintf(buf, "dec %s", user_mode(instr3a.rd));
  275.             } else {
  276.                 sprintf(buf, "dec %d, %s", instr3b.simm13, user_mode(instr3a.rd));
  277.             }
  278.             break;
  279.         }
  280.         /* orcc %g0,rs2,%g0 becomes tst rs2 */
  281.         if (instr3a.op3 == 0x12 && instr3a.rs1 == 0 && instr3a.rd == 0) {
  282.             sprintf(buf, "tst %s", user_mode(instr3a.rs2));
  283.             break;
  284.         }
  285. #endif
  286.  
  287.  
  288.         
  289.         if (immediate) {
  290.             if (instr3a.rs1 > 0) {
  291.                 sprintf(buf, "%s %s, %d, %s",
  292.                     opcode_ptr, user_mode(instr3a.rs1),
  293.                     SIGN_EXT13(instr3b.simm13),
  294.                     user_mode(instr3a.rd));
  295.             } else {
  296.                 /* %g0 is rs1: ignore it for clarity */
  297.                 sprintf(buf, "%s %d, %s", opcode_ptr,
  298.                     SIGN_EXT13(instr3b.simm13),
  299.                     user_mode(instr3a.rd));
  300.             }
  301.         } else {
  302.             sprintf(buf, "%s %s, %s, %s",
  303.                 opcode_ptr, user_mode(instr3a.rs1),
  304.                 user_mode(instr3a.rs2),
  305.                 user_mode(instr3a.rd));
  306.         }
  307.         break;
  308.     }
  309.  
  310.     return;
  311. }
  312.