Main Page | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

vm_local.h File Reference

#include "../game/q_shared.h"
#include "qcommon.h"

Include dependency graph for vm_local.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Data Structures

struct  vm_s
struct  vmSymbol_s

Defines

#define VM_OFFSET_PROGRAM_STACK   0
#define VM_OFFSET_SYSTEM_CALL   4

Typedefs

typedef int vmptr_t
typedef vmSymbol_s vmSymbol_t

Enumerations

enum  opcode_t {
  OP_UNDEF, OP_IGNORE, OP_BREAK, OP_ENTER,
  OP_LEAVE, OP_CALL, OP_PUSH, OP_POP,
  OP_CONST, OP_LOCAL, OP_JUMP, OP_EQ,
  OP_NE, OP_LTI, OP_LEI, OP_GTI,
  OP_GEI, OP_LTU, OP_LEU, OP_GTU,
  OP_GEU, OP_EQF, OP_NEF, OP_LTF,
  OP_LEF, OP_GTF, OP_GEF, OP_LOAD1,
  OP_LOAD2, OP_LOAD4, OP_STORE1, OP_STORE2,
  OP_STORE4, OP_ARG, OP_BLOCK_COPY, OP_SEX8,
  OP_SEX16, OP_NEGI, OP_ADD, OP_SUB,
  OP_DIVI, OP_DIVU, OP_MODI, OP_MODU,
  OP_MULI, OP_MULU, OP_BAND, OP_BOR,
  OP_BXOR, OP_BCOM, OP_LSH, OP_RSHI,
  OP_RSHU, OP_NEGF, OP_ADDF, OP_SUBF,
  OP_DIVF, OP_MULF, OP_CVIF, OP_CVFI
}

Functions

int VM_CallCompiled (vm_t *vm, int *args)
int VM_CallInterpreted (vm_t *vm, int *args)
void VM_Compile (vm_t *vm, vmHeader_t *header)
void VM_LogSyscalls (int *args)
void VM_PrepareInterpreter (vm_t *vm, vmHeader_t *header)
int VM_SymbolToValue (vm_t *vm, const char *symbol)
vmSymbol_tVM_ValueToFunctionSymbol (vm_t *vm, int value)
const char * VM_ValueToSymbol (vm_t *vm, int value)

Variables

vm_tcurrentVM
int vm_debugLevel


Define Documentation

#define VM_OFFSET_PROGRAM_STACK   0
 

Definition at line 123 of file vm_local.h.

#define VM_OFFSET_SYSTEM_CALL   4
 

Definition at line 124 of file vm_local.h.


Typedef Documentation

typedef int vmptr_t
 

Definition at line 114 of file vm_local.h.

typedef struct vmSymbol_s vmSymbol_t
 

Referenced by VM_CallInterpreted(), VM_LoadSymbols(), VM_ProfileSort(), VM_SymbolToValue(), VM_ValueToFunctionSymbol(), VM_ValueToSymbol(), and VM_VmProfile_f().


Enumeration Type Documentation

enum opcode_t
 

Enumeration values:
OP_UNDEF 
OP_IGNORE 
OP_BREAK 
OP_ENTER 
OP_LEAVE 
OP_CALL 
OP_PUSH 
OP_POP 
OP_CONST 
OP_LOCAL 
OP_JUMP 
OP_EQ 
OP_NE 
OP_LTI 
OP_LEI 
OP_GTI 
OP_GEI 
OP_LTU 
OP_LEU 
OP_GTU 
OP_GEU 
OP_EQF 
OP_NEF 
OP_LTF 
OP_LEF 
OP_GTF 
OP_GEF 
OP_LOAD1 
OP_LOAD2 
OP_LOAD4 
OP_STORE1 
OP_STORE2 
OP_STORE4 
OP_ARG 
OP_BLOCK_COPY 
OP_SEX8 
OP_SEX16 
OP_NEGI 
OP_ADD 
OP_SUB 
OP_DIVI 
OP_DIVU 
OP_MODI 
OP_MODU 
OP_MULI 
OP_MULU 
OP_BAND 
OP_BOR 
OP_BXOR 
OP_BCOM 
OP_LSH 
OP_RSHI 
OP_RSHU 
OP_NEGF 
OP_ADDF 
OP_SUBF 
OP_DIVF 
OP_MULF 
OP_CVIF 
OP_CVFI 

Definition at line 25 of file vm_local.h.

00025              {
00026     OP_UNDEF, 
00027 
00028     OP_IGNORE, 
00029 
00030     OP_BREAK,
00031 
00032     OP_ENTER,
00033     OP_LEAVE,
00034     OP_CALL,
00035     OP_PUSH,
00036     OP_POP,
00037 
00038     OP_CONST,
00039     OP_LOCAL,
00040 
00041     OP_JUMP,
00042 
00043     //-------------------
00044 
00045     OP_EQ,
00046     OP_NE,
00047 
00048     OP_LTI,
00049     OP_LEI,
00050     OP_GTI,
00051     OP_GEI,
00052 
00053     OP_LTU,
00054     OP_LEU,
00055     OP_GTU,
00056     OP_GEU,
00057 
00058     OP_EQF,
00059     OP_NEF,
00060 
00061     OP_LTF,
00062     OP_LEF,
00063     OP_GTF,
00064     OP_GEF,
00065 
00066     //-------------------
00067 
00068     OP_LOAD1,
00069     OP_LOAD2,
00070     OP_LOAD4,
00071     OP_STORE1,
00072     OP_STORE2,
00073     OP_STORE4,              // *(stack[top-1]) = stack[top]
00074     OP_ARG,
00075 
00076     OP_BLOCK_COPY,
00077 
00078     //-------------------
00079 
00080     OP_SEX8,
00081     OP_SEX16,
00082 
00083     OP_NEGI,
00084     OP_ADD,
00085     OP_SUB,
00086     OP_DIVI,
00087     OP_DIVU,
00088     OP_MODI,
00089     OP_MODU,
00090     OP_MULI,
00091     OP_MULU,
00092 
00093     OP_BAND,
00094     OP_BOR,
00095     OP_BXOR,
00096     OP_BCOM,
00097 
00098     OP_LSH,
00099     OP_RSHI,
00100     OP_RSHU,
00101 
00102     OP_NEGF,
00103     OP_ADDF,
00104     OP_SUBF,
00105     OP_DIVF,
00106     OP_MULF,
00107 
00108     OP_CVIF,
00109     OP_CVFI
00110 } opcode_t;


Function Documentation

int VM_CallCompiled vm_t vm,
int *  args
 

Definition at line 1164 of file vm_ppc.c.

References vm_t.

Referenced by VM_Call().

