cr88192

GPI / Simple Genetic Program Interpreter

Nov 18th, 2021
1,476
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 32.49 KB | None | 0 0
  1. /*
  2.  
  3. Simplistic Genetic Programming ISA.
  4. * Based around 3R instructions.
  5. * Each instruction word is 64 bits.
  6. * There are 16 or 32 registers (R0..R31).
  7. ** Each register is 64 bits.
  8. ** R0: ZR (Zero Register)
  9. ** R1: LR (Link Register) / IMM (Immediate)
  10.  
  11. Instruction encoding (Basic 3R):
  12. * (63:48): Opcode (8 or 10 logical bits)
  13. * (47:24): Ignore / Imm24
  14. * (23:16): Rd / Ld
  15. * (15: 8): Rs
  16. * ( 7: 0): Rt
  17.  
  18. Instruction encoding (Basic 2R):
  19. * (63:48): Opcode (8 or 10 logical bits)
  20. * (47:24): Ignore / Imm24
  21. * (23:16): Rd
  22. * (15: 8): Rs
  23. * ( 7: 0): Opcode 2
  24.  
  25. Instruction encoding (Imm48):
  26. * (63:56): Opcode (4 or 5 logical bits)
  27. * (55:48): Rd
  28. * (47: 0): Imm48
  29.  
  30.  
  31. Multiple encodings may map to the same logical register, and using ECC bits makes the register ID more resistant to random bit-flips (caused by the mutator).
  32.  
  33. The 8 bit register field will consist of 4 or 5 data bits and 4 or 3 parity bits.
  34. * The data bits will encode the register number using Gray-Coding
  35. * The parity bits will each XOR a group of 3 bits.
  36. * 4-bit: abcd: a^b^c, b^c^d, c^d^a
  37. * 5-bit: abcde: a^b^c, b^c^d, c^d^e
  38.  
  39. Encodings which fall into the "unrecoverable" or "disallowed" parts of the encoding space are interpreted as NOPs.
  40.  
  41. Opcodes will be encoded as either a single 4 or 5 bit value, or as a pair of 4 or 5 bit values. Opcodes will use either the 4 or 5 bit Gray Coding scheme.
  42.  
  43. Using a smaller encoding space may allow for faster convergence.
  44.  
  45.  
  46. Vector immediate values will be encoded as 48-bits, such as four 12-bit floating-point values (S.E5.M6), which may also be stored in gray-coded form. There might also be 2x 24-bit bit (truncated gray-coded single), or 1x 48-bit (truncated gray-coded double).
  47.  
  48. Opcode-Space:
  49. * 00: End Program
  50. * 01: 3R ALU
  51. ** 01-00: ADD
  52. ** 01-01: SUB
  53. ** 01-02: SHAD
  54. ** 01-03: SHLD
  55. ** 01-04: MUL
  56. ** 01-05: AND
  57. ** 01-06: OR
  58. ** 01-07: XOR
  59.  
  60. ** 01-08: MIN
  61. ** 01-09: MAX
  62. ** 01-0A: DIV
  63. ** 01-0B: MOD
  64.  
  65. ** 01-0C-00: MOV
  66.  
  67. * 02: Compare Branch
  68. ** 02-00: JCMPEQ
  69. ** 02-01: JCMPGT
  70. ** 02-02: JCMPGE
  71. ** 02-03: BSR (PC+Ld)
  72. ** 02-04: JCMPNE
  73. ** 02-05: JCMPLE
  74. ** 02-06: JCMPLT
  75. ** 02-07: JMP (Rs)
  76. ** 02-08: JCMPFEQ
  77. ** 02-09: JCMPFGT
  78. ** 02-0A: JCMPFGE
  79. ** 02-0B: -
  80. ** 02-0C: JCMPFNE
  81. ** 02-0D: JCMPFLE
  82. ** 02-0E: JCMPFLT
  83. ** 02-0F: -
  84.  
  85. * 03: 3R FPU
  86. ** 03-00: FADD
  87. ** 03-01: FSUB
  88. ** 03-02: FMUL
  89. ** 03-03: FDIV
  90. ** 03-04: FMAC
  91. ** 03-05: FMASC
  92. ** 03-06: FMIN
  93. ** 03-07: FMAX
  94.  
  95. ** 03-0C-00: RCP
  96. ** 03-0C-01: SQRT
  97. ** 03-0C-02: ATAN
  98.  
  99. ** 03-0C-04: I2F
  100. ** 03-0C-05: F2I
  101.  
  102. * 04: 3R VEC2F
  103. ** 04-00: PADD.F
  104. ** 04-01: PSUB.F
  105. ** 04-02: PMUL.F
  106. ** 04-03: PDIV.F
  107. * 05: 3R VEC4H
  108. ** 05-00: PADD.H
  109. ** 05-01: PSUB.H
  110. ** 05-02: PMUL.H
  111. ** 05-03: PDIV.H
  112.  
  113. * 0C: IMM Int48 (Load 48-bit Integer, Sign Extend)
  114. * 0D: IMM Float (Load 48-bit Truncated Double)
  115. * 0E: IMM VEC2F (Load 2x Float24, Truncated Single)
  116. * 0F: IMM VEC4H (Load 4x Float12, Truncated Half)
  117.  
  118. */
  119.  
  120. #include <stdio.h>
  121. #include <stdlib.h>
  122. #include <string.h>
  123. #include <stdint.h>
  124. #include <math.h>
  125.  
  126. #define GPI_ROMSZ   256
  127. #define GPI_GENSZ   256
  128. #define GPI_GENSEL  32
  129.  
  130. typedef int8_t      sbyte;
  131. typedef uint8_t byte;
  132. typedef int16_t s16;
  133. typedef uint16_t    u16;
  134. typedef int32_t s32;
  135. typedef uint32_t    u32;
  136. typedef int64_t s64;
  137. typedef uint64_t    u64;
  138.  
  139. typedef struct GPI_VMProg_s GPI_VMProg;
  140. typedef struct GPI_VMState_s    GPI_VMState;
  141. typedef struct GPI_Context_s    GPI_Context;
  142.  
  143. struct GPI_VMProg_s {
  144. u64 rom[GPI_ROMSZ];
  145. };
  146.  
  147. struct GPI_VMState_s {
  148. u64 reg[32];
  149. u64 u_reg[8];
  150. short nnop;
  151. byte pc;
  152. GPI_VMProg *prog;
  153. };
  154.  
  155. struct GPI_Context_s {
  156. GPI_VMProg *prog[GPI_GENSZ];
  157. double      prgw[GPI_GENSZ];
  158.  
  159. GPI_VMProg  prg_arr[GPI_GENSZ];
  160.  
  161. void    *userdata;
  162. void    (*SetupState)(GPI_Context *ctx, GPI_VMState *vm);
  163. double  (*RankState)(GPI_Context *ctx, GPI_VMState *vm);
  164. };
  165.  
  166. byte    gpi_gray4enc[16];
  167. byte    gpi_gray4dec[16];
  168. byte    gpi_gray5enc[32];
  169. byte    gpi_gray5dec[32];
  170.  
  171. byte    gpi_gray8enc[256];
  172. byte    gpi_gray8dec[256];
  173.  
  174. byte    gpi_base4encp[16];
  175. byte    gpi_base5encp[32];
  176. byte    gpi_base4decp[256];
  177. byte    gpi_base5decp[256];
  178.  
  179. byte    gpi_gray4encp[16];
  180. byte    gpi_gray5encp[32];
  181. byte    gpi_gray4decp[256];
  182. byte    gpi_gray5decp[256];
  183.  
  184. byte    gpi_gray4decpr[256];
  185. byte    gpi_gray5decpr[256];
  186. byte    gpi_graydecr[256];
  187. byte    gpi_graydeco[256];
  188.  
  189. u32     gpi_halfdechi[64];
  190. u16     gpi_halfenchi[512];
  191.  
  192. void GPI_InitTables(void)
  193. {
  194.     int p0, p1, p2, p3;
  195.     int i, j, k;
  196.    
  197.     for(i=0; i<16; i++)
  198.     {
  199.         j=i^(i>>1);
  200.         gpi_gray4enc[i]=j;
  201.         gpi_gray4dec[j]=i;
  202.     }
  203.     for(i=0; i<32; i++)
  204.     {
  205.         j=i^(i>>1);
  206.         gpi_gray5enc[i]=j;
  207.         gpi_gray5dec[j]=i;
  208.     }
  209.  
  210.     for(i=0; i<256; i++)
  211.     {
  212.         j=i^(i>>1);
  213.         gpi_gray8enc[i]=j;
  214.         gpi_gray8dec[j]=i;
  215.     }
  216.    
  217.     memset(gpi_base4decp, 0xFF, 256);
  218.     memset(gpi_base5decp, 0xFF, 256);
  219.  
  220.     for(i=0; i<16; i++)
  221.     {
  222.         p0=((i>>3)^(i>>2)^(i>>1))&1;
  223.         p1=((i>>2)^(i>>1)^(i>>0))&1;
  224.         p2=((i>>1)^(i>>0)^(i>>3))&1;
  225.         p3=((i>>3)^(i>>2)^(i>>1)^(i>>0))&1;
  226.         j=i|(p0<<7)|(p1<<6)|(p2<<5)|(p3<<4);
  227.         gpi_base4encp[i]=j;
  228.         gpi_base4decp[j]=i;
  229.     }
  230.  
  231.     for(i=0; i<32; i++)
  232.     {
  233.         p0=((i>>4)^(i>>3)^(i>>2))&1;
  234.         p1=((i>>3)^(i>>2)^(i>>1))&1;
  235.         p2=((i>>2)^(i>>1)^(i>>0))&1;
  236.         j=i|(p0<<7)|(p1<<6)|(p2<<5);
  237.         gpi_base5encp[i]=j;
  238.         gpi_base5decp[j]=i;
  239.     }
  240.  
  241.     for(i=0; i<256; i++)
  242.     {
  243.         j=gpi_base4decp[i];
  244.         if(j!=255)continue;
  245.        
  246.         for(j=0; j<8; j++)
  247.         {
  248.             p0=i^(1<<j);
  249.             p1=gpi_base4decp[p0];
  250.             p2=gpi_base4encp[p1];
  251.             if((p1!=255) && (p2==p0))
  252.             {
  253.                 gpi_base4decp[i]=p1;
  254.                 break;
  255.             }
  256.         }
  257.     }
  258.  
  259. #if 0
  260.     for(i=0; i<256; i++)
  261.     {
  262.         j=gpi_base4decp[i];
  263.         if(j!=255)continue;
  264.        
  265.         for(j=0; j<8; j++)
  266.             for(k=0; k<8; k++)
  267.         {
  268.             p0=i^(1<<j)^(1<<k);
  269.             p1=gpi_base4decp[p0];
  270.             p2=gpi_base4encp[p1];
  271.             if((p1!=255) && (p2==p0))
  272.             {
  273.                 gpi_base4decp[i]=p1;
  274.                 break;
  275.             }
  276.         }
  277.     }
  278. #endif
  279.  
  280.     for(i=0; i<256; i++)
  281.     {
  282.         j=gpi_base5decp[i];
  283.         if(j!=255)continue;
  284.        
  285.         for(j=0; j<8; j++)
  286.         {
  287.             p0=i^(1<<j);
  288.             p1=gpi_base5decp[p0];
  289.             p2=gpi_base5encp[p1];
  290.             if((p1!=255) && (p2==p0))
  291.             {
  292.                 gpi_base5decp[i]=p1;
  293.                 break;
  294.             }
  295.         }
  296.     }
  297.  
  298.     for(i=0; i<16; i++)
  299.         { gpi_gray4encp[i]=gpi_base4encp[gpi_gray4enc[i]]; }
  300.     for(i=0; i<32; i++)
  301.         { gpi_gray5encp[i]=gpi_base5encp[gpi_gray5enc[i]]; }
  302.  
  303.     for(i=0; i<256; i++)
  304.     {
  305.         j=gpi_base4decp[i];
  306.         k=(j>32)?255:gpi_gray4dec[j];
  307.         gpi_gray4decp[i]=k;
  308.  
  309.         if(k==255)      k=0;
  310.         gpi_gray4decpr[i]=k;
  311.  
  312.  
  313.         j=gpi_base5decp[i];
  314.         k=(j>32)?255:gpi_gray5dec[j];
  315.         gpi_gray5decp[i]=k;
  316.  
  317.         if(k==255)      k=0;
  318.         gpi_gray5decpr[i]=k;
  319.     }
  320.  
  321.     for(i=0; i<16; i++)
  322.     {
  323.         j=gpi_gray4encp[i];
  324.         k=gpi_gray4decp[j];
  325.        
  326.         if(k!=i)
  327.             { printf("Gray4: Round Trip Fail\n"); }
  328.     }
  329.  
  330.     for(i=0; i<32; i++)
  331.     {
  332.         j=gpi_gray5encp[i];
  333.         k=gpi_gray5decp[j];
  334.        
  335.         if(k!=i)
  336.             { printf("Gray5: Round Trip Fail\n"); }
  337.     }
  338.    
  339.     for(i=0; i<32; i++)
  340.     {
  341.         j=((i-15)+127)<<23;
  342.         if(i== 0)   j=  0U<<23;
  343.         if(i==31)   j=255U<<23;
  344.         gpi_halfdechi[0x00|i]=j;
  345.         gpi_halfdechi[0x20|i]=j|0x80000000U;
  346.     }
  347.  
  348.     for(i=0; i<256; i++)
  349.     {
  350.         j=(i-127)+15;
  351.         if(j<=0)j=0;
  352.         if(j>=15)j=15;
  353.         k=j<<10;
  354.         gpi_halfenchi[0x000|i]=0x0000|k;
  355.         gpi_halfenchi[0x100|i]=0x8000|k;
  356.     }
  357.    
  358.     for(i=0; i<256; i++)
  359.     {
  360.         gpi_graydecr[i]=gpi_gray4decpr[i];
  361. //      gpi_graydecr[i]=gpi_gray5decpr[i];
  362.  
  363.         gpi_graydeco[i]=gpi_gray4decpr[i];
  364.     }
  365. }
  366.  
  367. void GPI_DumpTables(void)
  368. {
  369.     int stat[64];
  370.     int i, j, k;
  371.    
  372.     printf("Gray4 Enc:\n");
  373.     for(i=0; i<16; i++)
  374.         { printf("%02X ", gpi_gray4enc[i]); }
  375.     printf("\n");
  376.  
  377.     printf("Gray4 EncP:\n");
  378.     for(i=0; i<16; i++)
  379.         { printf("%02X ", gpi_gray4encp[i]); }
  380.     printf("\n");
  381.  
  382.     printf("Gray5 Enc:\n");
  383.     for(i=0; i<32; i++)
  384.         { printf("%02X ", gpi_gray5enc[i]); }
  385.     printf("\n");
  386.  
  387.     printf("Gray5 EncP:\n");
  388.     for(i=0; i<32; i++)
  389.         { printf("%02X ", gpi_gray5encp[i]); }
  390.     printf("\n");
  391.  
  392.     printf("Gray4 DecP:\n");
  393.     for(i=0; i<64; i++)
  394.         stat[i]=0;
  395.     for(i=0; i<16; i++)
  396.     {
  397.         for(j=0; j<16; j++)
  398.         {
  399.             k=gpi_gray4decp[i*16+j];
  400.             printf("%02X ", k);
  401.             stat[k&63]++;
  402.         }
  403.         printf("\n");
  404.     }
  405.  
  406.     for(i=0; i<16; i++)
  407.     {
  408.         printf("%d ", stat[i]);
  409.     }
  410.     printf("%d\n", stat[63]);
  411.  
  412.     printf("Gray5 DecP:\n");
  413.     for(i=0; i<64; i++)
  414.         stat[i]=0;
  415.     for(i=0; i<16; i++)
  416.     {
  417.         for(j=0; j<16; j++)
  418.         {
  419.             k=gpi_gray5decp[i*16+j];
  420.             printf("%02X ", k);
  421.             stat[k&63]++;
  422.         }
  423.         printf("\n");
  424.     }
  425.  
  426.     for(i=0; i<32; i++)
  427.     {
  428.         printf("%d ", stat[i]);
  429.     }
  430.     printf("%d\n", stat[63]);
  431. }
  432.  
  433. int GPI_InterpAdd2F(GPI_VMState *ctx, int rs, int rt, int rd)
  434. {
  435.     float *fvs, *fvt, *fvd;
  436.     u64 vs, vt, vd;
  437.     vs=ctx->reg[rs];    vt=ctx->reg[rt];
  438.     fvs=(float *)(&vs);
  439.     fvt=(float *)(&vt);
  440.     fvd=(float *)(&vd);
  441.     fvd[0]=fvs[0]+fvt[0];
  442.     fvd[1]=fvs[1]+fvt[1];
  443.     ctx->reg[rd]=vd;
  444.     return(0);
  445. }
  446.  
  447. int GPI_InterpSub2F(GPI_VMState *ctx, int rs, int rt, int rd)
  448. {
  449.     float *fvs, *fvt, *fvd;
  450.     u64 vs, vt, vd;
  451.     vs=ctx->reg[rs];    vt=ctx->reg[rt];
  452.     fvs=(float *)(&vs);
  453.     fvt=(float *)(&vt);
  454.     fvd=(float *)(&vd);
  455.     fvd[0]=fvs[0]-fvt[0];
  456.     fvd[1]=fvs[1]-fvt[1];
  457.     ctx->reg[rd]=vd;
  458.     return(0);
  459. }
  460.  
  461. int GPI_InterpMul2F(GPI_VMState *ctx, int rs, int rt, int rd)
  462. {
  463.     float *fvs, *fvt, *fvd;
  464.     u64 vs, vt, vd;
  465.     vs=ctx->reg[rs];    vt=ctx->reg[rt];
  466.     fvs=(float *)(&vs);
  467.     fvt=(float *)(&vt);
  468.     fvd=(float *)(&vd);
  469.     fvd[0]=fvs[0]*fvt[0];
  470.     fvd[1]=fvs[1]*fvt[1];
  471.     ctx->reg[rd]=vd;
  472.     return(0);
  473. }
  474.  
  475. int GPI_InterpDiv2F(GPI_VMState *ctx, int rs, int rt, int rd)
  476. {
  477.     float *fvs, *fvt, *fvd;
  478.     u64 vs, vt, vd;
  479.     vs=ctx->reg[rs];    vt=ctx->reg[rt];
  480.     fvs=(float *)(&vs);
  481.     fvt=(float *)(&vt);
  482.     fvd=(float *)(&vd);
  483.     fvd[0]=fvs[0]/fvt[0];
  484.     fvd[1]=fvs[1]/fvt[1];
  485.     ctx->reg[rd]=vd;
  486.     return(0);
  487. }
  488.  
  489. float GPU_VecUnpackHalf(int val)
  490. {
  491.     float f;
  492.     u32 hf;
  493.    
  494.     hf=gpi_halfdechi[(val>>10)&63]|((val&1023)<<13);
  495.     *(u32 *)(&f)=hf;
  496.     return(f);
  497. }
  498.  
  499. int GPU_VecPackHalf(float val)
  500. {
  501.     u32 tv;
  502.     u16 hf;
  503.    
  504.     tv=*(u32 *)(&val);
  505.     hf=gpi_halfenchi[(tv>>23)&511]|((tv>>13)&1023);
  506.     return(hf);
  507. }
  508.  
  509. void GPU_VecUnpack4H(u64 vec, float *rfv)
  510. {
  511.     rfv[0]=GPU_VecUnpackHalf(vec>> 0);
  512.     rfv[1]=GPU_VecUnpackHalf(vec>>16);
  513.     rfv[2]=GPU_VecUnpackHalf(vec>>32);
  514.     rfv[3]=GPU_VecUnpackHalf(vec>>48);
  515. }
  516.  
  517. u64 GPU_VecPack4H(float *rfv)
  518. {
  519.     u64 tv;
  520.     u32 i0, i1, i2, i3;
  521.     i0=GPU_VecPackHalf(rfv[0]);
  522.     i1=GPU_VecPackHalf(rfv[1]);
  523.     i2=GPU_VecPackHalf(rfv[2]);
  524.     i3=GPU_VecPackHalf(rfv[3]);
  525.     i1=(i1<<16)|i0;
  526.     i3=(i3<<16)|i2;
  527.     tv=(((u64)i3)<<32)|i1;
  528.     return(tv);
  529. }
  530.  
  531. int GPI_InterpAdd4H(GPI_VMState *ctx, int rs, int rt, int rd)
  532. {
  533.     float fvs[4], fvt[4], fvd[4];
  534.     u64 vs, vt, vd;
  535.     vs=ctx->reg[rs];    vt=ctx->reg[rt];
  536.     GPU_VecUnpack4H(vs, fvs);
  537.     GPU_VecUnpack4H(vt, fvt);
  538.     fvd[0]=fvs[0]+fvt[0];
  539.     fvd[1]=fvs[1]+fvt[1];
  540.     fvd[2]=fvs[2]+fvt[2];
  541.     fvd[3]=fvs[3]+fvt[3];
  542.     vd=GPU_VecPack4H(fvd);
  543.     ctx->reg[rd]=vd;
  544.     return(0);
  545. }
  546.  
  547. int GPI_InterpSub4H(GPI_VMState *ctx, int rs, int rt, int rd)
  548. {
  549.     float fvs[4], fvt[4], fvd[4];
  550.     u64 vs, vt, vd;
  551.     vs=ctx->reg[rs];    vt=ctx->reg[rt];
  552.     GPU_VecUnpack4H(vs, fvs);
  553.     GPU_VecUnpack4H(vt, fvt);
  554.     fvd[0]=fvs[0]-fvt[0];
  555.     fvd[1]=fvs[1]-fvt[1];
  556.     fvd[2]=fvs[2]-fvt[2];
  557.     fvd[3]=fvs[3]-fvt[3];
  558.     vd=GPU_VecPack4H(fvd);
  559.     ctx->reg[rd]=vd;
  560.     return(0);
  561. }
  562.  
  563. int GPI_InterpMul4H(GPI_VMState *ctx, int rs, int rt, int rd)
  564. {
  565.     float fvs[4], fvt[4], fvd[4];
  566.     u64 vs, vt, vd;
  567.     vs=ctx->reg[rs];    vt=ctx->reg[rt];
  568.     GPU_VecUnpack4H(vs, fvs);
  569.     GPU_VecUnpack4H(vt, fvt);
  570.     fvd[0]=fvs[0]*fvt[0];
  571.     fvd[1]=fvs[1]*fvt[1];
  572.     fvd[2]=fvs[2]*fvt[2];
  573.     fvd[3]=fvs[3]*fvt[3];
  574.     vd=GPU_VecPack4H(fvd);
  575.     ctx->reg[rd]=vd;
  576.     return(0);
  577. }
  578.  
  579. int GPI_InterpDiv4H(GPI_VMState *ctx, int rs, int rt, int rd)
  580. {
  581.     float fvs[4], fvt[4], fvd[4];
  582.     u64 vs, vt, vd;
  583.     vs=ctx->reg[rs];    vt=ctx->reg[rt];
  584.     GPU_VecUnpack4H(vs, fvs);
  585.     GPU_VecUnpack4H(vt, fvt);
  586.     fvd[0]=fvs[0]/fvt[0];
  587.     fvd[1]=fvs[1]/fvt[1];
  588.     fvd[2]=fvs[2]/fvt[2];
  589.     fvd[3]=fvs[3]/fvt[3];
  590.     vd=GPU_VecPack4H(fvd);
  591.     ctx->reg[rd]=vd;
  592.     return(0);
  593. }
  594.  
  595. int GPI_InterpStep(GPI_VMState *ctx)
  596. {
  597.     double f, g, e, h;
  598.     s64 li, la, lb, lc;
  599.     u64 opw;
  600.     int pc, rd, rs, rt;
  601.     int i0, i1, i2;
  602.     int i, j, opn, opy, ret;
  603.    
  604.     ctx->reg[0]=0;
  605.     ret=0;
  606.  
  607.     pc=ctx->pc;
  608.     ctx->pc=pc+1;
  609.     opw=ctx->prog->rom[pc];
  610. //  opn=gpi_gray5decp[(opw>>56)&255];
  611.     opn=gpi_graydeco[(opw>>56)&255];
  612.     switch(opn)
  613.     {
  614.     case 0x00:
  615. //      ret=1;
  616.         break;
  617.     case 0x01:
  618.         rd=gpi_graydecr[(opw>>16)&255];
  619.         rs=gpi_graydecr[(opw>> 8)&255];
  620.         rt=gpi_graydecr[(opw>> 0)&255];
  621.  
  622.         i0=             gpi_gray8dec[(opw>>40)&255];
  623.         i0=(i0<<8) |    gpi_gray8dec[(opw>>32)&255];
  624.         i0=(i0<<8) |    gpi_gray8dec[(opw>>24)&255];
  625.        
  626.         i0=((s32)(i0<<8))>>8;
  627.  
  628.         ctx->nnop++;
  629. //      switch(gpi_gray5decp[(opw>>48)&255])
  630.         switch(gpi_graydeco[(opw>>48)&255])
  631.         {
  632.         case 0x00:
  633.             la=ctx->reg[rs];
  634.             lb=ctx->reg[rt];
  635.             if(rs==1)la=i0;
  636.             if(rt==1)lb=i0;
  637.             lc=la+lb;
  638.             ctx->reg[rd]=lc;
  639.             break;
  640.         case 0x01:
  641.             la=ctx->reg[rs];
  642.             lb=ctx->reg[rt];
  643.             if(rs==1)la=i0;
  644.             if(rt==1)lb=i0;
  645.             lc=la-lb;
  646.             ctx->reg[rd]=lc;
  647.             break;
  648.         case 0x02:
  649.             j=(sbyte)ctx->reg[rt];
  650.             if(rt==1)   j=i0;
  651.             if(j>=0)
  652.                 ctx->reg[rd]=((s64)ctx->reg[rs])<<(( j)&63);
  653.             else
  654.                 ctx->reg[rd]=((s64)ctx->reg[rs])>>((-j)&63);
  655.             break;
  656.         case 0x03:
  657.             j=(sbyte)ctx->reg[rt];
  658.             if(rt==1)   j=i0;
  659.             if(j>=0)
  660.                 ctx->reg[rd]=((u64)ctx->reg[rs])<<(( j)&63);
  661.             else
  662.                 ctx->reg[rd]=((u64)ctx->reg[rs])>>((-j)&63);
  663.             break;
  664.         case 0x04:
  665.             la=ctx->reg[rs];
  666.             lb=ctx->reg[rt];
  667.             if(rs==1)la=i0;
  668.             if(rt==1)lb=i0;
  669.             lc=la*lb;
  670.             ctx->reg[rd]=lc;
  671.             break;
  672.         case 0x05:
  673.             la=ctx->reg[rs];
  674.             lb=ctx->reg[rt];
  675.             if(rs==1)la=i0;
  676.             if(rt==1)lb=i0;
  677.             lc=la&lb;
  678.             ctx->reg[rd]=lc;
  679.             break;
  680.         case 0x06:
  681.             la=ctx->reg[rs];
  682.             lb=ctx->reg[rt];
  683.             if(rs==1)la=i0;
  684.             if(rt==1)lb=i0;
  685.             lc=la|lb;
  686.             ctx->reg[rd]=lc;
  687.             break;
  688.         case 0x07:
  689.             la=ctx->reg[rs];
  690.             lb=ctx->reg[rt];
  691.             if(rs==1)la=i0;
  692.             if(rt==1)lb=i0;
  693.             lc=la^lb;
  694.             ctx->reg[rd]=lc;
  695.             break;
  696.  
  697.         case 0x08:
  698.             la=ctx->reg[rs];
  699.             lb=ctx->reg[rt];
  700.             if(rs==1)la=i0;
  701.             if(rt==1)lb=i0;
  702.             lc=(la<lb)?la:lb;
  703.             ctx->reg[rd]=lc;
  704.             break;
  705.         case 0x09:
  706.             la=ctx->reg[rs];
  707.             lb=ctx->reg[rt];
  708.             if(rs==1)la=i0;
  709.             if(rt==1)lb=i0;
  710.             lc=(la>lb)?la:lb;
  711.             ctx->reg[rd]=lc;
  712.             break;
  713.         case 0x0A:
  714.             la=ctx->reg[rs];
  715.             lb=ctx->reg[rt];
  716.             if(rs==1)la=i0;
  717.             if(rt==1)lb=i0;
  718.             lc=(lb!=0)?(la/lb):0;
  719.             ctx->reg[rd]=lc;
  720.             break;
  721.         case 0x0B:
  722.             la=ctx->reg[rs];
  723.             lb=ctx->reg[rt];
  724.             if(rs==1)la=i0;
  725.             if(rt==1)lb=i0;
  726.             lc=(lb!=0)?(la%lb):0;
  727.             ctx->reg[rd]=lc;
  728.             break;
  729.  
  730.         case 0x0D:
  731.             rs=rd;
  732.         case 0x0C:
  733.             switch(rt)
  734.             {
  735.             case 0x00:
  736.                 ctx->reg[rd]=ctx->reg[rs];
  737.                 break;
  738.             }
  739.             break;
  740.         default:
  741.             break;
  742.         }
  743.         break;
  744.  
  745.     case 0x02:
  746.         rd=gpi_graydecr[(opw>>16)&255];
  747.         rs=gpi_graydecr[(opw>> 8)&255];
  748.         rt=gpi_graydecr[(opw>> 0)&255];
  749.         ctx->nnop++;
  750.         opy=gpi_graydeco[(opw>>48)&255];
  751. //      switch(gpi_gray5decp[(opw>>48)&255])
  752.         switch(opy)
  753.         {
  754.         case 0x00:
  755.         case 0x04:
  756.             la=ctx->reg[rs];
  757.             lb=ctx->reg[rt];
  758.             j=(rd>>1)^((rd&1)?-1:0);
  759.             if((la==lb) ^ ((opy&4)!=0))
  760.             {
  761. //              ctx->reg[1]=op->pc;
  762.                 ctx->pc=(pc+1+j)&(GPI_ROMSZ-1);
  763.                 if(ctx->pc==pc)
  764.                     ret=1;
  765.             }
  766.             break;
  767.         case 0x01:
  768.         case 0x05:
  769.             la=ctx->reg[rs];
  770.             lb=ctx->reg[rt];
  771.             j=(rd>>1)^((rd&1)?-1:0);
  772.             if((la>lb) ^ ((opy&4)!=0))
  773.             {
  774. //              ctx->reg[1]=op->pc;
  775.                 ctx->pc=(pc+1+j)&(GPI_ROMSZ-1);
  776.                 if(ctx->pc==pc)
  777.                     ret=1;
  778.             }
  779.             break;
  780.         case 0x02:
  781.         case 0x06:
  782.             la=ctx->reg[rs];
  783.             lb=ctx->reg[rt];
  784.             j=(rd>>1)^((rd&1)?-1:0);
  785.             if((la>=lb) ^ ((opy&4)!=0))
  786.             {
  787. //              ctx->reg[1]=op->pc;
  788.                 ctx->pc=(pc+1+j)&(GPI_ROMSZ-1);
  789.                 if(ctx->pc==pc)
  790.                     ret=1;
  791.             }
  792.             break;
  793.  
  794.         case 0x03:
  795.             j=(rd>>1)^((rd&1)?-1:0);
  796.             ctx->pc=pc+1+j;
  797.             if(ctx->pc==pc)
  798.                 ret=1;
  799.             break;
  800.  
  801.         case 0x07:
  802.             la=ctx->reg[rs];
  803.             ctx->pc=la&(GPI_ROMSZ-1);
  804.             if(ctx->pc==pc)
  805.                 ret=1;
  806.             break;
  807.  
  808.         case 0x08:
  809.         case 0x0C:
  810.             f=*(double *)(ctx->reg+rs);
  811.             g=*(double *)(ctx->reg+rt);
  812.             j=(rd>>1)^((rd&1)?-1:0);
  813.             if((f==g) ^ ((opy&4)!=0))
  814.             {
  815. //              ctx->reg[1]=op->pc;
  816.                 ctx->pc=(pc+1+j)&(GPI_ROMSZ-1);
  817.                 if(ctx->pc==pc)
  818.                     ret=1;
  819.             }
  820.             break;
  821.         case 0x09:
  822.         case 0x0D:
  823.             f=*(double *)(ctx->reg+rs);
  824.             g=*(double *)(ctx->reg+rt);
  825.             j=(rd>>1)^((rd&1)?-1:0);
  826.             if((f>g) ^ ((opy&4)!=0))
  827.             {
  828. //              ctx->reg[1]=op->pc;
  829.                 ctx->pc=(pc+1+j)&(GPI_ROMSZ-1);
  830.                 if(ctx->pc==pc)
  831.                     ret=1;
  832.             }
  833.             break;
  834.         case 0x0A:
  835.         case 0x0E:
  836.             f=*(double *)(ctx->reg+rs);
  837.             g=*(double *)(ctx->reg+rt);
  838.             j=(rd>>1)^((rd&1)?-1:0);
  839.             if((f>=g) ^ ((opy&4)!=0))
  840.             {
  841. //              ctx->reg[1]=op->pc;
  842.                 ctx->pc=(pc+1+j)&(GPI_ROMSZ-1);
  843.                 if(ctx->pc==pc)
  844.                     ret=1;
  845.             }
  846.             break;
  847.  
  848.         default:
  849.             break;
  850.         }
  851.         break;
  852.  
  853.     case 0x03:
  854.         rd=gpi_graydecr[(opw>>16)&255];
  855.         rs=gpi_graydecr[(opw>> 8)&255];
  856.         rt=gpi_graydecr[(opw>> 0)&255];
  857.  
  858.         i0=             gpi_gray8dec[(opw>>40)&255];
  859.         i0=(i0<<8) |    gpi_gray8dec[(opw>>32)&255];
  860.         i0=(i0<<8) |    gpi_gray8dec[(opw>>24)&255];
  861.         i0=(i0<<8);
  862.        
  863.         e=*(float *)(&i0);
  864.  
  865.         ctx->nnop++;
  866. //      switch(gpi_gray5decp[(opw>>48)&255])
  867.         switch(gpi_graydeco[(opw>>48)&255])
  868.         {
  869.         case 0x00:
  870.             f=*(double *)(ctx->reg+rs);
  871.             g=*(double *)(ctx->reg+rt);
  872.             if(rs==1)f=e;
  873.             if(rt==1)g=e;
  874.             h=f+g;
  875.             *(double *)(ctx->reg+rd)=h;
  876.             break;
  877.         case 0x01:
  878.             f=*(double *)(ctx->reg+rs);
  879.             g=*(double *)(ctx->reg+rt);
  880.             if(rs==1)f=e;
  881.             if(rt==1)g=e;
  882.             h=f-g;
  883.             *(double *)(ctx->reg+rd)=h;
  884.             break;
  885.         case 0x02:
  886.             f=*(double *)(ctx->reg+rs);
  887.             g=*(double *)(ctx->reg+rt);
  888.             if(rs==1)f=e;
  889.             if(rt==1)g=e;
  890.             h=f*g;
  891.             *(double *)(ctx->reg+rd)=h;
  892.             break;
  893.         case 0x03:
  894.             f=*(double *)(ctx->reg+rs);
  895.             g=*(double *)(ctx->reg+rt);
  896.             if(rs==1)f=e;
  897.             if(rt==1)g=e;
  898.             h = (g!=0) ? (f/g) : 0;
  899.             *(double *)(ctx->reg+rd)=h;
  900.             break;
  901.  
  902.         case 0x04:
  903.             f=*(double *)(ctx->reg+rs);
  904.             g=*(double *)(ctx->reg+rt);
  905.             if(rs==1)f=e;
  906.             if(rt==1)g=e;
  907.             h=*(double *)(ctx->reg+rd);
  908.             h=h+f*g;
  909.             *(double *)(ctx->reg+rd)=h;
  910.             break;
  911.  
  912.         case 0x05:
  913.             f=*(double *)(ctx->reg+rs);
  914.             g=*(double *)(ctx->reg+rt);
  915.             h=f+g*e;
  916.             *(double *)(ctx->reg+rd)=h;
  917.             break;
  918.  
  919.         case 0x06:
  920.             f=*(double *)(ctx->reg+rs);
  921.             g=*(double *)(ctx->reg+rt);
  922.             if(rs==1)f=e;
  923.             if(rt==1)g=e;
  924.  
  925. //          h=*(double *)(ctx->reg+rd);
  926.             h=(f<g)?f:g;
  927.             *(double *)(ctx->reg+rd)=h;
  928.             break;
  929.         case 0x07:
  930.             f=*(double *)(ctx->reg+rs);
  931.             g=*(double *)(ctx->reg+rt);
  932.             if(rs==1)f=e;
  933.             if(rt==1)g=e;
  934.  
  935. //          h=*(double *)(ctx->reg+rd);
  936.             h=(f>g)?f:g;
  937.             *(double *)(ctx->reg+rd)=h;
  938.             break;
  939.        
  940.         case 0x0D:
  941.             rs=rd;
  942.         case 0x0C:
  943.             switch(rt)
  944.             {
  945.             case 0x00:
  946.                 f=*(double *)(ctx->reg+rs);
  947.                 h = (f!=0) ? (1.0/f) : 0;
  948.                 *(double *)(ctx->reg+rd)=h;
  949.                 break;
  950.             case 0x01:
  951.                 f=*(double *)(ctx->reg+rs);
  952.                 h = (f>=0) ? sqrt(f) : -sqrt(-f);
  953.                 *(double *)(ctx->reg+rd)=h;
  954.                 break;
  955.             case 0x02:
  956.                 f=*(double *)(ctx->reg+rs);
  957.                 h = atan(f);
  958.                 *(double *)(ctx->reg+rd)=h;
  959.                 break;
  960.  
  961.             case 0x04:
  962.                 f=ctx->reg[rs];
  963.                 *(double *)(ctx->reg+rd)=f;
  964.                 break;
  965.             case 0x05:
  966.                 f=*(double *)(ctx->reg+rs);
  967.                 ctx->reg[rd]=f;
  968.                 break;
  969.             }
  970.             break;
  971.        
  972.         default:
  973.             break;
  974.         }
  975.         break;
  976.  
  977.     case 0x04:
  978.         rd=gpi_graydecr[(opw>>16)&255];
  979.         rs=gpi_graydecr[(opw>> 8)&255];
  980.         rt=gpi_graydecr[(opw>> 0)&255];
  981.         ctx->nnop++;
  982. //      switch(gpi_gray5decp[(opw>>48)&255])
  983.         switch(gpi_graydeco[(opw>>48)&255])
  984.         {
  985.         case 0x00:
  986.             GPI_InterpAdd2F(ctx, rs, rt, rd);
  987.             break;
  988.         case 0x01:
  989.             GPI_InterpSub2F(ctx, rs, rt, rd);
  990.             break;
  991.         case 0x02:
  992.             GPI_InterpMul2F(ctx, rs, rt, rd);
  993.             break;
  994.         case 0x03:
  995.             GPI_InterpDiv2F(ctx, rs, rt, rd);
  996.             break;
  997.         default:
  998.             break;
  999.         }
  1000.         break;
  1001.  
  1002.     case 0x05:
  1003.         rd=gpi_graydecr[(opw>>16)&255];
  1004.         rs=gpi_graydecr[(opw>> 8)&255];
  1005.         rt=gpi_graydecr[(opw>> 0)&255];
  1006.         ctx->nnop++;
  1007.  
  1008. //      switch(gpi_gray5decp[(opw>>48)&255])
  1009.         switch(gpi_graydeco[(opw>>48)&255])
  1010.         {
  1011.         case 0x00:
  1012.             GPI_InterpAdd4H(ctx, rs, rt, rd);
  1013.             break;
  1014.         case 0x01:
  1015.             GPI_InterpSub4H(ctx, rs, rt, rd);
  1016.             break;
  1017.         case 0x02:
  1018.             GPI_InterpMul4H(ctx, rs, rt, rd);
  1019.             break;
  1020.         case 0x03:
  1021.             GPI_InterpDiv4H(ctx, rs, rt, rd);
  1022.             break;
  1023.         default:
  1024.             break;
  1025.         }
  1026.         break;
  1027.        
  1028.     case 0x0C:
  1029.         rd=gpi_graydecr[(opw>>48)&255];
  1030.         li=             gpi_gray8dec[(opw>>40)&255];
  1031.         li=(li<<8) |    gpi_gray8dec[(opw>>32)&255];
  1032.         li=(li<<8) |    gpi_gray8dec[(opw>>24)&255];
  1033.         li=(li<<8) |    gpi_gray8dec[(opw>>16)&255];
  1034.         li=(li<<8) |    gpi_gray8dec[(opw>> 8)&255];
  1035.         li=(li<<8) |    gpi_gray8dec[(opw>> 0)&255];
  1036.         li=(li<<16)>>16;
  1037.         ctx->reg[rd]=li;
  1038.         ctx->nnop++;
  1039.         break;
  1040.     case 0x0D:
  1041.         rd=gpi_graydecr[(opw>>48)&255];
  1042.         li=             gpi_gray8dec[(opw>>40)&255];
  1043.         li=(li<<8) |    gpi_gray8dec[(opw>>32)&255];
  1044.         li=(li<<8) |    gpi_gray8dec[(opw>>24)&255];
  1045.         li=(li<<8) |    gpi_gray8dec[(opw>>16)&255];
  1046.         li=(li<<8) |    gpi_gray8dec[(opw>> 8)&255];
  1047.         li=(li<<8) |    gpi_gray8dec[(opw>> 0)&255];
  1048.         li=(li<<16);
  1049.         ctx->reg[rd]=li;
  1050.         ctx->nnop++;
  1051.         break;
  1052.     case 0x0E:
  1053.         rd=gpi_graydecr[(opw>>48)&255];
  1054.         li=             gpi_gray8dec[(opw>>40)&255];
  1055.         li=(li<<8) |    gpi_gray8dec[(opw>>32)&255];
  1056.         li=(li<<8) |    gpi_gray8dec[(opw>>24)&255];
  1057.         li=(li<<8);
  1058.         li=(li<<8) |    gpi_gray8dec[(opw>>16)&255];
  1059.         li=(li<<8) |    gpi_gray8dec[(opw>> 8)&255];
  1060.         li=(li<<8) |    gpi_gray8dec[(opw>> 0)&255];
  1061.         li=(li<<8);
  1062.         ctx->reg[rd]=li;
  1063.         ctx->nnop++;
  1064.         break;
  1065.     case 0x0F:
  1066.         rd=gpi_graydecr[(opw>>48)&255];
  1067.         if(!rd)
  1068.         {
  1069.             ret=1;
  1070.             break;
  1071.         }
  1072.        
  1073.         i0=             gpi_gray8dec[(opw>>40)&255];
  1074.         i0=(i0<<8) |    gpi_gray8dec[(opw>>32)&255];
  1075.         i0=(i0<<8) |    gpi_gray8dec[(opw>>24)&255];
  1076.         i1=             gpi_gray8dec[(opw>>16)&255];
  1077.         i1=(i1<<8) |    gpi_gray8dec[(opw>> 8)&255];
  1078.         i1=(i1<<8) |    gpi_gray8dec[(opw>> 0)&255];
  1079.         li=             (((i0>>12)&4095)<<4);
  1080.         li=(li<<16) |   (((i0>> 0)&4095)<<4);
  1081.         li=(li<<16) |   (((i1>>12)&4095)<<4);
  1082.         li=(li<<16) |   (((i1>> 0)&4095)<<4);
  1083.         ctx->reg[rd]=li;
  1084.         ctx->nnop++;
  1085.         break;
  1086.  
  1087.     default:
  1088.         /* NOP */
  1089.         break;
  1090.     }
  1091.     return(ret);
  1092. }
  1093.  
  1094. int GPI_RunSteps(GPI_VMState *ctx)
  1095. {
  1096.     int pc, cnt, rt;
  1097.  
  1098.     ctx->pc=0;
  1099.     ctx->nnop=0;
  1100.    
  1101.     cnt=512;
  1102.     while((cnt--)>0)
  1103.     {
  1104.         rt=GPI_InterpStep(ctx);
  1105.         if(rt>0)
  1106.             break;
  1107.     }
  1108.  
  1109.     return(cnt);
  1110. }
  1111.  
  1112.  
  1113.  
  1114. int GPI_ProgDumpOp(GPI_VMProg *prog, int pc)
  1115. {
  1116.     double f, g, h;
  1117.     char *sn;
  1118.     s64 li;
  1119.     u64 opw;
  1120.     int rd, rs, rt;
  1121.     int i0, i1, i2;
  1122.     int i, j, opn, opy, ret;
  1123.    
  1124.     ret=0;
  1125.     sn=0;
  1126.  
  1127.     opw=prog->rom[pc];
  1128.     opn=gpi_graydeco[(opw>>56)&255];
  1129.     switch(opn)
  1130.     {
  1131.     case 0x00:
  1132. //      ret=1;
  1133.         break;
  1134.     case 0x01:
  1135.         rd=gpi_graydecr[(opw>>16)&255];
  1136.         rs=gpi_graydecr[(opw>> 8)&255];
  1137.         rt=gpi_graydecr[(opw>> 0)&255];
  1138.         opy=gpi_graydeco[(opw>>48)&255];
  1139.         switch(opy)
  1140.         {
  1141.         case 0x00:  sn="ADD";   break;
  1142.         case 0x01:  sn="SUB";   break;
  1143.         case 0x02:  sn="SHAD";  break;
  1144.         case 0x03:  sn="SHLD";  break;
  1145.         case 0x04:  sn="MUL";   break;
  1146.         case 0x05:  sn="AND";   break;
  1147.         case 0x06:  sn="OR";    break;
  1148.         case 0x07:  sn="XOR";   break;
  1149.  
  1150.         case 0x08:  sn="MIN";   break;
  1151.         case 0x09:  sn="MAX";   break;
  1152.         case 0x0A:  sn="DIV";   break;
  1153.         case 0x0B:  sn="MOD";   break;
  1154.  
  1155.         case 0x0D:
  1156.             rs=rd;
  1157.         case 0x0C:
  1158.             switch(rt)
  1159.             {
  1160.             case 0x00:  sn="MOV";   break;
  1161.             }
  1162.             break;
  1163.  
  1164.         default:
  1165.             break;
  1166.         }
  1167.         if(sn)
  1168.         {
  1169.             if(opy>=0x0C)
  1170.                 printf("  %s R%d, R%d\n", sn, rs, rd);
  1171.             else
  1172.                 printf("  %s R%d, R%d, R%d\n", sn, rs, rt, rd);
  1173.         }
  1174.         break;
  1175.  
  1176.     case 0x02:
  1177.         rd=gpi_graydecr[(opw>>16)&255];
  1178.         rs=gpi_graydecr[(opw>> 8)&255];
  1179.         rt=gpi_graydecr[(opw>> 0)&255];
  1180.         opy=gpi_graydeco[(opw>>48)&255];
  1181.         switch(opy)
  1182.         {
  1183.         case 0x00:  sn="JCMPEQ";    break;
  1184.         case 0x01:  sn="JCMPGT";    break;
  1185.         case 0x02:  sn="JCMPGE";    break;
  1186.         case 0x03:  sn="BSR";       break;
  1187.  
  1188.         case 0x04:  sn="JCMPNE";    break;
  1189.         case 0x05:  sn="JCMPLE";    break;
  1190.         case 0x06:  sn="JCMPLT";    break;
  1191.         case 0x07:  sn="JMP";       break;
  1192.  
  1193.         case 0x08:  sn="JCMPFEQ";   break;
  1194.         case 0x09:  sn="JCMPFGT";   break;
  1195.         case 0x0A:  sn="JCMPFGE";   break;
  1196.  
  1197.         case 0x0C:  sn="JCMPFNE";   break;
  1198.         case 0x0D:  sn="JCMPFLE";   break;
  1199.         case 0x0E:  sn="JCMPFLT";   break;
  1200.         }
  1201.  
  1202.         if(sn)
  1203.         {
  1204.             printf("  %s R%d, R%d, L%d\n", sn, rs, rt, rd);
  1205.         }
  1206.         break;
  1207.  
  1208.     case 0x03:
  1209.         rd=gpi_graydecr[(opw>>16)&255];
  1210.         rs=gpi_graydecr[(opw>> 8)&255];
  1211.         rt=gpi_graydecr[(opw>> 0)&255];
  1212.         i0=0;
  1213.  
  1214.         opy=gpi_graydeco[(opw>>48)&255];
  1215.         switch(opy)
  1216.         {
  1217.         case 0x00:  sn="FADD";  break;
  1218.         case 0x01:  sn="FSUB";  break;
  1219.         case 0x02:  sn="FMUL";  break;
  1220.         case 0x03:  sn="FDIV";  break;
  1221.         case 0x04:  sn="FMAC";  break;
  1222.         case 0x05:
  1223.             i0=             gpi_gray8dec[(opw>>40)&255];
  1224.             i0=(i0<<8) |    gpi_gray8dec[(opw>>32)&255];
  1225.             i0=(i0<<8) |    gpi_gray8dec[(opw>>24)&255];
  1226.             sn="FMASC";
  1227.             break;
  1228.  
  1229.         case 0x06:  sn="FMIN";  break;
  1230.         case 0x07:  sn="FMAX";  break;
  1231.  
  1232.         case 0x0D:
  1233.             rs=rd;
  1234.         case 0x0C:
  1235.             switch(rt)
  1236.             {
  1237.             case 0x00:  sn="RCP";   break;
  1238.             case 0x01:  sn="SQRT";  break;
  1239.             case 0x02:  sn="ATAN";  break;
  1240.  
  1241.             case 0x04:  sn="I2F";   break;
  1242.             case 0x05:  sn="F2I";   break;
  1243.             }
  1244.             break;
  1245.  
  1246.         default:
  1247.             break;
  1248.         }
  1249.         if(sn)
  1250.         {
  1251.             if(opy>=0x0C)
  1252.                 printf("  %s R%d, R%d\n", sn, rs, rd);
  1253.             else if(i0)
  1254.                 printf("  %s R%d, R%d, %X, R%d\n", sn, rs, rt, i0, rd);
  1255.             else
  1256.                 printf("  %s R%d, R%d, R%d\n", sn, rs, rt, rd);
  1257.         }
  1258.         break;
  1259.  
  1260.     case 0x04:
  1261.         rd=gpi_graydecr[(opw>>16)&255];
  1262.         rs=gpi_graydecr[(opw>> 8)&255];
  1263.         rt=gpi_graydecr[(opw>> 0)&255];
  1264.         opy=gpi_graydeco[(opw>>48)&255];
  1265.         switch(opy)
  1266.         {
  1267.         case 0x00:  sn="PADD.F";    break;
  1268.         case 0x01:  sn="PSUB.F";    break;
  1269.         case 0x02:  sn="PMUL.F";    break;
  1270.         case 0x03:  sn="PDIV.F";    break;
  1271.         default:
  1272.             break;
  1273.         }
  1274.         if(sn)
  1275.             { printf("  %s R%d, R%d, R%d\n", sn, rs, rt, rd); }
  1276.         break;
  1277.  
  1278.     case 0x05:
  1279.         rd=gpi_graydecr[(opw>>16)&255];
  1280.         rs=gpi_graydecr[(opw>> 8)&255];
  1281.         rt=gpi_graydecr[(opw>> 0)&255];
  1282.         opy=gpi_graydeco[(opw>>48)&255];
  1283.         switch(opy)
  1284.         {
  1285.         case 0x00:  sn="PADD.H";    break;
  1286.         case 0x01:  sn="PSUB.H";    break;
  1287.         case 0x02:  sn="PMUL.H";    break;
  1288.         case 0x03:  sn="PDIV.H";    break;
  1289.         default:
  1290.             break;
  1291.         }
  1292.         if(sn)
  1293.             { printf("  %s R%d, R%d, R%d\n", sn, rs, rt, rd); }
  1294.         break;
  1295.        
  1296.     case 0x0C:
  1297.         rd=gpi_graydecr[(opw>>48)&255];
  1298.         li=             gpi_gray8dec[(opw>>40)&255];
  1299.         li=(li<<8) |    gpi_gray8dec[(opw>>32)&255];
  1300.         li=(li<<8) |    gpi_gray8dec[(opw>>24)&255];
  1301.         li=(li<<8) |    gpi_gray8dec[(opw>>16)&255];
  1302.         li=(li<<8) |    gpi_gray8dec[(opw>> 8)&255];
  1303.         li=(li<<8) |    gpi_gray8dec[(opw>> 0)&255];
  1304.         li=(li<<16)>>16;
  1305.         printf("  MOV %llX, R%d\n", li, rd);
  1306.         break;
  1307.     case 0x0D:
  1308.         rd=gpi_graydecr[(opw>>48)&255];
  1309.         li=             gpi_gray8dec[(opw>>40)&255];
  1310.         li=(li<<8) |    gpi_gray8dec[(opw>>32)&255];
  1311.         li=(li<<8) |    gpi_gray8dec[(opw>>24)&255];
  1312.         li=(li<<8) |    gpi_gray8dec[(opw>>16)&255];
  1313.         li=(li<<8) |    gpi_gray8dec[(opw>> 8)&255];
  1314.         li=(li<<8) |    gpi_gray8dec[(opw>> 0)&255];
  1315.         li=(li<<16);
  1316.         printf("  MOV %llX, R%d\n", li, rd);
  1317.         break;
  1318.     case 0x0E:
  1319.         rd=gpi_graydecr[(opw>>48)&255];
  1320.         li=             gpi_gray8dec[(opw>>40)&255];
  1321.         li=(li<<8) |    gpi_gray8dec[(opw>>32)&255];
  1322.         li=(li<<8) |    gpi_gray8dec[(opw>>24)&255];
  1323.         li=(li<<8);
  1324.         li=(li<<8) |    gpi_gray8dec[(opw>>16)&255];
  1325.         li=(li<<8) |    gpi_gray8dec[(opw>> 8)&255];
  1326.         li=(li<<8) |    gpi_gray8dec[(opw>> 0)&255];
  1327.         li=(li<<8);
  1328.         printf("  MOV %llX, R%d\n", li, rd);
  1329.         break;
  1330.     case 0x0F:
  1331.         rd=gpi_graydecr[(opw>>48)&255];
  1332.         if(!rd)
  1333.         {
  1334.             ret=1;
  1335.             break;
  1336.         }
  1337.  
  1338.         i0=             gpi_gray8dec[(opw>>40)&255];
  1339.         i0=(i0<<8) |    gpi_gray8dec[(opw>>32)&255];
  1340.         i0=(i0<<8) |    gpi_gray8dec[(opw>>24)&255];
  1341.         i1=             gpi_gray8dec[(opw>>16)&255];
  1342.         i1=(i1<<8) |    gpi_gray8dec[(opw>> 8)&255];
  1343.         i1=(i1<<8) |    gpi_gray8dec[(opw>> 0)&255];
  1344.         li=             (((i0>>12)&4095)<<4);
  1345.         li=(li<<16) |   (((i0>> 0)&4095)<<4);
  1346.         li=(li<<16) |   (((i1>>12)&4095)<<4);
  1347.         li=(li<<16) |   (((i1>> 0)&4095)<<4);
  1348.         printf("  MOV %llX, R%d\n", li, rd);
  1349.         break;
  1350.  
  1351.     default:
  1352.         /* NOP */
  1353.         break;
  1354.     }
  1355.     return(ret);
  1356. }
  1357.  
  1358. int GPI_ProgDump(GPI_VMProg *prog)
  1359. {
  1360.     int i, j, k;
  1361.    
  1362.     for(i=0; i<GPI_ROMSZ; i++)
  1363.     {
  1364.         k=GPI_ProgDumpOp(prog, i);
  1365.         if(k>0)
  1366.             break;
  1367.     }
  1368.     return(0);
  1369. }
  1370.  
  1371. u64 gpi_rngseed1;
  1372. u64 gpi_rngseed2;
  1373. u64 gpi_rngseed3;
  1374. u64 gpi_rngseed4;
  1375.  
  1376. int gpi_rand16()
  1377. {
  1378.     u64 s1, s2, s3, s4;
  1379.    
  1380.     s1=gpi_rngseed1*2147483647ULL*65521ULL;
  1381.     s2=gpi_rngseed2*2147483647ULL*65521ULL;
  1382.     s3=gpi_rngseed3*2147483647ULL*65521ULL;
  1383.     s4=gpi_rngseed4*2147483647ULL*65521ULL;
  1384.     gpi_rngseed1=s1+(gpi_rngseed4>>48)+1;
  1385.     gpi_rngseed2=s2+(gpi_rngseed1>>48)+1;
  1386.     gpi_rngseed3=s3+(gpi_rngseed2>>48)+1;
  1387.     gpi_rngseed4=s4+(gpi_rngseed3>>48)+1;
  1388.     return((u16)(s1>>48));
  1389. }
  1390.  
  1391. u64 gpi_randbits64()
  1392. {
  1393.     u64 li;
  1394.     li=             gpi_rand16();
  1395.     li=(li<<16) |   gpi_rand16();
  1396.     li=(li<<16) |   gpi_rand16();
  1397.     li=(li<<16) |   gpi_rand16();
  1398.     return(li);
  1399. }
  1400.  
  1401. int GPI_PrgBreedPair(GPI_VMProg *prga, GPI_VMProg *prgb, GPI_VMProg *prgc)
  1402. {
  1403.     byte ofstab[16]={0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4};
  1404.     u64 m;
  1405.     int i, j, k, ofs;
  1406.    
  1407.     ofs=0;
  1408.  
  1409.     k=gpi_rand16();
  1410.  
  1411. //  if((k&0xFF00)==0x0F00)
  1412.     if(0)
  1413.     {
  1414. //      ofs=(k&7);
  1415.         ofs=ofstab[k&15];
  1416. //      ofs=1;
  1417.         if(k&128)
  1418.             ofs=-ofs;
  1419.  
  1420.         for(i=0; i<GPI_ROMSZ; i++)
  1421.         {
  1422.             m=gpi_randbits64();
  1423.             j=i+ofs;
  1424.             if((j<0) || (j>=GPI_ROMSZ))
  1425.             {
  1426.                 prgc->rom[i]=m;
  1427.                 continue;
  1428.             }
  1429.             prgc->rom[i]=(prga->rom[j]&m)|(prgb->rom[j]&(~m));
  1430.         }
  1431.     }else
  1432.     {
  1433.         for(i=0; i<GPI_ROMSZ; i++)
  1434.         {
  1435.             m=gpi_randbits64();
  1436.             prgc->rom[i]=(prga->rom[i]&m)|(prgb->rom[i]&(~m));
  1437.         }
  1438.     }
  1439.  
  1440. //  for(i=0; i<64; i++)
  1441.     for(i=0; i<256; i++)
  1442. //  for(i=0; i<1024; i++)
  1443.     {
  1444.         j=gpi_rand16();
  1445.         prgc->rom[(j>>8)&255]^=(1ULL<<(j&63));
  1446.     }
  1447.    
  1448.     return(0);
  1449. }
  1450.  
  1451. int GPI_PrgBreedInit(GPI_VMProg *prg)
  1452. {
  1453.     u64 m;
  1454.     int i, j, k, ofs;
  1455.    
  1456.     for(i=0; i<GPI_ROMSZ; i++)
  1457.     {
  1458.         m=gpi_randbits64();
  1459.         for(j=0; j<256; j++)
  1460.         {
  1461. //          k=gpi_gray5decp[(m>>56)&255];
  1462.             k=gpi_graydeco[(m>>56)&255];
  1463. //          if(k==0xFF)
  1464.             if(k==0x00)
  1465.                 break;
  1466.             m^=((u64)gpi_rand16())<<48;
  1467.         }
  1468.         prg->rom[i]=m;
  1469.     }
  1470.  
  1471.     return(0);
  1472. }
  1473.  
  1474. int GPI_SetupContextInit(GPI_Context *ctx)
  1475. {
  1476.     int i, j, k;
  1477.    
  1478.     for(i=0; i<GPI_GENSZ; i++)
  1479.     {
  1480.         ctx->prog[i]=(ctx->prg_arr)+i;
  1481.         GPI_PrgBreedInit(ctx->prog[i]);
  1482.     }
  1483.  
  1484.     return(0);
  1485. }
  1486.  
  1487. int GPI_StepContext(GPI_Context *ctx)
  1488. {
  1489.     GPI_VMState tvm;
  1490.     GPI_VMProg *prg;
  1491.     GPI_VMState *vm;
  1492.     double f;
  1493.     int i0, i1;
  1494.     int i, j, k;
  1495.    
  1496.     vm=&tvm;
  1497.    
  1498.     for(i=0; i<GPI_GENSZ; i++)
  1499.     {
  1500.         vm->prog=ctx->prog[i];
  1501.         if(!(vm->prog))
  1502.         {
  1503.             ctx->prgw[i]=999999999;
  1504.             continue;
  1505.         }
  1506.  
  1507.         for(j=0; j<32; j++)
  1508.         {
  1509. //          vm->reg[j]=gpi_randbits64()|0x4000400040004000ULL;
  1510.             vm->reg[j]=gpi_randbits64()|0x7F0070007F007000ULL;
  1511.         }
  1512.  
  1513.         if(ctx->SetupState)
  1514.             ctx->SetupState(ctx, vm);
  1515.         GPI_RunSteps(vm);
  1516.         if(ctx->RankState)
  1517.             ctx->prgw[i]=ctx->RankState(ctx, vm);
  1518.     }
  1519.    
  1520.     for(i=0; i<GPI_GENSZ; i++)
  1521.     {
  1522.         for(j=i+1; j<GPI_GENSZ; j++)
  1523.         {
  1524.             if(ctx->prgw[j]<ctx->prgw[i])
  1525.             {
  1526.                 f=ctx->prgw[i];
  1527.                 ctx->prgw[i]=ctx->prgw[j];
  1528.                 ctx->prgw[j]=f;
  1529.                
  1530.                 prg=ctx->prog[i];
  1531.                 ctx->prog[i]=ctx->prog[j];
  1532.                 ctx->prog[j]=prg;
  1533.             }
  1534.         }
  1535.     }
  1536.  
  1537.     for(i=GPI_GENSEL; i<GPI_GENSZ; i++)
  1538.     {
  1539. //      j=gpi_rand16();
  1540. //      i0=(j>>0)&(GPI_GENSEL-1);
  1541. //      i1=(j>>8)&(GPI_GENSEL-1);
  1542.  
  1543.         for(j=0; j<64; j++)
  1544.         {
  1545.             i0=gpi_rand16()&4095;
  1546.             i1=gpi_rand16()&4095;
  1547.             i0=(i0*i0)>>12;
  1548.             i1=(i1*i1)>>12;
  1549.             i0=i0/(4096/GPI_GENSEL);
  1550.             i1=i1/(4096/GPI_GENSEL);
  1551.             if(i0!=i1)
  1552.                 break;
  1553.         }
  1554.        
  1555.         GPI_PrgBreedPair(
  1556.             ctx->prog[i0],
  1557.             ctx->prog[i1],
  1558.             ctx->prog[i]);
  1559.     }
  1560. }
  1561.  
  1562. void atan2_SetupState(GPI_Context *ctx, GPI_VMState *vm)
  1563. {
  1564.     double xa[8];
  1565.     double x, y, th;
  1566.     int i, j, k;
  1567.  
  1568.     j=gpi_rand16();
  1569.    
  1570. //  x=(((j>>8)&255)-127)*(1.0/32);
  1571. //  y=(((j>>0)&255)-127)*(1.0/32);
  1572.  
  1573.     y=0;
  1574.     for(i=0; i<4; i++)
  1575.     {
  1576.         x=(gpi_rand16()/16.0)-j;
  1577.         xa[i]=x;
  1578.         y=y+x;
  1579.     }
  1580.    
  1581. //  th=y/8;
  1582.     th=y;
  1583.  
  1584. //  th=atan2(y, x);
  1585.    
  1586. //  *(double *)(vm->u_reg+0)=x;
  1587. //  *(double *)(vm->u_reg+1)=y;
  1588.     *(double *)(vm->u_reg+2)=th;
  1589.  
  1590. //  *(double *)(vm->reg+4)=x;
  1591. //  *(double *)(vm->reg+5)=y;
  1592.  
  1593.     for(i=0; i<8; i++)
  1594.         *(double *)(vm->reg+4+i)=xa[i];
  1595. }
  1596.  
  1597. double atan2_RankState(GPI_Context *ctx, GPI_VMState *vm)
  1598. {
  1599.     double th0, th1, d;
  1600.     int i;
  1601.  
  1602.     th0=*(double *)(vm->u_reg+2);
  1603.     th1=*(double *)(vm->reg+2);
  1604.    
  1605.     d=(th0-th1);
  1606. //  d=(d*d)*1000000;
  1607. //  d=(d*d)*0.001;
  1608.     d=(d*d)*0.01;
  1609.     if((d>9999999) || isinf(d) || isnan(d))
  1610.         d=9999999;
  1611.  
  1612.     d+=0.00001*vm->nnop;
  1613.  
  1614.     return(d);
  1615.  
  1616. //  i=d;
  1617. //  if(i<0)
  1618. //      i=99999999;
  1619. //  i+=vm->nnop;
  1620. //  return(i);
  1621. }
  1622.  
  1623. char *gpi_print_ffixed(char *tb, double val)
  1624. {
  1625.     int hi, lo;
  1626.    
  1627.     hi=val;
  1628.     lo=(val-hi)*10000;
  1629.     sprintf(tb, "%6d.%04d", hi, lo);
  1630.     return(tb);
  1631. }
  1632.  
  1633. int main()
  1634. {
  1635.     char tb1[64];
  1636.     char tb2[64];
  1637.     GPI_Context *ctx;
  1638.     double e, le;
  1639.     int i, j, k;
  1640.  
  1641.     GPI_InitTables();
  1642. //  GPI_DumpTables();
  1643.    
  1644.     ctx=malloc(sizeof(GPI_Context));
  1645.     memset(ctx, 0, sizeof(GPI_Context));
  1646.    
  1647.     GPI_SetupContextInit(ctx);
  1648.    
  1649.     ctx->SetupState=atan2_SetupState;
  1650.     ctx->RankState=atan2_RankState;
  1651.    
  1652.     le=999999999.0;
  1653. //  for(i=0; i<4096; i++)
  1654. //  for(i=0; i<65536; i++)
  1655.     for(i=0; i<262144; i++)
  1656.     {
  1657.         e=0;
  1658.         for(j=0; j<16; j++)
  1659.             e+=ctx->prgw[j];
  1660.  
  1661.         le=(le*0.999)+(e*0.001);
  1662.  
  1663.         if((i>1024) && (le<0.001))
  1664.         {
  1665.             printf("\n");
  1666.             printf("Convergence Detected\n");
  1667.             break;
  1668.         }
  1669.  
  1670. //      printf("Gen %d, best=%d\n", i, ctx->prgw[0]);
  1671. //      printf("Gen %d, best=%-05.4f  %-06.4f  \r", i, ctx->prgw[0], e);
  1672.         printf("Gen %d, best=%s  %s  \r", i,
  1673.             gpi_print_ffixed(tb1, ctx->prgw[0]),
  1674.             gpi_print_ffixed(tb2, e));
  1675.         GPI_StepContext(ctx);
  1676. //      printf("Best w=%d\n", ctx->prgw[0]);
  1677.     }
  1678.    
  1679.     printf("\n");
  1680.    
  1681.     GPI_ProgDump(ctx->prog[0]);
  1682. }
  1683.  
Advertisement
Add Comment
Please, Sign In to add comment