]> git.xonotic.org Git - xonotic/darkplaces.git/commitdiff
prvm: Implement integer and pointer opcodes
authorcloudwalk <cloudwalk@d7cf8633-e32d-0410-b094-e92efae38249>
Thu, 9 Jul 2020 16:58:43 +0000 (16:58 +0000)
committercloudwalk <cloudwalk@d7cf8633-e32d-0410-b094-e92efae38249>
Thu, 9 Jul 2020 16:58:43 +0000 (16:58 +0000)
NOTE: At the time of this commit, gmqcc does not generate these opcodes.
Only fteqcc does. These may be unstable or incomplete. Do not use in
production yet.

git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@12794 d7cf8633-e32d-0410-b094-e92efae38249

pr_comp.h
prvm_execprogram.h

index d1643b628e15be619dc3b02115222b0e4c2852ce..19b8f15a8c50f2758ddc86c7240a6ce993e84065 100644 (file)
--- a/pr_comp.h
+++ b/pr_comp.h
@@ -118,7 +118,89 @@ typedef enum opcode_e
        OP_OR,
 
        OP_BITAND,
-       OP_BITOR
+       OP_BITOR,
+
+       OP_STORE_I = 113,
+
+       OP_ADD_I = 116,
+       OP_ADD_FI,
+       OP_ADD_IF,
+
+       OP_SUB_I,
+       OP_SUB_FI,
+       OP_SUB_IF,
+       OP_CONV_IF,
+       OP_CONV_FI,
+
+       OP_LOAD_I = 126,
+       OP_STOREP_I,
+
+       OP_BITAND_I = 130,
+       OP_BITOR_I,
+
+       OP_MUL_I,
+       OP_DIV_I,
+       OP_EQ_I,
+       OP_NE_I,
+
+       OP_NOT_I = 138,
+
+       OP_DIV_VF,
+       
+       OP_STORE_P = 152,
+
+       OP_LE_I = 161,
+       OP_GE_I,
+       OP_LT_I,
+       OP_GT_I,
+       
+       OP_LE_IF,
+       OP_GE_IF,
+       OP_LT_IF,
+       OP_GT_IF,
+
+       OP_LE_FI,
+       OP_GE_FI,
+       OP_LT_FI,
+       OP_GT_FI,
+
+       OP_EQ_IF,
+       OP_EQ_FI,
+
+       OP_MUL_IF = 179,
+       OP_MUL_FI,
+       OP_MUL_VI,
+       OP_DIV_IF = 183,
+       OP_DIV_FI,
+       OP_BITAND_IF,
+       OP_BITOR_IF,
+       OP_BITAND_FI,
+       OP_BITOR_FI,
+       OP_AND_I,
+       OP_OR_I,
+       OP_AND_IF,
+       OP_OR_IF,
+       OP_AND_FI,
+       OP_OR_FI,
+       OP_NE_IF,
+       OP_NE_FI,
+
+       OP_GSTOREP_I,
+       OP_GSTOREP_F,
+       OP_GSTOREP_ENT,
+       OP_GSTOREP_FLD,
+       OP_GSTOREP_S,
+       OP_GSTOREP_FNC,         
+       OP_GSTOREP_V,
+       OP_GADDRESS,
+       OP_GLOAD_I,
+       OP_GLOAD_F,
+       OP_GLOAD_FLD,
+       OP_GLOAD_ENT,
+       OP_GLOAD_S,
+       OP_GLOAD_FNC,
+       OP_BOUNDCHECK,
+       OP_GLOAD_V = 216
 }
 opcode_t;
 
index 60a112c1c2dcb02d55644d8931cf8dae35375558..3982737ed33c0e52cfc470901a6cbc7ed342556c 100644 (file)
@@ -1,4 +1,5 @@
 extern cvar_t prvm_garbagecollection_enable;