01164                                            {
01165     int     stack[1024];
01166     int     programStack;
01167     int     stackOnEntry;
01168     byte    *image;
01169 
01170     currentVM = vm;
01171 
01172     // interpret the code
01173     vm->currentlyInterpreting = qtrue;
01174 
01175     // we might be called recursively, so this might not be the very top
01176     programStack = vm->programStack;
01177     stackOnEntry = programStack;
01178     image = vm->dataBase;
01179     
01180     // set up the stack frame 
01181     programStack -= 48;
01182 
01183     *(int *)&image[ programStack + 44] = args[9];
01184     *(int *)&image[ programStack + 40] = args[8];
01185     *(int *)&image[ programStack + 36] = args[7];
01186     *(int *)&image[ programStack + 32] = args[6];
01187     *(int *)&image[ programStack + 28] = args[5];
01188     *(int *)&image[ programStack + 24] = args[4];
01189     *(int *)&image[ programStack + 20] = args[3];
01190     *(int *)&image[ programStack + 16] = args[2];
01191     *(int *)&image[ programStack + 12] = args[1];
01192     *(int *)&image[ programStack + 8 ] = args[0];
01193     *(int *)&image[ programStack + 4 ] = 0; // return stack
01194     *(int *)&image[ programStack ] = -1;    // will terminate the loop on return
01195 
01196     // off we go into generated code...
01197     // the PPC calling standard says the parms will all go into R3 - R11, so 
01198     // no special asm code is needed here
01199 #ifdef __GNUC__
01200     ((void(*)(int, int, int, int, int, int, int, int))(vm->codeBase))( 
01201         programStack, (int)&stack, 
01202         (int)image, vm->dataMask, (int)&AsmCall, 
01203         (int)vm->instructionPointers, vm->instructionPointersLength,
01204         (int)vm );
01205 #else
01206     ((void(*)(int, int, int, int, int, int, int, int))(vm->codeBase))( 
01207         programStack, (int)&stack, 
01208         (int)image, vm->dataMask, *(int *)&AsmCall /* skip function pointer header */, 
01209         (int)vm->instructionPointers, vm->instructionPointersLength,
01210         (int)vm );
01211 #endif
01212     vm->programStack = stackOnEntry;
01213 
01214     vm->currentlyInterpreting = qfalse;
01215 
01216     return stack[1];
01217 }

int VM_CallInterpreted vm_t vm,
int *  args
 

Definition at line 313 of file vm_interpreted.c.

References vm_s::breakCount, vm_s::breakFunction, byte, vm_s::callLevel, vm_s::codeBase, vm_s::codeLength, Com_Error(), Com_Printf(), count, vm_s::currentlyInterpreting, vm_s::dataBase, vm_s::dataMask, DEBUGSTR, ERR_DROP, i, vm_s::instructionPointers, OP_ADD, OP_ADDF, OP_ARG, OP_BAND, OP_BCOM, OP_BLOCK_COPY, OP_BOR, OP_BREAK, OP_BXOR, OP_CALL, OP_CONST, OP_CVFI, OP_CVIF, OP_DIVF, OP_DIVI, OP_DIVU, OP_ENTER, OP_EQ, OP_EQF, OP_GEF, OP_GEI, OP_GEU, OP_GTF, OP_GTI, OP_GTU, OP_JUMP, OP_LEAVE, OP_LEF, OP_LEI, OP_LEU, OP_LOAD1, OP_LOAD2, OP_LOAD4, OP_LOCAL, OP_LSH, OP_LTF, OP_LTI, OP_LTU, OP_MODI, OP_MODU, OP_MULF, OP_MULI, OP_MULU, OP_NE, OP_NEF, OP_NEGF, OP_NEGI, OP_POP, OP_PUSH, OP_RSHI, OP_RSHU, OP_SEX16, OP_SEX8, OP_STORE1, OP_STORE2, OP_STORE4, OP_SUB, OP_SUBF, vmSymbol_s::profileCount, vm_s::programStack, r, r2, src, vm_s::stackBottom, vm_s::systemCall, v1, VM_Debug(), vm_debugLevel, vm_t, VM_ValueToFunctionSymbol(), VM_ValueToSymbol(), and vmSymbol_t.

Referenced by VM_Call().

