Example #1
0
void sum_statistics(COUNTER *ptotalstats, COUNTER *pstats)
{
  int i;
  COUNTER tmp;

  for(i=0; i<MaxStat; i++)
  {
    Add_Counter(tmp,pstats[i],ptotalstats[i]);
    ptotalstats[i]=tmp;
  }
}
Example #2
0
DBL POVFPU_RunDefault(FUNCTION fn)
{
	StackFrame *pstack = POVFPU_Current_Context->pstackbase;
	DBL *dblstack = POVFPU_Current_Context->dblstackbase;
	unsigned int maxdblstacksize = POVFPU_Current_Context->maxdblstacksize;
	DBL r0, r1, r2, r3, r4, r5, r6, r7;
	Instruction *program = NULL;
	unsigned int k = 0;
	unsigned int pc = 0;
	unsigned int ccr = 0;
	unsigned int sp = 0;
	unsigned int psp = 0;

#if (SUPPORT_INTEGER_INSTRUCTIONS == 1)
	POV_LONG iA, iB, itemp;
#endif

#if (DEBUG_DEFAULTCPU == 1)
	COUNTER instr;
	Long_To_Counter(POVFPU_Functions[fn].fn.program_size, instr);
	Add_Counter(stats[Ray_Function_VM_Instruction_Est], stats[Ray_Function_VM_Instruction_Est], instr);
#endif

	Increase_Counter(stats[Ray_Function_VM_Calls]);

	program = POVFPU_Functions[fn].fn.program;

	while(true)
	{
		k = GET_K(program[pc]);
		switch(GET_OP(program[pc]))
		{
			OP_MATH_AOP(0,+);           // add   Rs, Rd
			OP_MATH_AOP(1,-);           // sub   Rs, Rd
			OP_MATH_AOP(2,*);           // mul   Rs, Rd
			OP_MATH_AOP(3,/);           // div   Rs, Rd
			OP_MOD_A(4);                // mod   Rs, Rd

			OP_ASSIGN_ABOP(5,0,r0);     // move  R0, Rd
			OP_ASSIGN_ABOP(5,1,r1);     // move  R1, Rd
			OP_ASSIGN_ABOP(5,2,r2);     // move  R2, Rd
			OP_ASSIGN_ABOP(5,3,r3);     // move  R3, Rd
			OP_ASSIGN_ABOP(5,4,r4);     // move  R4, Rd
			OP_ASSIGN_ABOP(5,5,r5);     // move  R5, Rd
			OP_ASSIGN_ABOP(5,6,r6);     // move  R6, Rd
			OP_ASSIGN_ABOP(5,7,r7);     // move  R7, Rd

			OP_CMP_ABC(6,0,r0);         // cmp   R0, Rd
			OP_CMP_ABC(6,1,r1);         // cmp   R1, Rd
			OP_CMP_ABC(6,2,r2);         // cmp   R2, Rd
			OP_CMP_ABC(6,3,r3);         // cmp   R3, Rd
			OP_CMP_ABC(6,4,r4);         // cmp   R4, Rd
			OP_CMP_ABC(6,5,r5);         // cmp   R5, Rd
			OP_CMP_ABC(6,6,r6);         // cmp   R6, Rd
			OP_CMP_ABC(6,7,r7);         // cmp   R7, Rd

			OP_ASSIGN_ABOP(7,0,-r0);    // neg   R0, Rd
			OP_ASSIGN_ABOP(7,1,-r1);    // neg   R1, Rd
			OP_ASSIGN_ABOP(7,2,-r2);    // neg   R2, Rd
			OP_ASSIGN_ABOP(7,3,-r3);    // neg   R3, Rd
			OP_ASSIGN_ABOP(7,4,-r4);    // neg   R4, Rd
			OP_ASSIGN_ABOP(7,5,-r5);    // neg   R5, Rd
			OP_ASSIGN_ABOP(7,6,-r6);    // neg   R6, Rd
			OP_ASSIGN_ABOP(7,7,-r7);    // neg   R7, Rd

			OP_ABS_A(8);                // abs   Rs, Rd

			OP_MATH_ABCOP(9,0,POVFPU_Consts[k],+);      // addi  k, Rd
			OP_MATH_ABCOP(9,1,POVFPU_Consts[k],-);      // subi  k, Rd
			OP_MATH_ABCOP(9,2,POVFPU_Consts[k],*);      // muli  k, Rd
			OP_MATH_ABCOP(9,3,POVFPU_Consts[k],/);      // divi  k, Rd
			OP_MOD_ABC(9,4,POVFPU_Consts[k]);           // modi  k, Rd
			OP_ASSIGN_ABOP(9,5,POVFPU_Consts[k]);       // loadi k, Rd

			OP_CMP_ABC(9,6,POVFPU_Consts[k]);           // cmpi  k, Rs

			OP_ASSIGN_ABOP(10,0,ccr == 1);              // seq   Rd
			OP_ASSIGN_ABOP(10,1,ccr != 1);              // sne   Rd
			OP_ASSIGN_ABOP(10,2,ccr == 2);              // slt   Rd
			OP_ASSIGN_ABOP(10,3,ccr >= 1);              // sle   Rd
			OP_ASSIGN_ABOP(10,4,ccr == 0);              // sgt   Rd
			OP_ASSIGN_ABOP(10,5,ccr <= 1);              // sge   Rd
			OP_MATH_ABCOP(10,6,0.0,==);                 // teq   Rd
			OP_MATH_ABCOP(10,7,0.0,!=);                 // tne   Rd

			OP_ASSIGN_ABOP(11,0,POVFPU_Globals[k]);     // load  0(k), Rd
			OP_ASSIGN_ABOP(11,1,dblstack[sp+k]);        // load  SP(k), Rd

			OP_REVASSIGN_ABOP(12,0,POVFPU_Globals[k]);  // store Rs, 0(k)
			OP_REVASSIGN_ABOP(12,1,dblstack[sp+k]);     // store Rs, SP(k)

			OP_SPECIAL(13,0,0,if(ccr == 1) pc = k - 1); // beq   k
			OP_SPECIAL(13,1,0,if(ccr != 1) pc = k - 1); // bne   k
			OP_SPECIAL(13,2,0,if(ccr == 2) pc = k - 1); // blt   k
			OP_SPECIAL(13,3,0,if(ccr >= 1) pc = k - 1); // ble   k
			OP_SPECIAL(13,4,0,if(ccr == 0) pc = k - 1); // bgt   k
			OP_SPECIAL(13,5,0,if(ccr <= 1) pc = k - 1); // bge   k

			OP_XCC_ABOP(14,0,==);                       // xeq   Rd
			OP_XCC_ABOP(14,1,!=);                       // xne   Rd
			OP_XCC_ABOP(14,2,<);                        // xlt   Rd
			OP_XCC_ABOP(14,3,<=);                       // xle   Rd
			OP_XCC_ABOP(14,4,>);                        // xgt   Rd
			OP_XCC_ABOP(14,5,>=);                       // xge   Rd

			OP_SPECIAL(14,6,0,if((r0 == 0.0) && (r0 == 0.0)) POVFPU_Exception(fn)); // xdz   R0, R0
			OP_SPECIAL(14,6,1,if((r0 == 0.0) && (r1 == 0.0)) POVFPU_Exception(fn)); // xdz   R0, R1
			OP_SPECIAL(14,6,2,if((r0 == 0.0) && (r2 == 0.0)) POVFPU_Exception(fn)); // xdz   R0, R2
			OP_SPECIAL(14,6,3,if((r0 == 0.0) && (r3 == 0.0)) POVFPU_Exception(fn)); // xdz   R0, R3
			OP_SPECIAL(14,6,4,if((r0 == 0.0) && (r4 == 0.0)) POVFPU_Exception(fn)); // xdz   R0, R4
			OP_SPECIAL(14,6,5,if((r0 == 0.0) && (r5 == 0.0)) POVFPU_Exception(fn)); // xdz   R0, R5
			OP_SPECIAL(14,6,6,if((r0 == 0.0) && (r6 == 0.0)) POVFPU_Exception(fn)); // xdz   R0, R6
			OP_SPECIAL(14,6,7,if((r0 == 0.0) && (r7 == 0.0)) POVFPU_Exception(fn)); // xdz   R0, R7

			OP_SPECIAL_CASE(15,0,0)                     // jsr   k
				pstack[psp].pc = pc;
				pstack[psp].fn = fn;
				psp++;
				if(psp >= MAX_CALL_STACK_SIZE)
					POVFPU_Exception(fn, "Maximum function evaluation recursion level reached.");
				pc = k;
				continue; // prevent increment of pc
			OP_SPECIAL_CASE(15,0,1)                     // jmp   k
				pc = k;
				continue; // prevent increment of pc
			OP_SPECIAL_CASE(15,0,2)                     // rts
				if(psp == 0)
					return r0;
				psp--;
				pc = pstack[psp].pc; // old position, will be incremented
				fn = pstack[psp].fn;
				program = POVFPU_Functions[fn].fn.program;
				break;
			OP_SPECIAL_CASE(15,0,3)                     // call  k
				pstack[psp].pc = pc;
				pstack[psp].fn = fn;
				psp++;
				if(psp >= MAX_CALL_STACK_SIZE)
					POVFPU_Exception(fn, "Maximum function evaluation recursion level reached.");
				fn = k;
				program = POVFPU_Functions[fn].fn.program;
				pc = 0;
				continue; // prevent increment of pc

			OP_SPECIAL_CASE(15,0,4)                     // sys1  k
				r0 = POVFPU_Sys1Table[k](r0);
				break;
			OP_SPECIAL_CASE(15,0,5)                     // sys2  k
				r0 = POVFPU_Sys2Table[k](r0,r1);
				break;
			OP_SPECIAL_CASE(15,0,6)                     // trap  k
				r0 = POVFPU_TrapTable[k].fn(&dblstack[sp], fn);
				maxdblstacksize = POVFPU_Current_Context->maxdblstacksize;
				dblstack = POVFPU_Current_Context->dblstackbase;
				break;
			OP_SPECIAL_CASE(15,0,7)                     // traps k
				POVFPU_TrapSTable[k].fn(&dblstack[sp], fn, sp);
				maxdblstacksize = POVFPU_Current_Context->maxdblstacksize;
				dblstack = POVFPU_Current_Context->dblstackbase;
				break;

			OP_SPECIAL_CASE(15,1,0)                     // grow  k
				if((unsigned int)((unsigned int)sp + (unsigned int)k) >= (unsigned int)MAX_K)
				{
					POVFPU_Exception(fn, "Stack full. Possible infinite recursive function call.");
				}
				else if(sp + k >= maxdblstacksize)
				{
					maxdblstacksize = POVFPU_Current_Context->maxdblstacksize = POVFPU_Current_Context->maxdblstacksize + max(k + 1, (unsigned int)256);
					dblstack = POVFPU_Current_Context->dblstackbase = (DBL *)POV_REALLOC(dblstack, sizeof(DBL) * maxdblstacksize, "fn: stack");
				}
				break;
			OP_SPECIAL_CASE(15,1,1)                     // push  k
				if(sp + k >= maxdblstacksize)
					POVFPU_Exception(fn, "Function evaluation stack overflow.");
				sp += k;
				break;
			OP_SPECIAL_CASE(15,1,2)                     // pop   k
				if(k > sp)
					POVFPU_Exception(fn, "Function evaluation stack underflow.");
				sp -= k;
				break;
#if (SUPPORT_INTEGER_INSTRUCTIONS == 1)
			OP_SPECIAL_CASE(15,1,3)                     // iconv
				iA = POV_LONG(r0);
				break;
			OP_SPECIAL_CASE(15,1,4)                     // fconv
				r0 = DBL(iA);
				break;

			OP_SPECIAL_CASE(15,1,5)                     // reserved
				POVFPU_Exception(fn, "Internal error - reserved function VM opcode found!");
				break;

			OP_INT_MATH_ABOP(15,32,+);                  // add   s, d
			OP_INT_MATH_ABOP(15,33,-);                  // sub   s, d
			OP_INT_MATH_ABOP(15,34,*);                  // mul   s, d
			OP_INT_SPECIAL(15,35,0,iA = iA / iB);       // div   B, A
			OP_INT_SPECIAL(15,35,1,iB = iB / iA);       // div   A, B
			OP_INT_SPECIAL(15,35,2,iA = iA % iB);       // mod   B, A
			OP_INT_SPECIAL(15,35,3,iB = iB % iA);       // mod   A, B

			OP_INT_SPECIAL(15,36,0,ccr = (((iB > iA) & 1) << 1) | ((iB == iA) & 1)); // cmp   B, A
			OP_INT_SPECIAL(15,36,1,ccr = (((iA > iB) & 1) << 1) | ((iA == iB) & 1)); // cmp   A, B

			OP_INT_SPECIAL(15,36,2,itemp = iA; iA = iB; iB = itemp); // exg   A, B

			OP_INT_SPECIAL(15,36,3,iA = iB = 0);        // clr   A, B
			OP_INT_SPECIAL(15,37,0,iA = 0);             // clr   A
			OP_INT_SPECIAL(15,37,1,iB = 0);             // clr   B

			OP_INT_SPECIAL(15,37,2,iA = iB);            // move  B, A
			OP_INT_SPECIAL(15,37,3,iB = iA);            // move  A, B

			OP_INT_SPECIAL(15,38,0,iA = -iA);           // neg   A
			OP_INT_SPECIAL(15,38,1,iB = -iB);           // neg   B

			OP_INT_SPECIAL(15,38,2,iA = abs(iA));       // abs   A
			OP_INT_SPECIAL(15,38,3,iB = abs(iB));       // abs   B

			OP_INT_SPECIAL(15,39,0,iA = iA + k);        // addi  k, A
			OP_INT_SPECIAL(15,39,1,iB = iB + k);        // addi  k, B
			OP_INT_SPECIAL(15,39,2,iA = iA - k);        // subi  k, A
			OP_INT_SPECIAL(15,39,3,iB = iB - k);        // subi  k, B

			OP_INT_MATH_SHIFT_ABOP(15,40,<<,POV_LONG);     // asl   s, d
			OP_INT_MATH_SHIFT_ABOP(15,41,>>,POV_LONG);     // asr   s, d
			OP_INT_MATH_SHIFT_ABOP(15,42,<<,POV_ULONG);    // lsl   s, d
			OP_INT_MATH_SHIFT_ABOP(15,43,>>,POV_ULONG);    // lsr   s, d

			OP_INT_MATH_ABOP(15,44,&);                  // and   s, d
			OP_INT_MATH_ABOP(15,45,|);                  // or    s, d
			OP_INT_MATH_ABOP(15,46,^);                  // xor   s, d
			OP_INT_SPECIAL(15,47,0,iA = !iA);           // not   A, A
			OP_INT_SPECIAL(15,47,1,iA = !iB);           // not   B, A
			OP_INT_SPECIAL(15,47,2,iB = !iA);           // not   A, B
			OP_INT_SPECIAL(15,47,3,iB = !iB);           // not   B, B

			OP_INT_SPECIAL(15,48,0,iA = k);             // loadi A
			OP_INT_SPECIAL(15,48,1,iB = k);             // loadi B
			OP_INT_SPECIAL(15,48,2,iA = (iA << 16) | k);// ldhi  A
			OP_INT_SPECIAL(15,48,3,iB = (iB << 16) | k);// ldhi  B

			OP_INT_SPECIAL(15,49,0,iA = max(POV_LONG(k), iA)); // max   k, A
			OP_INT_SPECIAL(15,49,1,iB = max(POV_LONG(k), iB)); // max   k, B
			OP_INT_SPECIAL(15,49,2,iA = min(POV_LONG(k), iA)); // min   k, A
			OP_INT_SPECIAL(15,49,3,iB = min(POV_LONG(k), iB)); // min   k, B

			OP_INT_SPECIAL(15,50,0,iA = (POV_LONG(iA) << k));  // asl   k, A
			OP_INT_SPECIAL(15,50,1,iB = (POV_LONG(iB) >> k));  // asr   k, B
			OP_INT_SPECIAL(15,50,2,iA = (POV_ULONG(iA) << k)); // lsl   k, A
			OP_INT_SPECIAL(15,50,3,iB = (POV_ULONG(iB) >> k)); // lsr   k, B
#endif
			default:                                    // nop
				break;
		}

		pc++;
	}

#if (DEBUG_DEFAULTCPU == 1)
	printf("Registers\n");
	printf("=========\n");
	printf("PC = %d\n", (int)pc);
	printf("CCR = %x\n", (int)ccr);
	printf("R0 = %8f   R4 = %8f\n", (float)r0, (float)r4);
	printf("R1 = %8f   R5 = %8f\n", (float)r1, (float)r5);
	printf("R2 = %8f   R6 = %8f\n", (float)r2, (float)r6);
	printf("R3 = %8f   R7 = %8f\n", (float)r3, (float)r7);
#endif
}