+int i;
 // NEED to reset startst after calling this! startst may or may not be clobbered!
 #define ADVANCE_PROFILE_BEFORE_JUMP() \
        prog->xfunction->profile += (st - startst); \
@@ -111,7 +112,183 @@ extern cvar_t prvm_garbagecollection_enable;
        &&handle_OP_OR,
 
        &&handle_OP_BITAND,
-       &&handle_OP_BITOR
+       &&handle_OP_BITOR,
+
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+
+       &&handle_OP_STORE_I,
+
+       NULL,
+       NULL,
+
+       &&handle_OP_ADD_I,
+       &&handle_OP_ADD_FI,
+       &&handle_OP_ADD_IF,
+
+       &&handle_OP_SUB_I,
+       &&handle_OP_SUB_FI,
+       &&handle_OP_SUB_IF,
+       &&handle_OP_CONV_IF,
+       &&handle_OP_CONV_FI,
+
+       NULL,
+       NULL,
+
+       &&handle_OP_LOAD_I,
+       &&handle_OP_STOREP_I,
+
+       NULL,
+       NULL,
+
+       &&handle_OP_BITAND_I,
+       &&handle_OP_BITOR_I,
+
+       &&handle_OP_MUL_I,
+       &&handle_OP_DIV_I,
+       &&handle_OP_EQ_I,
+       &&handle_OP_NE_I,
+
+       NULL,
+       NULL,
+
+       &&handle_OP_NOT_I,
+
+       &&handle_OP_DIV_VF,
+
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+
+       &&handle_OP_STORE_P,
+
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+
+       &&handle_OP_LE_I,
+       &&handle_OP_GE_I,
+       &&handle_OP_LT_I,
+       &&handle_OP_GT_I,
+       
+       &&handle_OP_LE_IF,
+       &&handle_OP_GE_IF,
+       &&handle_OP_LT_IF,
+       &&handle_OP_GT_IF,
+
+       &&handle_OP_LE_FI,
+       &&handle_OP_GE_FI,
+       &&handle_OP_LT_FI,
+       &&handle_OP_GT_FI,
+
+       &&handle_OP_EQ_IF,
+       &&handle_OP_EQ_FI,
+
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+
+       &&handle_OP_MUL_IF,
+       &&handle_OP_MUL_FI,
+       &&handle_OP_MUL_VI,
+
+       NULL,
+
+       &&handle_OP_DIV_IF,
+       &&handle_OP_DIV_FI,
+       &&handle_OP_BITAND_IF,
+       &&handle_OP_BITOR_IF,
+       &&handle_OP_BITAND_FI,
+       &&handle_OP_BITOR_FI,
+       &&handle_OP_AND_I,
+       &&handle_OP_OR_I,
+       &&handle_OP_AND_IF,
+       &&handle_OP_OR_IF,
+       &&handle_OP_AND_FI,
+       &&handle_OP_OR_FI,
+       &&handle_OP_NE_IF,
+       &&handle_OP_NE_FI,
+
+       &&handle_OP_GSTOREP_I,
+       &&handle_OP_GSTOREP_F,
+       &&handle_OP_GSTOREP_ENT,
+       &&handle_OP_GSTOREP_FLD,
+       &&handle_OP_GSTOREP_S,
+       &&handle_OP_GSTOREP_FNC,                
+       &&handle_OP_GSTOREP_V,
+       &&handle_OP_GADDRESS,
+       &&handle_OP_GLOAD_I,
+       &&handle_OP_GLOAD_F,
+       &&handle_OP_GLOAD_FLD,
+       &&handle_OP_GLOAD_ENT,
+       &&handle_OP_GLOAD_S,
+       &&handle_OP_GLOAD_FNC,
+       &&handle_OP_BOUNDCHECK,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       &&handle_OP_GLOAD_V
            };
 #define DISPATCH_OPCODE() \
     goto *dispatchtable[(++st)->op]
@@ -614,8 +791,6 @@ extern cvar_t prvm_garbagecollection_enable;
                                }
                                DISPATCH_OPCODE();
 