00313                                               {
00314     int     stack[MAX_STACK];
00315     int     *opStack;
00316     int     programCounter;
00317     int     programStack;
00318     int     stackOnEntry;
00319     byte    *image;
00320     int     *codeImage;
00321     int     v1;
00322     int     dataMask;
00323 #ifdef DEBUG_VM
00324     vmSymbol_t  *profileSymbol;
00325 #endif
00326 
00327     // interpret the code
00328     vm->currentlyInterpreting = qtrue;
00329 
00330     // we might be called recursively, so this might not be the very top
00331     programStack = stackOnEntry = vm->programStack;
00332 
00333 #ifdef DEBUG_VM
00334     profileSymbol = VM_ValueToFunctionSymbol( vm, 0 );
00335     // uncomment this for debugging breakpoints
00336     vm->breakFunction = 0;
00337 #endif
00338     // set up the stack frame 
00339 
00340     image = vm->dataBase;
00341     codeImage = (int *)vm->codeBase;
00342     dataMask = vm->dataMask;
00343     
00344     // leave a free spot at start of stack so
00345     // that as long as opStack is valid, opStack-1 will
00346     // not corrupt anything
00347     opStack = stack;
00348     programCounter = 0;
00349 
00350     programStack -= 48;
00351 
00352     *(int *)&image[ programStack + 44] = args[9];
00353     *(int *)&image[ programStack + 40] = args[8];
00354     *(int *)&image[ programStack + 36] = args[7];
00355     *(int *)&image[ programStack + 32] = args[6];
00356     *(int *)&image[ programStack + 28] = args[5];
00357     *(int *)&image[ programStack + 24] = args[4];
00358     *(int *)&image[ programStack + 20] = args[3];
00359     *(int *)&image[ programStack + 16] = args[2];
00360     *(int *)&image[ programStack + 12] = args[1];
00361     *(int *)&image[ programStack + 8 ] = args[0];
00362     *(int *)&image[ programStack + 4 ] = 0; // return stack
00363     *(int *)&image[ programStack ] = -1;    // will terminate the loop on return
00364 
00365     vm->callLevel = 0;
00366     
00367     VM_Debug(0);
00368 
00369 //  vm_debugLevel=2;
00370     // main interpreter loop, will exit when a LEAVE instruction
00371     // grabs the -1 program counter
00372 
00373 #define r2 codeImage[programCounter]
00374 
00375     while ( 1 ) {
00376         int     opcode, r0, r1;
00377 //      unsigned int    r2;
00378 
00379 nextInstruction:
00380         r0 = ((int *)opStack)[0];
00381         r1 = ((int *)opStack)[-1];
00382 nextInstruction2:
00383         opcode = codeImage[ programCounter++ ];
00384 #ifdef DEBUG_VM
00385         if ( (unsigned)programCounter > vm->codeLength ) {
00386             Com_Error( ERR_DROP, "VM pc out of range" );
00387         }
00388 
00389         if ( opStack < stack ) {
00390             Com_Error( ERR_DROP, "VM opStack underflow" );
00391         }
00392         if ( opStack >= stack+MAX_STACK ) {
00393             Com_Error( ERR_DROP, "VM opStack overflow" );
00394         }
00395 
00396         if ( programStack <= vm->stackBottom ) {
00397             Com_Error( ERR_DROP, "VM stack overflow" );
00398         }
00399 
00400         if ( programStack & 3 ) {
00401             Com_Error( ERR_DROP, "VM program stack misaligned" );
00402         }
00403 
00404         if ( vm_debugLevel > 1 ) {
00405             Com_Printf( "%s %s\n", DEBUGSTR, opnames[opcode] );
00406         }
00407         profileSymbol->profileCount++;
00408 #endif
00409 
00410         switch ( opcode ) {
00411 #ifdef DEBUG_VM
00412         default:
00413             Com_Error( ERR_DROP, "Bad VM instruction" );  // this should be scanned on load!
00414 #endif
00415         case OP_BREAK:
00416             vm->breakCount++;
00417             goto nextInstruction2;
00418         case OP_CONST:
00419             opStack++;
00420             r1 = r0;
00421             r0 = *opStack = r2;
00422             
00423             programCounter += 4;
00424             goto nextInstruction2;
00425         case OP_LOCAL:
00426             opStack++;
00427             r1 = r0;
00428             r0 = *opStack = r2+programStack;
00429 
00430             programCounter += 4;
00431             goto nextInstruction2;
00432 
00433         case OP_LOAD4:
00434 #ifdef DEBUG_VM
00435             if ( *opStack & 3 ) {
00436                 Com_Error( ERR_DROP, "OP_LOAD4 misaligned" );
00437             }
00438 #endif
00439             r0 = *opStack = *(int *)&image[ r0&dataMask ];
00440             goto nextInstruction2;
00441         case OP_LOAD2:
00442             r0 = *opStack = *(unsigned short *)&image[ r0&dataMask ];
00443             goto nextInstruction2;
00444         case OP_LOAD1:
00445             r0 = *opStack = image[ r0&dataMask ];
00446             goto nextInstruction2;
00447 
00448         case OP_STORE4:
00449             *(int *)&image[ r1&(dataMask & ~3) ] = r0;
00450             opStack -= 2;
00451             goto nextInstruction;
00452         case OP_STORE2:
00453             *(short *)&image[ r1&(dataMask & ~1) ] = r0;
00454             opStack -= 2;
00455             goto nextInstruction;
00456         case OP_STORE1:
00457             image[ r1&dataMask ] = r0;
00458             opStack -= 2;
00459             goto nextInstruction;
00460 
00461         case OP_ARG:
00462             // single byte offset from programStack
00463             *(int *)&image[ codeImage[programCounter] + programStack ] = r0;
00464             opStack--;
00465             programCounter += 1;
00466             goto nextInstruction;
00467 
00468         case OP_BLOCK_COPY:
00469             {
00470                 int     *src, *dest;
00471                 int     i, count, srci, desti;
00472 
00473                 count = r2;
00474                 // MrE: copy range check
00475                 srci = r0 & dataMask;
00476                 desti = r1 & dataMask;
00477                 count = ((srci + count) & dataMask) - srci;
00478                 count = ((desti + count) & dataMask) - desti;
00479 
00480                 src = (int *)&image[ r0&dataMask ];
00481                 dest = (int *)&image[ r1&dataMask ];
00482                 if ( ( (int)src | (int)dest | count ) & 3 ) {
00483                     Com_Error( ERR_DROP, "OP_BLOCK_COPY not dword aligned" );
00484                 }
00485                 count >>= 2;
00486                 for ( i = count-1 ; i>= 0 ; i-- ) {
00487                     dest[i] = src[i];
00488                 }
00489                 programCounter += 4;
00490                 opStack -= 2;
00491             }
00492             goto nextInstruction;
00493 
00494         case OP_CALL:
00495             // save current program counter
00496             *(int *)&image[ programStack ] = programCounter;
00497             
00498             // jump to the location on the stack
00499             programCounter = r0;
00500             opStack--;
00501             if ( programCounter < 0 ) {
00502                 // system call
00503                 int     r;
00504                 int     temp;
00505 #ifdef DEBUG_VM
00506                 int     stomped;
00507 
00508                 if ( vm_debugLevel ) {
00509                     Com_Printf( "%s---> systemcall(%i)\n", DEBUGSTR, -1 - programCounter );
00510                 }
00511 #endif
00512                 // save the stack to allow recursive VM entry
00513                 temp = vm->callLevel;
00514                 vm->programStack = programStack - 4;
00515 #ifdef DEBUG_VM
00516                 stomped = *(int *)&image[ programStack + 4 ];
00517 #endif
00518                 *(int *)&image[ programStack + 4 ] = -1 - programCounter;
00519 
00520 //VM_LogSyscalls( (int *)&image[ programStack + 4 ] );
00521                 r = vm->systemCall( (int *)&image[ programStack + 4 ] );
00522 
00523 #ifdef DEBUG_VM
00524                 // this is just our stack frame pointer, only needed
00525                 // for debugging
00526                 *(int *)&image[ programStack + 4 ] = stomped;
00527 #endif
00528 
00529                 // save return value
00530                 opStack++;
00531                 *opStack = r;
00532                 programCounter = *(int *)&image[ programStack ];
00533                 vm->callLevel = temp;
00534 #ifdef DEBUG_VM
00535                 if ( vm_debugLevel ) {
00536                     Com_Printf( "%s<--- %s\n", DEBUGSTR, VM_ValueToSymbol( vm, programCounter ) );
00537                 }
00538 #endif
00539             } else {
00540                 programCounter = vm->instructionPointers[ programCounter ];
00541             }
00542             goto nextInstruction;
00543 
00544         // push and pop are only needed for discarded or bad function return values
00545         case OP_PUSH:
00546             opStack++;
00547             goto nextInstruction;
00548         case OP_POP:
00549             opStack--;
00550             goto nextInstruction;
00551 
00552         case OP_ENTER:
00553 #ifdef DEBUG_VM
00554             profileSymbol = VM_ValueToFunctionSymbol( vm, programCounter );
00555 #endif
00556             // get size of stack frame
00557             v1 = r2;
00558 
00559             programCounter += 4;
00560             programStack -= v1;
00561 #ifdef DEBUG_VM
00562             // save old stack frame for debugging traces
00563             *(int *)&image[programStack+4] = programStack + v1;
00564             if ( vm_debugLevel ) {
00565                 Com_Printf( "%s---> %s\n", DEBUGSTR, VM_ValueToSymbol( vm, programCounter - 5 ) );
00566                 if ( vm->breakFunction && programCounter - 5 == vm->breakFunction ) {
00567                     // this is to allow setting breakpoints here in the debugger
00568                     vm->breakCount++;
00569 //                  vm_debugLevel = 2;
00570 //                  VM_StackTrace( vm, programCounter, programStack );
00571                 }
00572                 vm->callLevel++;
00573             }
00574 #endif
00575             goto nextInstruction;
00576         case OP_LEAVE:
00577             // remove our stack frame
00578             v1 = r2;
00579 
00580             programStack += v1;
00581 
00582             // grab the saved program counter
00583             programCounter = *(int *)&image[ programStack ];
00584 #ifdef DEBUG_VM
00585             profileSymbol = VM_ValueToFunctionSymbol( vm, programCounter );
00586             if ( vm_debugLevel ) {
00587                 vm->callLevel--;
00588                 Com_Printf( "%s<--- %s\n", DEBUGSTR, VM_ValueToSymbol( vm, programCounter ) );
00589             }
00590 #endif
00591             // check for leaving the VM
00592             if ( programCounter == -1 ) {
00593                 goto done;
00594             }
00595             goto nextInstruction;
00596 
00597         /*
00598         ===================================================================
00599         BRANCHES
00600         ===================================================================
00601         */
00602 
00603         case OP_JUMP:
00604             programCounter = r0;
00605             programCounter = vm->instructionPointers[ programCounter ];
00606             opStack--;
00607             goto nextInstruction;
00608 
00609         case OP_EQ:
00610             opStack -= 2;
00611             if ( r1 == r0 ) {
00612                 programCounter = r2;    //vm->instructionPointers[r2];
00613                 goto nextInstruction;
00614             } else {
00615                 programCounter += 4;
00616                 goto nextInstruction;
00617             }
00618 
00619         case OP_NE:
00620             opStack -= 2;
00621             if ( r1 != r0 ) {
00622                 programCounter = r2;    //vm->instructionPointers[r2];
00623                 goto nextInstruction;
00624             } else {
00625                 programCounter += 4;
00626                 goto nextInstruction;
00627             }
00628 
00629         case OP_LTI:
00630             opStack -= 2;
00631             if ( r1 < r0 ) {
00632                 programCounter = r2;    //vm->instructionPointers[r2];
00633                 goto nextInstruction;
00634             } else {
00635                 programCounter += 4;
00636                 goto nextInstruction;
00637             }
00638 
00639         case OP_LEI:
00640             opStack -= 2;
00641             if ( r1 <= r0 ) {
00642                 programCounter = r2;    //vm->instructionPointers[r2];
00643                 goto nextInstruction;
00644             } else {
00645                 programCounter += 4;
00646                 goto nextInstruction;
00647             }
00648 
00649         case OP_GTI:
00650             opStack -= 2;
00651             if ( r1 > r0 ) {
00652                 programCounter = r2;    //vm->instructionPointers[r2];
00653                 goto nextInstruction;
00654             } else {
00655                 programCounter += 4;
00656                 goto nextInstruction;
00657             }
00658 
00659         case OP_GEI:
00660             opStack -= 2;
00661             if ( r1 >= r0 ) {
00662                 programCounter = r2;    //vm->instructionPointers[r2];
00663                 goto nextInstruction;
00664             } else {
00665                 programCounter += 4;
00666                 goto nextInstruction;
00667             }
00668 
00669         case OP_LTU:
00670             opStack -= 2;
00671             if ( ((unsigned)r1) < ((unsigned)r0) ) {
00672                 programCounter = r2;    //vm->instructionPointers[r2];
00673                 goto nextInstruction;
00674             } else {
00675                 programCounter += 4;
00676                 goto nextInstruction;
00677             }
00678 
00679         case OP_LEU:
00680             opStack -= 2;
00681             if ( ((unsigned)r1) <= ((unsigned)r0) ) {
00682                 programCounter = r2;    //vm->instructionPointers[r2];
00683                 goto nextInstruction;
00684             } else {
00685                 programCounter += 4;
00686                 goto nextInstruction;
00687             }
00688 
00689         case OP_GTU:
00690             opStack -= 2;
00691             if ( ((unsigned)r1) > ((unsigned)r0) ) {
00692                 programCounter = r2;    //vm->instructionPointers[r2];
00693                 goto nextInstruction;
00694             } else {
00695                 programCounter += 4;
00696                 goto nextInstruction;
00697             }
00698 
00699         case OP_GEU:
00700             opStack -= 2;
00701             if ( ((unsigned)r1) >= ((unsigned)r0) ) {
00702                 programCounter = r2;    //vm->instructionPointers[r2];
00703                 goto nextInstruction;
00704             } else {
00705                 programCounter += 4;
00706                 goto nextInstruction;
00707             }
00708 
00709         case OP_EQF:
00710             if ( ((float *)opStack)[-1] == *(float *)opStack ) {
00711                 programCounter = r2;    //vm->instructionPointers[r2];
00712                 opStack -= 2;
00713                 goto nextInstruction;
00714             } else {
00715                 programCounter += 4;
00716                 opStack -= 2;
00717                 goto nextInstruction;
00718             }
00719 
00720         case OP_NEF:
00721             if ( ((float *)opStack)[-1] != *(float *)opStack ) {
00722                 programCounter = r2;    //vm->instructionPointers[r2];
00723                 opStack -= 2;
00724                 goto nextInstruction;
00725             } else {
00726                 programCounter += 4;
00727                 opStack -= 2;
00728                 goto nextInstruction;
00729             }
00730 
00731         case OP_LTF:
00732             if ( ((float *)opStack)[-1] < *(float *)opStack ) {
00733                 programCounter = r2;    //vm->instructionPointers[r2];
00734                 opStack -= 2;
00735                 goto nextInstruction;
00736             } else {
00737                 programCounter += 4;
00738                 opStack -= 2;
00739                 goto nextInstruction;
00740             }
00741 
00742         case OP_LEF:
00743             if ( ((float *)opStack)[-1] <= *(float *)opStack ) {
00744                 programCounter = r2;    //vm->instructionPointers[r2];
00745                 opStack -= 2;
00746                 goto nextInstruction;
00747             } else {
00748                 programCounter += 4;
00749                 opStack -= 2;
00750                 goto nextInstruction;
00751             }
00752 
00753         case OP_GTF:
00754             if ( ((float *)opStack)[-1] > *(float *)opStack ) {
00755                 programCounter = r2;    //vm->instructionPointers[r2];
00756                 opStack -= 2;
00757                 goto nextInstruction;
00758             } else {
00759                 programCounter += 4;
00760                 opStack -= 2;
00761                 goto nextInstruction;
00762             }
00763 
00764         case OP_GEF:
00765             if ( ((float *)opStack)[-1] >= *(float *)opStack ) {
00766                 programCounter = r2;    //vm->instructionPointers[r2];
00767                 opStack -= 2;
00768                 goto nextInstruction;
00769             } else {
00770                 programCounter += 4;
00771                 opStack -= 2;
00772                 goto nextInstruction;
00773             }
00774 
00775 
00776         //===================================================================
00777 
00778         case OP_NEGI:
00779             *opStack = -r0;
00780             goto nextInstruction;
00781         case OP_ADD:
00782             opStack[-1] = r1 + r0;
00783             opStack--;
00784             goto nextInstruction;
00785         case OP_SUB:
00786             opStack[-1] = r1 - r0;
00787             opStack--;
00788             goto nextInstruction;
00789         case OP_DIVI:
00790             opStack[-1] = r1 / r0;
00791             opStack--;
00792             goto nextInstruction;
00793         case OP_DIVU:
00794             opStack[-1] = ((unsigned)r1) / ((unsigned)r0);
00795             opStack--;
00796             goto nextInstruction;
00797         case OP_MODI:
00798             opStack[-1] = r1 % r0;
00799             opStack--;
00800             goto nextInstruction;
00801         case OP_MODU:
00802             opStack[-1] = ((unsigned)r1) % (unsigned)r0;
00803             opStack--;
00804             goto nextInstruction;
00805         case OP_MULI:
00806             opStack[-1] = r1 * r0;
00807             opStack--;
00808             goto nextInstruction;
00809         case OP_MULU:
00810             opStack[-1] = ((unsigned)r1) * ((unsigned)r0);
00811             opStack--;
00812             goto nextInstruction;
00813 
00814         case OP_BAND:
00815             opStack[-1] = ((unsigned)r1) & ((unsigned)r0);
00816             opStack--;
00817             goto nextInstruction;
00818         case OP_BOR:
00819             opStack[-1] = ((unsigned)r1) | ((unsigned)r0);
00820             opStack--;
00821             goto nextInstruction;
00822         case OP_BXOR:
00823             opStack[-1] = ((unsigned)r1) ^ ((unsigned)r0);
00824             opStack--;
00825             goto nextInstruction;
00826         case OP_BCOM:
00827             opStack[-1] = ~ ((unsigned)r0);
00828             goto nextInstruction;
00829 
00830         case OP_LSH:
00831             opStack[-1] = r1 << r0;
00832             opStack--;
00833             goto nextInstruction;
00834         case OP_RSHI:
00835             opStack[-1] = r1 >> r0;
00836             opStack--;
00837             goto nextInstruction;
00838         case OP_RSHU:
00839             opStack[-1] = ((unsigned)r1) >> r0;
00840             opStack--;
00841             goto nextInstruction;
00842 
00843         case OP_NEGF:
00844             *(float *)opStack =  -*(float *)opStack;
00845             goto nextInstruction;
00846         case OP_ADDF:
00847             *(float *)(opStack-1) = *(float *)(opStack-1) + *(float *)opStack;
00848             opStack--;
00849             goto nextInstruction;
00850         case OP_SUBF:
00851             *(float *)(opStack-1) = *(float *)(opStack-1) - *(float *)opStack;
00852             opStack--;
00853             goto nextInstruction;
00854         case OP_DIVF:
00855             *(float *)(opStack-1) = *(float *)(opStack-1) / *(float *)opStack;
00856             opStack--;
00857             goto nextInstruction;
00858         case OP_MULF:
00859             *(float *)(opStack-1) = *(float *)(opStack-1) * *(float *)opStack;
00860             opStack--;
00861             goto nextInstruction;
00862 
00863         case OP_CVIF:
00864             *(float *)opStack =  (float)*opStack;
00865             goto nextInstruction;
00866         case OP_CVFI:
00867             *opStack = (int) *(float *)opStack;
00868             goto nextInstruction;
00869         case OP_SEX8:
00870             *opStack = (signed char)*opStack;
00871             goto nextInstruction;
00872         case OP_SEX16:
00873             *opStack = (short)*opStack;
00874             goto nextInstruction;
00875         }
00876     }
00877 
00878 done:
00879     vm->currentlyInterpreting = qfalse;
00880 
00881     if ( opStack != &stack[1] ) {
00882         Com_Error( ERR_DROP, "Interpreter error: opStack = %i", opStack - stack );
00883     }
00884 
00885     vm->programStack = stackOnEntry;
00886 
00887     // return the result
00888     return *opStack;
00889 }

Here is the call graph for this function:

void VM_Compile vm_t vm,
vmHeader_t header
 

Definition at line 437 of file vm_ppc.c.

References vm_t.

Referenced by VM_Create().

00437                                                 {
00438     int     op;
00439     int     maxLength;
00440     int     v;
00441     int     i;
00442         
00443     // set up the into-to-float variables
00444     ((int *)itofConvert)[0] = 0x43300000;
00445     ((int *)itofConvert)[1] = 0x80000000;
00446     ((int *)itofConvert)[2] = 0x43300000;
00447 
00448     // allocate a very large temp buffer, we will shrink it later
00449     maxLength = header->codeLength * 8;
00450     buf = Z_Malloc( maxLength );
00451     jused = Z_Malloc(header->instructionCount + 2);
00452     Com_Memset(jused, 0, header->instructionCount+2);
00453     
00454     // compile everything twice, so the second pass will have valid instruction
00455     // pointers for branches
00456     for ( pass = -1 ; pass < 2 ; pass++ ) {
00457 
00458     rtopped = qfalse;
00459         // translate all instructions
00460         pc = 0;
00461     
00462     pop0 = 343545;
00463     pop1 = 2443545;
00464     oc0 = -2343535;
00465     oc1 = 24353454;
00466     tvm = vm;
00467         code = (byte *)header + header->codeOffset;
00468         compiledOfs = 0;
00469 #ifndef __GNUC__
00470         // metrowerks seems to require this header in front of functions
00471         Emit4( (int)(buf+2) );
00472         Emit4( 0 );
00473 #endif
00474 
00475         for ( instruction = 0 ; instruction < header->instructionCount ; instruction++ ) {
00476             if ( compiledOfs*4 > maxLength - 16 ) {
00477                 Com_Error( ERR_DROP, "VM_Compile: maxLength exceeded" );
00478             }
00479 
00480             op = code[ pc ];
00481             if ( !pass ) {
00482                 vm->instructionPointers[ instruction ] = compiledOfs * 4;
00483             }
00484             pc++;
00485             switch ( op ) {
00486             case 0:
00487                 break;
00488             case OP_BREAK:
00489                 InstImmU( PPC_ADDI, R_TOP, 0, 0 );
00490                 InstImm( PPC_LWZ, R_TOP, R_TOP, 0 );            // *(int *)0 to crash to debugger
00491         rtopped = qfalse;
00492                 break;
00493             case OP_ENTER:
00494                 InstImm( PPC_ADDI, R_STACK, R_STACK, -Constant4() );    // sub R_STACK, R_STACK, imm
00495         rtopped = qfalse;
00496                 break;
00497             case OP_CONST:
00498                 v = Constant4();
00499         if (code[pc] == OP_LOAD4 || code[pc] == OP_LOAD2 || code[pc] == OP_LOAD1) {
00500             v &= vm->dataMask;
00501         }
00502                 if ( v < 32768 && v >= -32768 ) {
00503                     InstImmU( PPC_ADDI, R_TOP, 0, v & 0xffff );
00504                 } else {
00505                     InstImmU( PPC_ADDIS, R_TOP, 0, (v >> 16)&0xffff );
00506                     if ( v & 0xffff ) {
00507                         InstImmU( PPC_ORI, R_TOP, R_TOP, v & 0xffff );
00508                     }
00509                 }
00510         if (code[pc] == OP_LOAD4) {
00511             Inst( PPC_LWZX, R_TOP, R_TOP, R_MEMBASE );      // load from memory base
00512             pc++;
00513             instruction++;
00514         } else if (code[pc] == OP_LOAD2) {
00515             Inst( PPC_LHZX, R_TOP, R_TOP, R_MEMBASE );      // load from memory base
00516             pc++;
00517             instruction++;
00518         } else if (code[pc] == OP_LOAD1) {
00519             Inst( PPC_LBZX, R_TOP, R_TOP, R_MEMBASE );      // load from memory base
00520             pc++;
00521             instruction++;
00522         }
00523         if (code[pc] == OP_STORE4) {
00524             InstImm( PPC_LWZ, R_SECOND, R_OPSTACK, 0 ); // get value from opstack
00525             InstImm( PPC_ADDI, R_OPSTACK, R_OPSTACK, -4 );
00526             //Inst( PPC_AND, R_MEMMASK, R_SECOND, R_SECOND );   // mask it
00527             Inst( PPC_STWX, R_TOP, R_SECOND, R_MEMBASE );   // store from memory base
00528             pc++;
00529             instruction++;
00530             rtopped = qfalse;
00531             break;
00532         } else if (code[pc] == OP_STORE2) {
00533             InstImm( PPC_LWZ, R_SECOND, R_OPSTACK, 0 ); // get value from opstack
00534             InstImm( PPC_ADDI, R_OPSTACK, R_OPSTACK, -4 );
00535             //Inst( PPC_AND, R_MEMMASK, R_SECOND, R_SECOND );   // mask it
00536             Inst( PPC_STHX, R_TOP, R_SECOND, R_MEMBASE );   // store from memory base
00537             pc++;
00538             instruction++;
00539             rtopped = qfalse;
00540             break;
00541         } else if (code[pc] == OP_STORE1) {
00542             InstImm( PPC_LWZ, R_SECOND, R_OPSTACK, 0 ); // get value from opstack
00543             InstImm( PPC_ADDI, R_OPSTACK, R_OPSTACK, -4 );
00544             //Inst( PPC_AND, R_MEMMASK, R_SECOND, R_SECOND );   // mask it
00545             Inst( PPC_STBX, R_TOP, R_SECOND, R_MEMBASE );   // store from memory base
00546             pc++;
00547             instruction++;
00548             rtopped = qfalse;
00549             break;
00550         }
00551         if (code[pc] == OP_JUMP) {
00552             jused[v] = 1;
00553         }
00554         InstImm( PPC_STWU, R_TOP, R_OPSTACK, 4 );
00555         rtopped = qtrue;
00556         break;
00557             case OP_LOCAL:
00558         oc0 = oc1;
00559         oc1 = Constant4();
00560         if (code[pc] == OP_LOAD4 || code[pc] == OP_LOAD2 || code[pc] == OP_LOAD1) {
00561             oc1 &= vm->dataMask;
00562         }
00563                 InstImm( PPC_ADDI, R_TOP, R_STACK, oc1 );
00564         if (code[pc] == OP_LOAD4) {
00565             Inst( PPC_LWZX, R_TOP, R_TOP, R_MEMBASE );      // load from memory base
00566             pc++;
00567             instruction++;
00568         } else if (code[pc] == OP_LOAD2) {
00569             Inst( PPC_LHZX, R_TOP, R_TOP, R_MEMBASE );      // load from memory base
00570             pc++;
00571             instruction++;
00572         } else if (code[pc] == OP_LOAD1) {
00573             Inst( PPC_LBZX, R_TOP, R_TOP, R_MEMBASE );      // load from memory base
00574             pc++;
00575             instruction++;
00576         }
00577         if (code[pc] == OP_STORE4) {
00578             InstImm( PPC_LWZ, R_SECOND, R_OPSTACK, 0 );     // get value from opstack
00579             InstImm( PPC_ADDI, R_OPSTACK, R_OPSTACK, -4 );
00580             //Inst( PPC_AND, R_MEMMASK, R_SECOND, R_SECOND );   // mask it
00581             Inst( PPC_STWX, R_TOP, R_SECOND, R_MEMBASE );   // store from memory base
00582             pc++;
00583             instruction++;
00584             rtopped = qfalse;
00585             break;
00586         } else if (code[pc] == OP_STORE2) {
00587             InstImm( PPC_LWZ, R_SECOND, R_OPSTACK, 0 );     // get value from opstack
00588             InstImm( PPC_ADDI, R_OPSTACK, R_OPSTACK, -4 );
00589             //Inst( PPC_AND, R_MEMMASK, R_SECOND, R_SECOND );   // mask it
00590             Inst( PPC_STHX, R_TOP, R_SECOND, R_MEMBASE );   // store from memory base
00591             pc++;
00592             instruction++;
00593             rtopped = qfalse;
00594             break;
00595         } else if (code[pc] == OP_STORE1) {
00596             InstImm( PPC_LWZ, R_SECOND, R_OPSTACK, 0 );     // get value from opstack
00597             InstImm( PPC_ADDI, R_OPSTACK, R_OPSTACK, -4 );
00598             //Inst( PPC_AND, R_MEMMASK, R_SECOND, R_SECOND );   // mask it
00599             Inst( PPC_STBX, R_TOP, R_SECOND, R_MEMBASE );   // store from memory base
00600             pc++;
00601             instruction++;
00602             rtopped = qfalse;
00603             break;
00604         }
00605                 InstImm( PPC_STWU, R_TOP, R_OPSTACK, 4 );
00606         rtopped = qtrue;
00607                 break;
00608             case OP_ARG:
00609                 ltop();                         // get value from opstack
00610                 InstImm( PPC_ADDI, R_OPSTACK, R_OPSTACK, -4 );
00611                 InstImm( PPC_ADDI, R_EA, R_STACK, Constant1() );    // location to put it
00612                 Inst( PPC_STWX, R_TOP, R_EA, R_MEMBASE );
00613         rtopped = qfalse;
00614                 break;
00615             case OP_CALL:
00616                 Inst( PPC_MFSPR, R_SECOND, 8, 0 );          // move from link register
00617                 InstImm( PPC_STWU, R_SECOND, R_REAL_STACK, -16 );   // save off the old return address
00618 
00619                 Inst( PPC_MTSPR, R_ASMCALL, 9, 0 );         // move to count register
00620                 Inst( PPC_BCCTR | 1, 20, 0, 0 );            // jump and link to the count register
00621 
00622                 InstImm( PPC_LWZ, R_SECOND, R_REAL_STACK, 0 );      // fetch the old return address
00623                 InstImm( PPC_ADDI, R_REAL_STACK, R_REAL_STACK, 16 );
00624                 Inst( PPC_MTSPR, R_SECOND, 8, 0 );          // move to link register
00625         rtopped = qfalse;
00626                 break;
00627             case OP_PUSH:
00628                 InstImm( PPC_ADDI, R_OPSTACK, R_OPSTACK, 4 );
00629         rtopped = qfalse;
00630                 break;
00631             case OP_POP:
00632                 InstImm( PPC_ADDI, R_OPSTACK, R_OPSTACK, -4 );
00633         rtopped = qfalse;
00634                 break;
00635             case OP_LEAVE:
00636                 InstImm( PPC_ADDI, R_STACK, R_STACK, Constant4() ); // add R_STACK, R_STACK, imm
00637                 Inst( PPC_BCLR, 20, 0, 0 );                         // branch unconditionally to link register
00638         rtopped = qfalse;
00639                 break;
00640             case OP_LOAD4:
00641                 ltop();                         // get value from opstack
00642         //Inst( PPC_AND, R_MEMMASK, R_TOP, R_TOP );     // mask it
00643                 Inst( PPC_LWZX, R_TOP, R_TOP, R_MEMBASE );      // load from memory base
00644                 InstImm( PPC_STW, R_TOP, R_OPSTACK, 0 );
00645         rtopped = qtrue;
00646                 break;
00647             case OP_LOAD2:
00648                 ltop();                         // get value from opstack
00649         //Inst( PPC_AND, R_MEMMASK, R_TOP, R_TOP );     // mask it
00650                 Inst( PPC_LHZX, R_TOP, R_TOP, R_MEMBASE );      // load from memory base
00651                 InstImm( PPC_STW, R_TOP, R_OPSTACK, 0 );
00652         rtopped = qtrue;
00653                 break;
00654             case OP_LOAD1:
00655                 ltop();                         // get value from opstack
00656         //Inst( PPC_AND, R_MEMMASK, R_TOP, R_TOP );     // mask it
00657                 Inst( PPC_LBZX, R_TOP, R_TOP, R_MEMBASE );      // load from memory base
00658                 InstImm( PPC_STW, R_TOP, R_OPSTACK, 0 );
00659         rtopped = qtrue;
00660                 break;
00661             case OP_STORE4:
00662                 ltopandsecond();                    // get value from opstack
00663         //Inst( PPC_AND, R_MEMMASK, R_SECOND, R_SECOND );       // mask it
00664                 Inst( PPC_STWX, R_TOP, R_SECOND, R_MEMBASE );       // store from memory base
00665         rtopped = qfalse;
00666                 break;
00667             case OP_STORE2:
00668                 ltopandsecond();                    // get value from opstack
00669         //Inst( PPC_AND, R_MEMMASK, R_SECOND, R_SECOND );       // mask it
00670                 Inst( PPC_STHX, R_TOP, R_SECOND, R_MEMBASE );       // store from memory base
00671         rtopped = qfalse;
00672                 break;
00673             case OP_STORE1:
00674                 ltopandsecond();                    // get value from opstack
00675         //Inst( PPC_AND, R_MEMMASK, R_SECOND, R_SECOND );       // mask it
00676                 Inst( PPC_STBX, R_TOP, R_SECOND, R_MEMBASE );       // store from memory base
00677         rtopped = qfalse;
00678                 break;
00679 
00680             case OP_EQ:
00681                 ltopandsecond();                    // get value from opstack
00682                 Inst( PPC_CMP, 0, R_SECOND, R_TOP );
00683                 i = Constant4();
00684                 jused[i] = 1;
00685                 InstImm( PPC_BC, 4, 2, 8 );
00686                 if ( pass==1 ) {
00687                     v = vm->instructionPointers[ i ] - (int)&buf[compiledOfs];                    
00688                 } else {
00689                     v = 0;             
00690                 }
00691                 Emit4(PPC_B | (v&0x3ffffff) );
00692                 rtopped = qfalse;
00693                 break;
00694             case OP_NE:
00695                 ltopandsecond();                    // get value from opstack
00696                 Inst( PPC_CMP, 0, R_SECOND, R_TOP );
00697                 i = Constant4();
00698                 jused[i] = 1;
00699                 InstImm( PPC_BC, 12, 2, 8 );
00700                 if ( pass==1 ) {
00701                     v = vm->instructionPointers[ i ] - (int)&buf[compiledOfs];                    
00702                 } else {
00703                     v = 0;
00704                 }
00705                 Emit4(PPC_B | (unsigned int)(v&0x3ffffff) );
00706 //                InstImm( PPC_BC, 4, 2, v );
00707 
00708                 rtopped = qfalse;
00709                 break;
00710             case OP_LTI:
00711                 ltopandsecond();                    // get value from opstack
00712                 Inst( PPC_CMP, 0, R_SECOND, R_TOP );
00713                 i = Constant4();
00714                 jused[i] = 1;
00715                 InstImm( PPC_BC, 4, 0, 8 );
00716                 if ( pass==1 ) {
00717                     v = vm->instructionPointers[ i ] - (int)&buf[compiledOfs];
00718                 } else {
00719                     v = 0;
00720                 }
00721                 Emit4(PPC_B | (unsigned int)(v&0x3ffffff) );
00722 //                InstImm( PPC_BC, 12, 0, v );
00723                 rtopped = qfalse;
00724                 break;
00725             case OP_LEI:
00726                 ltopandsecond();                    // get value from opstack
00727                 Inst( PPC_CMP, 0, R_SECOND, R_TOP );
00728                 i = Constant4();
00729                 jused[i] = 1;
00730                 InstImm( PPC_BC, 12, 1, 8 );
00731                 if ( pass==1 ) {
00732                     v = vm->instructionPointers[ i ] - (int)&buf[compiledOfs];
00733                 } else {
00734                     v = 0;
00735                 }
00736                 Emit4(PPC_B | (unsigned int)(v&0x3ffffff) );
00737 //                InstImm( PPC_BC, 4, 1, v );
00738                 rtopped = qfalse;
00739                 break;
00740             case OP_GTI:
00741                 ltopandsecond();        // get value from opstack
00742                 Inst( PPC_CMP, 0, R_SECOND, R_TOP );
00743                 i = Constant4();
00744                 jused[i] = 1;
00745                 InstImm( PPC_BC, 4, 1, 8 );
00746                 if ( pass==1 ) {
00747                     v = vm->instructionPointers[ i ] - (int)&buf[compiledOfs];
00748                 } else {
00749                     v = 0;
00750                 }
00751                 Emit4(PPC_B | (unsigned int)(v&0x3ffffff) );
00752 //                InstImm( PPC_BC, 12, 1, v );
00753                 rtopped = qfalse;
00754                 break;
00755             case OP_GEI:
00756                 ltopandsecond();        // get value from opstack
00757                 Inst( PPC_CMP, 0, R_SECOND, R_TOP );
00758                 i = Constant4();
00759                 jused[i] = 1;
00760                 InstImm( PPC_BC, 12, 0, 8 );
00761                 if ( pass==1 ) {
00762                     v = vm->instructionPointers[ i ] - (int)&buf[compiledOfs];
00763                 } else {
00764                     v = 0;
00765                 }
00766                 Emit4(PPC_B | (unsigned int)(v&0x3ffffff) );
00767 //                InstImm( PPC_BC, 4, 0, v );
00768                 rtopped = qfalse;
00769                 break;
00770             case OP_LTU:
00771                 ltopandsecond();        // get value from opstack
00772                 Inst( PPC_CMPL, 0, R_SECOND, R_TOP );
00773                 i = Constant4();
00774         jused[i] = 1;
00775                 InstImm( PPC_BC, 4, 0, 8 );
00776                 if ( pass==1 ) {
00777                     v = vm->instructionPointers[ i ] - (int)&buf[compiledOfs];
00778                 } else {
00779                     v = 0;
00780                 }
00781                 Emit4(PPC_B | (unsigned int)(v&0x3ffffff) );
00782 //                InstImm( PPC_BC, 12, 0, v );
00783         rtopped = qfalse;
00784                 break;
00785             case OP_LEU:
00786                 ltopandsecond();        // get value from opstack
00787                 Inst( PPC_CMPL, 0, R_SECOND, R_TOP );
00788                 i = Constant4();
00789         jused[i] = 1;
00790                 InstImm( PPC_BC, 12, 1, 8 );
00791                 if ( pass==1 ) {
00792                     v = vm->instructionPointers[ i ] - (int)&buf[compiledOfs];
00793                 } else {
00794                     v = 0;
00795                 }
00796                 Emit4(PPC_B | (unsigned int)(v&0x3ffffff) );
00797 //                InstImm( PPC_BC, 4, 1, v );
00798         rtopped = qfalse;
00799                 break;
00800             case OP_GTU:
00801                 ltopandsecond();        // get value from opstack
00802                 Inst( PPC_CMPL, 0, R_SECOND, R_TOP );
00803                 i = Constant4();
00804         jused[i] = 1;
00805                 InstImm( PPC_BC, 4, 1, 8 );
00806                 if ( pass==1 ) {
00807                     v = vm->instructionPointers[ i ] - (int)&buf[compiledOfs];
00808                 } else {
00809                     v = 0;
00810                 }
00811                 Emit4(PPC_B | (unsigned int)(v&0x3ffffff) );
00812 //                InstImm( PPC_BC, 12, 1, v );
00813         rtopped = qfalse;
00814                 break;
00815             case OP_GEU:
00816                 ltopandsecond();        // get value from opstack
00817                 Inst( PPC_CMPL, 0, R_SECOND, R_TOP );
00818                 i = Constant4();
00819         jused[i] = 1;
00820                 InstImm( PPC_BC, 12, 0, 8 );
00821                 if ( pass==1 ) {
00822                     v = vm->instructionPointers[ i ] - (int)&buf[compiledOfs];
00823                 } else {
00824                     v = 0;
00825                 }
00826                 Emit4(PPC_B | (unsigned int)(v&0x3ffffff) );
00827 //                InstImm( PPC_BC, 4, 0, v );
00828         rtopped = qfalse;
00829                 break;
00830                 
00831             case OP_EQF:
00832                 fltopandsecond();       // get value from opstack
00833                 Inst( PPC_FCMPU, 0, R_TOP, R_SECOND );
00834                 i = Constant4();
00835         jused[i] = 1;
00836                 InstImm( PPC_BC, 4, 2, 8 );
00837                 if ( pass==1 ) {
00838                     v = vm->instructionPointers[ i ] - (int)&buf[compiledOfs];
00839                 } else {
00840                     v = 0;
00841                 }
00842                 Emit4(PPC_B | (unsigned int)(v&0x3ffffff) );
00843 //                InstImm( PPC_BC, 12, 2, v );
00844         rtopped = qfalse;
00845                 break;          
00846             case OP_NEF:
00847                 fltopandsecond();       // get value from opstack
00848                 Inst( PPC_FCMPU, 0, R_TOP, R_SECOND );
00849                 i = Constant4();
00850         jused[i] = 1;
00851                 InstImm( PPC_BC, 12, 2, 8 );
00852                 if ( pass==1 ) {
00853                     v = vm->instructionPointers[ i ] - (int)&buf[compiledOfs];
00854                 } else {
00855                     v = 0;
00856                 }
00857                 Emit4(PPC_B | (unsigned int)(v&0x3ffffff) );
00858 //                InstImm( PPC_BC, 4, 2, v );
00859         rtopped = qfalse;
00860                 break;          
00861             case OP_LTF:
00862                 fltopandsecond();       // get value from opstack
00863                 Inst( PPC_FCMPU, 0, R_SECOND, R_TOP );
00864                 i = Constant4();
00865         jused[i] = 1;
00866                 InstImm( PPC_BC, 4, 0, 8 );
00867                 if ( pass==1 ) {
00868                     v = vm->instructionPointers[ i ] - (int)&buf[compiledOfs];
00869                 } else {
00870                     v = 0;
00871                 }
00872                 Emit4(PPC_B | (unsigned int)(v&0x3ffffff) );
00873 //                InstImm( PPC_BC, 12, 0, v );
00874         rtopped = qfalse;
00875                 break;          
00876             case OP_LEF:
00877                 fltopandsecond();       // get value from opstack
00878                 Inst( PPC_FCMPU, 0, R_SECOND, R_TOP );
00879                 i = Constant4();
00880         jused[i] = 1;
00881                 InstImm( PPC_BC, 12, 1, 8 );
00882                 if ( pass==1 ) {
00883                     v = vm->instructionPointers[ i ] - (int)&buf[compiledOfs];
00884                 } else {
00885                     v = 0;
00886                 }
00887                 Emit4(PPC_B | (unsigned int)(v&0x3ffffff) );
00888 //                InstImm( PPC_BC, 4, 1, v );
00889         rtopped = qfalse;
00890                 break;          
00891             case OP_GTF:
00892                 fltopandsecond();       // get value from opstack
00893                 Inst( PPC_FCMPU, 0, R_SECOND, R_TOP );
00894                 i = Constant4();
00895         jused[i] = 1;
00896                 InstImm( PPC_BC, 4, 1, 8 );
00897                 if ( pass==1 ) {
00898                     v = vm->instructionPointers[ i ] - (int)&buf[compiledOfs];
00899                 } else {
00900                     v = 0;
00901                 }
00902                 Emit4(PPC_B | (unsigned int)(v&0x3ffffff) );
00903 //                InstImm( PPC_BC, 12, 1, v );
00904         rtopped = qfalse;
00905                 break;          
00906             case OP_GEF:
00907                 fltopandsecond();       // get value from opstack
00908                 <