-// LadyHavoc: to be enabled when Progs version 7 (or whatever it will be numbered) is finalized
-/*
                        HANDLE_OPCODE(OP_ADD_I):
                                OPC->_int = OPA->_int + OPB->_int;
                                DISPATCH_OPCODE();
@@ -765,6 +940,7 @@ extern cvar_t prvm_garbagecollection_enable;
                                OPC->_float = OPA->_float != (prvm_vec_t)OPB->_int;
                                DISPATCH_OPCODE();
                        HANDLE_OPCODE(OP_STORE_I):
+                       HANDLE_OPCODE(OP_STORE_P):
                                OPB->_int = OPA->_int;
                                DISPATCH_OPCODE();
                        HANDLE_OPCODE(OP_STOREP_I):
@@ -776,7 +952,7 @@ extern cvar_t prvm_garbagecollection_enable;
                                        goto cleanup;
                                }
 #endif
-                               ptr = (prvm_eval_t *)(prog->edictsfields + OPB->_int);
+                               ptr = (prvm_eval_t *)(prog->edictsfields.ip + OPB->_int);
                                ptr->_int = OPA->_int;
                                DISPATCH_OPCODE();
                        HANDLE_OPCODE(OP_LOAD_I):
@@ -787,7 +963,7 @@ extern cvar_t prvm_garbagecollection_enable;
                                        prog->error_cmd("%s Progs attempted to read an out of bounds edict number", prog->name);
                                        goto cleanup;
                                }
-                               if (OPB->_int < 0 || OPB->_int >= progs->entityfields)
+                               if (OPB->_int < 0 || OPB->_int >= progs->entityfields.ip)
                                {
                                        PRE_ERROR();
                                        prog->error_cmd("%s Progs attempted to read an invalid field in an edict", prog->name);
@@ -795,7 +971,7 @@ extern cvar_t prvm_garbagecollection_enable;
                                }
 #endif
                                ed = PRVM_PROG_TO_EDICT(OPA->edict);
-                               OPC->_int = ((prvm_eval_t *)((int *)ed->v + OPB->_int))->_int;
+                               OPC->_int = ((prvm_eval_t *)((int *)ed->fields.ip + OPB->_int))->_int;
                                DISPATCH_OPCODE();
 
                        HANDLE_OPCODE(OP_GSTOREP_I):
@@ -804,41 +980,35 @@ extern cvar_t prvm_garbagecollection_enable;
                        HANDLE_OPCODE(OP_GSTOREP_FLD):          // integers
                        HANDLE_OPCODE(OP_GSTOREP_S):
                        HANDLE_OPCODE(OP_GSTOREP_FNC):          // pointers
-#if PRBOUNDSCHECK
-                               if (OPB->_int < 0 || OPB->_int >= pr_globaldefs)
+                               if (OPB->_int < 0 || OPB->_int >= prog->numglobaldefs)
                                {
                                        PRE_ERROR();
                                        prog->error_cmd("%s Progs attempted to write to an invalid indexed global", prog->name);
                                        goto cleanup;
                                }
-#endif
-                               pr_iglobals[OPB->_int] = OPA->_int;
+                               prog->globals.ip[OPB->_int] = OPA->_int;
                                DISPATCH_OPCODE();
                        HANDLE_OPCODE(OP_GSTOREP_V):
-#if PRBOUNDSCHECK
-                               if (OPB->_int < 0 || OPB->_int + 2 >= pr_globaldefs)
+                               if (OPB->_int < 0 || OPB->_int + 2 >= prog->numglobaldefs)
                                {
                                        PRE_ERROR();
                                        prog->error_cmd("%s Progs attempted to write to an invalid indexed global", prog->name);
                                        goto cleanup;
                                }
-#endif
-                               pr_iglobals[OPB->_int  ] = OPA->ivector[0];
-                               pr_iglobals[OPB->_int+1] = OPA->ivector[1];
-                               pr_iglobals[OPB->_int+2] = OPA->ivector[2];
+                               prog->globals.ip[OPB->_int  ] = OPA->ivector[0];
+                               prog->globals.ip[OPB->_int+1] = OPA->ivector[1];
+                               prog->globals.ip[OPB->_int+2] = OPA->ivector[2];
                                DISPATCH_OPCODE();
 
                        HANDLE_OPCODE(OP_GADDRESS):
                                i = OPA->_int + (prvm_int_t) OPB->_float;
-#if PRBOUNDSCHECK
-                               if (i < 0 || i >= pr_globaldefs)
+                               if (i < 0 || i >= prog->numglobaldefs)
                                {
                                        PRE_ERROR();
                                        prog->error_cmd("%s Progs attempted to address an out of bounds global", prog->name);
                                        goto cleanup;
                                }
-#endif
-                               OPC->_int = pr_iglobals[i];
+                               OPC->_int = prog->globals.ip[i];
                                DISPATCH_OPCODE();
 
                        HANDLE_OPCODE(OP_GLOAD_I):
@@ -847,42 +1017,38 @@ extern cvar_t prvm_garbagecollection_enable;
                        HANDLE_OPCODE(OP_GLOAD_ENT):
                        HANDLE_OPCODE(OP_GLOAD_S):
                        HANDLE_OPCODE(OP_GLOAD_FNC):
-#if PRBOUNDSCHECK
-                               if (OPA->_int < 0 || OPA->_int >= pr_globaldefs)
+                               // FIXME?: Is this correct?             vvvvvvvvvvvvv
+                               if (OPA->_int < 0 || OPA->_int >= prog->numglobaldefs)
                                {
                                        PRE_ERROR();
                                        prog->error_cmd("%s Progs attempted to read an invalid indexed global", prog->name);
                                        goto cleanup;
                                }
-#endif
-                               OPC->_int = pr_iglobals[OPA->_int];
+                               OPC->_int = prog->globals.ip[OPA->_int];
                                DISPATCH_OPCODE();
 
                        HANDLE_OPCODE(OP_GLOAD_V):
-#if PRBOUNDSCHECK
-                               if (OPA->_int < 0 || OPA->_int + 2 >= pr_globaldefs)
+                               // FIXME?: Is this correct?                 vvvvvvvvvvvvv
+                               if (OPA->_int < 0 || OPA->_int + 2 >= prog->numglobaldefs)
                                {
                                        PRE_ERROR();
                                        prog->error_cmd("%s Progs attempted to read an invalid indexed global", prog->name);
                                        goto cleanup;
                                }
-#endif
-                               OPC->ivector[0] = pr_iglobals[OPA->_int  ];
-                               OPC->ivector[1] = pr_iglobals[OPA->_int+1];
-                               OPC->ivector[2] = pr_iglobals[OPA->_int+2];
+                               OPC->ivector[0] = prog->globals.ip[OPA->_int  ];
+                               OPC->ivector[1] = prog->globals.ip[OPA->_int+1];
+                               OPC->ivector[2] = prog->globals.ip[OPA->_int+2];
                                DISPATCH_OPCODE();
 
                        HANDLE_OPCODE(OP_BOUNDCHECK):
-                               if (OPA->_int < 0 || OPA->_int >= st->b)
+                               if (OPA->_int < 0 || OPA->_int >= OPB->_int)
                                {
                                        PRE_ERROR();
-                                       prog->error_cmd("%s Progs boundcheck failed at line number %d, value is < 0 or >= %d", prog->name, st->b, st->c);
+                                       prog->error_cmd("%s Progs boundcheck failed at line number %d, value is < 0 or >= %d", prog->name, OPB->_int, OPC->_int);
                                        goto cleanup;
                                }
                                DISPATCH_OPCODE();
 
-*/
-
 #if !USE_COMPUTED_GOTOS
                        default:
                                PRE_ERROR();