emuloop.c

00001 /* File:      emuloop.c
00002 ** Author(s): Warren, Swift, Xu, Sagonas, Johnson
00003 ** Contact:   xsb-contact@cs.sunysb.edu
00004 ** 
00005 ** Copyright (C) The Research Foundation of SUNY, 1986, 1993-1998
00006 ** Copyright (C) ECRC, Germany, 1990
00007 ** 
00008 ** XSB is free software; you can redistribute it and/or modify it under the
00009 ** terms of the GNU Library General Public License as published by the Free
00010 ** Software Foundation; either version 2 of the License, or (at your option)
00011 ** any later version.
00012 ** 
00013 ** XSB is distributed in the hope that it will be useful, but WITHOUT ANY
00014 ** WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00015 ** FOR A PARTICULAR PURPOSE.  See the GNU Library General Public License for
00016 ** more details.
00017 ** 
00018 ** You should have received a copy of the GNU Library General Public License
00019 ** along with XSB; if not, write to the Free Software Foundation,
00020 ** Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00021 **
00022 ** $Id: emuloop.c,v 1.141 2006/07/21 20:20:46 crued Exp $
00023 ** 
00024 */
00025 
00026 #include "xsb_config.h"
00027 #include "xsb_debug.h"
00028 
00029 #include <stdio.h>
00030 #include <stdlib.h>
00031 #include <signal.h>
00032 #include <string.h>
00033 
00034 #ifdef FOREIGN
00035 #ifndef SOLARIS
00036 #ifndef FOREIGN_WIN32
00037 #include <sys/un.h>
00038 #endif
00039 #endif
00040 #endif
00041 
00042 #include "auxlry.h"
00043 #include "cell_xsb.h"
00044 #include "register.h"
00045 #include "error_xsb.h"
00046 #include "inst_xsb.h"
00047 #include "psc_xsb.h"
00048 #include "deref.h"
00049 #include "memory_xsb.h"
00050 #include "heap_xsb.h"
00051 #include "sig_xsb.h"
00052 #include "context.h"
00053 #include "varstring_xsb.h"
00054 #include "emudef.h"
00055 #include "loader_xsb.h"
00056 #include "binding.h"
00057 #include "flags_xsb.h"
00058 #include "trie_internals.h"
00059 #include "choice.h"
00060 #include "sw_envs.h"
00061 #include "macro_xsb.h"
00062 #include "tables.h"
00063 #include "subinst.h"
00064 #include "scc_xsb.h"
00065 #include "subp.h"
00066 #include "tr_utils.h"
00067 #include "cut_xsb.h"
00068 #include "export.h"
00069 #include "orient_xsb.h"
00070 #include "io_builtins_xsb.h"
00071 #include "unify_xsb.h"
00072 #include "emuloop_aux.h"
00073 #include "remove_unf.h"
00074 #include "thread_xsb.h"
00075 #include "deadlock.h"
00076 #include "rw_lock.h"
00077 #include "debug_xsb.h"
00078 #include "hash_xsb.h"
00079 #include "struct_manager.h"
00080 #include "builtin.h"
00081 
00082 /*
00083  * Variable ans_var_pos_reg is a pointer to substitution factor of an
00084  * answer in the heap.  It is used and set in function
00085  * variant_answer_search().  The name of this variable is from VarPosReg, a
00086  * variable used in variant_call_search() to save the substitution factor
00087  * of the call.
00088  */
00089 #ifndef MULTI_THREAD
00090 CPtr    ans_var_pos_reg;
00091 #endif
00092 
00093 //#define MULTI_THREAD_LOGGING
00094 #ifdef MULTI_THREAD_LOGGING
00095 /* To help debug multithreaded applications: 
00096 Creates a log-file for each thread, and
00097 Logs calls and executes to it.
00098 */
00099 FILE *th_log_file[100] = {NULL};
00100 int th_log_cnt[100] = {0};
00101 
00102 void open_th_log_file(int tid) {
00103   char fname[100];
00104   sprintf(fname,"temp_th_log_file_%d",tid);
00105   th_log_file[tid] = fopen(fname,"w");
00106   return;
00107 }
00108 
00109 void log_rec(CTXTdeclc Psc psc, char *ctype) {
00110     if (!th_log_file[th->tid]) open_th_log_file(th->tid);
00111     fprintf(th_log_file[th->tid],"inst(%d,%s,'%s',%d).\n",++th_log_cnt[th->tid],ctype,get_name(psc),get_arity(psc));
00112     return;
00113 }
00114 #endif
00115 
00116 /*----------------------------------------------------------------------*/
00117 
00118 #include "tr_delay.h"
00119 #include "tr_code_xsb_i.h"
00120 
00121 /*----------------------------------------------------------------------*/
00122 /* indirect threading-related stuff                                     */
00123 
00124 #ifdef DEBUG_VM
00125 
00126 #define XSB_Debug_Instr                                    \
00127    if (flags[PIL_TRACE]) {                                 \
00128       debug_inst(CTXTc lpcreg, ereg);                      \
00129    }                                                       \
00130    xctr++;
00131 
00132 #else
00133 
00134 #define XSB_Debug_Instr
00135 
00136 #endif
00137 
00138 #ifdef PROFILE
00139 
00140 #define XSB_Profile_Instr                                     \
00141     if (pflags[PROFFLAG]) {                                   \
00142       inst_table[(int) *(lpcreg)][sizeof(Cell)+1]             \
00143         = inst_table[(int) *(lpcreg)][sizeof(Cell)+1] + 1;    \
00144       if (pflags[PROFFLAG] > 1 && (int) *lpcreg == builtin)   \
00145         builtin_table[(int) *(lpcreg+3)][1] =                 \
00146           builtin_table[(int) *(lpcreg+3)][1] + 1;            \
00147     } 
00148 
00149 #else
00150 
00151 #define XSB_Profile_Instr
00152 
00153 #endif
00154 
00155 #define handle_xsb_profile_interrupt                            \
00156     if (asynint_val && (asynint_val & PROFINT_MARK)) {          \
00157       asynint_val &= ~PROFINT_MARK;                             \
00158       log_prog_ctr(lpcreg);                                     \
00159     }                                                           \
00160 
00161 /* lfcastro: with INSN_BLOCKS, we use a block for each WAM instruction, 
00162    and define temporary variables locally; otherwise, temp variables are 
00163    global to the emuloop function.
00164 
00165    TLS: this experiment does not seem to have worked -- no other
00166    occurrences of INSN_BLOCKS in the system.*/
00167 
00168 #ifdef INSN_BLOCKS
00169 
00170 #define Def1op          register Cell op1;
00171 #define Def1fop         register float fop2;
00172 #define Def2ops         register Cell op1, op2;
00173 #define Def2fops        register Cell op1; register float fop2;
00174 #define Def3ops         register Cell op1,op2; register CPtr op3;
00175 #define DefOps13        register Cell op1; register CPtr op3;
00176 
00177 #define DefGlobOps
00178 
00179 #else
00180 
00181 #define Def1op
00182 #define Def1fop
00183 #define Def2ops
00184 #define Def2fops
00185 #define Def3ops
00186 #define DefOps13
00187 
00188 #define DefGlobOps register Cell op1,op2; register CPtr op3; float fop2;
00189 
00190 #endif
00191 
00192 /* lfcastro: with JUMPTABLE_EMULOOP, we use GCC's first-order labels to
00193    create a jumptable for the WAM instructions of emuloop(); otherwise 
00194    a switch statement is used. */
00195 
00196 #ifdef JUMPTABLE_EMULOOP
00197 
00198 static void *instr_addr_table[256];
00199 
00200 #define XSB_End_Instr()                                      \
00201                    XSB_Debug_Instr                           \
00202                    XSB_Profile_Instr                         \
00203                    goto *instr_addr_table[(byte)*lpcreg];          \
00204                    }
00205 
00206 
00207 #define XSB_Next_Instr()                                     \
00208                    do {                                      \
00209                       XSB_Debug_Instr                        \
00210                       XSB_Profile_Instr                      \
00211                       goto *instr_addr_table[(byte)*lpcreg];       \
00212                    } while(0)
00213 
00214 
00215 #define XSB_Start_Instr_Chained(Instr,Label)                 \
00216         Label: 
00217 
00218 #define XSB_Start_Instr(Instr,Label)                         \
00219         Label: {
00220                    
00221 
00222 
00223 #else /* no threading */
00224 
00225 #define XSB_Next_Instr()              goto contcase
00226 
00227 #define XSB_End_Instr()               goto contcase; }
00228 
00229 #define XSB_Start_Instr_Chained(Instr,Label)                 \
00230         case Instr:
00231 
00232 #define XSB_Start_Instr(Instr,Label)                         \
00233         case Instr: { 
00234 
00235 #endif
00236 
00237 /*----------------------------------------------------------------------*/
00238 
00239 #define get_axx         (lpcreg[1])
00240 #define get_vxx         (ereg-(Cell)lpcreg[1])
00241 #define get_rxx         (rreg+lpcreg[1])
00242 
00243 #define get_xax         (lpcreg[2])
00244 #define get_xvx         (ereg-(Cell)lpcreg[2])
00245 #define get_xrx         (rreg+lpcreg[2])
00246 
00247 #define get_xxa         (lpcreg[3])
00248 #define get_xxv         (ereg-(Cell)lpcreg[3])
00249 #define get_xxr         (rreg+lpcreg[3])
00250 
00251 #define get_xxxl        (*(CPtr)(lpcreg+sizeof(Cell)))
00252 #define get_xxxs        (*(CPtr)(lpcreg+sizeof(Cell)))
00253 #define get_xxxc        (*(CPtr)(lpcreg+sizeof(Cell)))
00254 #define get_xxxn        (*(CPtr)(lpcreg+sizeof(Cell)))
00255 #define get_xxxg        (*(CPtr)(lpcreg+sizeof(Cell)))
00256 #define get_xxxi        (*(CPtr)(lpcreg+sizeof(Cell)))
00257 #define get_xxxf        (*(float *)(lpcreg+sizeof(Cell)))
00258 
00259 #define get_xxxxi       (*(CPtr)(lpcreg+sizeof(Cell)*2))
00260 #define get_xxxxl       (*(CPtr)(lpcreg+sizeof(Cell)*2))
00261 
00262 #define Op1(Expr)       op1 = (Cell)Expr
00263 #define Op2(Expr)       op2 = (Cell)Expr
00264 #define Op2f(Expr)      fop2 = (float)Expr
00265 #define Op3(Expr)       op3 = (CPtr)Expr
00266 
00267 #define Register(Expr)  (cell(Expr))
00268 #define Variable(Expr)  (cell(Expr))
00269 
00270 #define size_none       0
00271 #define size_xxx        1
00272 #define size_xxxX       2
00273 #define size_xxxXX      3
00274 
00275 #define ADVANCE_PC(InstrSize)  (lpcreg += InstrSize*sizeof(Cell))
00276 
00277 /* Be sure that flag only has the following two values. */
00278 
00279 #define WRITE           1
00280 #define READFLAG        0
00281 
00282 /* TLS Macro does not appear to be used */
00283 #ifdef USE_BP_LPCREG
00284 #define POST_LPCREG_DECL asm ("bp")
00285 #else
00286 #define POST_LPCREG_DECL
00287 #endif
00288 
00289 
00290 //Below is the implementation of the inline functions for creating and manipulating boxed floats,
00291 // declared in cell_xsb.h. They only exist if the FAST_FLOATS tag is undefined. Otherwise, they
00292 // are defined as Cell-based macros. See cell_xsb.h for details.
00293 #ifndef FAST_FLOATS
00294 inline void bld_boxedfloat(CTXTdeclc CPtr addr, Float value)
00295 {
00296     Float tempFloat = value;
00297     new_heap_functor(hreg,box_psc);
00298     bld_int(hreg,((ID_BOXED_FLOAT << BOX_ID_OFFSET ) | FLOAT_HIGH_16_BITS(tempFloat) ));
00299     hreg++;
00300     bld_int(hreg,FLOAT_MIDDLE_24_BITS(tempFloat)); hreg++;
00301     bld_int(hreg,FLOAT_LOW_24_BITS(tempFloat)); hreg++;
00302     cell(addr) = makecs(hreg-4);
00303 }
00304 
00305 //the below function assumes that the Float type will be exactally twice the size of the 
00306 //   UInteger type. See basictypes.h for the declaration of converter types.
00307 inline Float make_float_from_ints(UInteger high, UInteger low)
00308 {
00309   FloatToIntsConv converter;
00310   converter.int_vals.high = high;
00311   converter.int_vals.low = low;
00312   return converter.float_val;
00313 }
00314 #else
00315 inline void bld_boxedfloat(CTXTdeclc CPtr addr, Float value) {
00316   bld_float(addr,value);
00317 }
00318 #endif
00319 
00320 /*----------------------------------------------------------------------*/
00321 /* The following macros work for all CPs.  Make sure this remains       */
00322 /* the case...                                                          */
00323 /*----------------------------------------------------------------------*/
00324 
00325 #define Fail1 lpcreg = cp_pcreg(breg)
00326 
00327 #define restore_trail_condition_registers(breg) \
00328       if (*breg != (Cell) &check_complete_inst) { \
00329         ebreg = cp_ebreg(breg); \
00330         hbreg = cp_hreg(breg); \
00331       } 
00332 
00333 /*----------------------------------------------------------------------*/
00334 
00335 extern int  builtin_call(CTXTdeclc byte), unifunc_call(CTXTdeclc int, CPtr);
00336 extern Cell builtin_table[BUILTIN_TBL_SZ][2];
00337 extern Pair build_call(CTXTdeclc Psc);
00338 
00339 extern int is_proper_list(Cell term);
00340 extern int is_most_general_term(Cell term);
00341 
00342 extern void log_prog_ctr(byte *);
00343 extern long prof_flag;
00344 
00345 #ifdef DEBUG_VM
00346 extern void debug_inst(CTXTdeclc byte *, CPtr);
00347 #endif
00348 
00349 /* TLS: took out unused global.
00350  * int debug_assert = 0;
00351  */ 
00352 
00353 #ifndef MULTI_THREAD
00354 xsbBool neg_delay;
00355 int  xwammode, level_num;
00356 #endif
00357 
00358 #ifdef DEBUG_VM
00359 int  xctr;
00360 #endif
00361 
00362 /*----------------------------------------------------------------------*/
00363 
00364 #include "schedrev_xsb_i.h"
00365 
00366 #ifndef LOCAL_EVAL 
00367 #include "wfs_xsb_i.h" 
00368 #endif 
00369 #include "complete_local.h"
00370 
00371 /*----------------------------------------------------------------------*/
00372 
00373 /* place for a meaningful message when segfault is detected */
00374 char *xsb_default_segfault_msg =
00375      "\n++Memory violation occurred during evaluation.\n++Please report this problem using the XSB bug tracking system accessible from\n++\t http://sourceforge.net/projects/xsb\n++Please supply the steps necessary to reproduce the bug.\n";
00376 
00377 
00378 #ifndef MULTI_THREAD
00379 jmp_buf xsb_abort_fallback_environment;
00380 #endif
00381 
00382 char *xsb_segfault_message;
00383 
00384 /*======================================================================*/
00385 /* the main emulator loop.                                              */
00386 /*======================================================================*/
00387 
00388 /*
00389  * The WAM instructions are aligned with word (4 bytes on 32-bit machines,
00390  * or 8-byte on 64-bit machines), the shortest instructions (like fail)
00391  * take one word, and the longest ones take three words (like
00392  * switchon3bound).  If an instruction takes more than one word, then the
00393  * 2nd (or 3rd) word always contains an operand that takes one word.  The
00394  * one-word operands can be (see file emu/inst_xsb.h):
00395  *
00396  *      L - label
00397  *      S - structure symbol
00398  *      C - constant symbol
00399  *      N - number
00400  *      G - string
00401  *      I - 2nd & 3rd arguments of switchonbound
00402  *      F - floating point number
00403  *
00404  * The opcode of all instructions takes the first byte in the first word.
00405  * The rest 3 bytes contain operands that needs only one byte.  These
00406  * one-byte operands can be:
00407  *
00408  *      P - pad, not used
00409  *      A - one byte number
00410  *      V - variable offset
00411  *      R - register number
00412  *
00413  * (In 64-bit machines there are 4 bytes of extra padding space for each 
00414  *  instruction)
00415  */
00416 
00417 int emuloop(CTXTdeclc byte *startaddr)
00418 {
00419   register CPtr rreg;
00420   register byte *lpcreg POST_LPCREG_DECL;
00421   DefGlobOps
00422   byte flag = READFLAG;         /* read/write mode flag */
00423   int  restore_type;    /* 0 for retry restore; 1 for trust restore */ 
00424 #ifdef MULTI_THREAD
00425     int (*fp)();
00426 #endif
00427 #if (defined(GC) && defined(GC_TEST))
00428 /* Used only in the garbage collection test; does not affect emulator o/w */
00429 #define GC_INFERENCES 66 /* make sure the garbage collection test is hard */
00430   static int infcounter = 0;
00431 #endif
00432 
00433   xsb_segfault_message = xsb_default_segfault_msg;
00434   rreg = reg; /* for SUN (TLS ???) */
00435 
00436 #ifdef JUMPTABLE_EMULOOP
00437 
00438 #define XSB_INST(INum,Instr,Label,d1,d2,d3,d4) \
00439         instr_addr_table[INum] = && Label
00440 #include "xsb_inst_list.h"
00441 
00442 #endif
00443 
00444   if ((lpcreg = (byte *) setjmp(xsb_abort_fallback_environment))) {
00445     /*
00446     * Short circuit untrailing to avoid possible seg faults in
00447     * switch_envs.
00448     */
00449     trreg = cp_trreg(breg);
00450     /* Restore the default signal handling */
00451     signal(SIGSEGV, xsb_default_segfault_handler);
00452    } else 
00453     lpcreg = startaddr;  /* first instruction of entire engine */
00454 #ifdef JUMPTABLE_EMULOOP
00455   XSB_Next_Instr();
00456 #else
00457 contcase:     /* the main loop */
00458 #ifdef DEBUG_VM
00459   if (flags[PIL_TRACE]) debug_inst(CTXTc lpcreg, ereg);
00460   xctr++;
00461 #endif
00462 #ifdef PROFILE
00463   if (pflags[PROFFLAG]) {
00464     inst_table[(int) *(lpcreg)][sizeof(Cell)+1]
00465       = inst_table[(int) *(lpcreg)][sizeof(Cell)+1] + 1;
00466     if (pflags[PROFFLAG] > 1 && (int) *lpcreg == builtin) 
00467       builtin_table[(int) *(lpcreg+3)][1] = 
00468         builtin_table[(int) *(lpcreg+3)][1] + 1;
00469   }
00470 #endif
00471   switch (*lpcreg) {
00472 #endif
00473     
00474   XSB_Start_Instr(getpvar,_getpvar)  /* PVR */
00475     Def2ops
00476     Op1(Variable(get_xvx));
00477     Op2(Register(get_xxr));
00478     ADVANCE_PC(size_xxx);
00479    /* trailing is needed here because this instruction can also be
00480        generated *after* the occurrence of the first call - kostis */
00481     bind_copy((CPtr)op1, op2);      /* In WAM bld_copy() */
00482   XSB_End_Instr()
00483 
00484   XSB_Start_Instr(getpval,_getpval) /* PVR */
00485     Def2ops
00486     Op1(Variable(get_xvx));
00487     Op2(Register(get_xxr));
00488     ADVANCE_PC(size_xxx);
00489     unify_xsb(_getpval);
00490   XSB_End_Instr()
00491 
00492   XSB_Start_Instr(getstrv,_getstrv) /* PPV-S */
00493     Def2ops
00494     Op1(Variable(get_xxv));
00495     Op2(get_xxxs);
00496     ADVANCE_PC(size_xxxX);
00497     nunify_with_str(op1,op2);
00498   XSB_End_Instr()
00499 
00500   XSB_Start_Instr(gettval,_gettval) /* PRR */
00501     Def2ops
00502     Op1(Register(get_xrx));
00503     Op2(Register(get_xxr));
00504     ADVANCE_PC(size_xxx);
00505     unify_xsb(_gettval);
00506   XSB_End_Instr()
00507 
00508   XSB_Start_Instr(getcon,_getcon) /* PPR-C */
00509     Def2ops
00510     Op1(Register(get_xxr));
00511     Op2(get_xxxc);
00512     ADVANCE_PC(size_xxxX);
00513     nunify_with_con(op1,op2);
00514   XSB_End_Instr()
00515 
00516   XSB_Start_Instr(getnil,_getnil) /* PPR */
00517     Def1op
00518     Op1(Register(get_xxr));
00519     ADVANCE_PC(size_xxx);
00520     nunify_with_nil(op1);
00521   XSB_End_Instr()       
00522 
00523   XSB_Start_Instr(getstr,_getstr) /* PPR-S */
00524     Def2ops
00525     Op1(Register(get_xxr));
00526     Op2(get_xxxs);
00527     ADVANCE_PC(size_xxxX);
00528     nunify_with_str(op1,op2);
00529   XSB_End_Instr()
00530 
00531   XSB_Start_Instr(getlist,_getlist) /* PPR */
00532     Def1op
00533     Op1(Register(get_xxr));
00534     ADVANCE_PC(size_xxx);
00535     nunify_with_list_sym(op1);
00536   XSB_End_Instr()
00537 
00538   XSB_Start_Instr(getattv,_getattv) /* PPR */
00539     Def1op
00540     Op1(Register(get_xxr));
00541     ADVANCE_PC(size_xxx);
00542     nunify_with_attv(op1);
00543   XSB_End_Instr()
00544 
00545 /* TLS: Need trailing here: for a full explanation, see "A Note on
00546    Trailing in the SLGWAM on my web page. */
00547   XSB_Start_Instr(unipvar,_unipvar) /* PPV */
00548     Def1op
00549     Op1(get_xxv);
00550     ADVANCE_PC(size_xxx);
00551     if (!flag) {        /* if (flag == READ) */
00552       /* also introduce trailing here - bmd & kostis
00553          was: bld_copy((CPtr)op1, *(sreg++)); */
00554       bind_copy((CPtr)op1, *(sreg));
00555       sreg++;
00556     } else {
00557       bind_ref((CPtr)op1, hreg);
00558       new_heap_free(hreg);
00559     }
00560   XSB_End_Instr()
00561 
00562   XSB_Start_Instr(unipval,_unipval) /* PPV */
00563     Def2ops
00564     Op1(Variable(get_xxv));
00565     ADVANCE_PC(size_xxx);
00566     if (flag) { /* if (flag == WRITE) */
00567       nbldval(op1); 
00568     } 
00569     else {
00570       op2 = *(sreg++);
00571       unify_xsb(_unipval);
00572     } 
00573   XSB_End_Instr()
00574 
00575   XSB_Start_Instr(unitvar,_unitvar) /* PPR */
00576     Def1op
00577     Op1(get_xxr);
00578     ADVANCE_PC(size_xxx);
00579     if (!flag) {        /* if (flag == READ) */
00580       bld_copy((CPtr)op1, *(sreg++));
00581     }
00582     else {
00583       bld_ref((CPtr)op1, hreg);
00584       new_heap_free(hreg);
00585     }
00586   XSB_End_Instr()
00587 
00588     /* "avar" stands for anonymous variable */
00589   XSB_Start_Instr(uniavar,_uniavar) /* PPP */
00590     ADVANCE_PC(size_xxx);
00591     if (!flag) {        /* if (flag == READ) */
00592       sreg++;
00593     }
00594     else {
00595       new_heap_free(hreg);
00596     }
00597   XSB_End_Instr()
00598 
00599   XSB_Start_Instr(unitval,_unitval) /* PPR */
00600     Def2ops
00601     Op1(Register(get_xxr));
00602     ADVANCE_PC(size_xxx);
00603     if (flag) { /* if (flag == WRITE) */
00604       nbldval(op1); 
00605       XSB_Next_Instr();
00606     }
00607     else {
00608       op2 = *(sreg++);
00609       unify_xsb(_unitval);
00610     } 
00611   XSB_End_Instr()
00612 
00613   XSB_Start_Instr(unicon,_unicon) /* PPP-C */
00614     Def2ops
00615     Op2(get_xxxc);
00616     ADVANCE_PC(size_xxxX);
00617     if (flag) { /* if (flag == WRITE) */
00618       new_heap_string(hreg, (char *)op2);
00619     }
00620     else {  
00621       /* op2 already set */
00622       op1 = *(sreg++);
00623       nunify_with_con(op1,op2);
00624     }
00625   XSB_End_Instr()
00626 
00627   XSB_Start_Instr(uninil,_uninil) /* PPP */
00628     Def1op
00629     ADVANCE_PC(size_xxx);
00630     if (flag) { /* if (flag == WRITE) */
00631       new_heap_nil(hreg);
00632     }
00633     else {
00634       op1 = *(sreg++);
00635       nunify_with_nil(op1);
00636     }
00637   XSB_End_Instr()
00638 
00639   XSB_Start_Instr(getnumcon,_getnumcon) /* PPR-B */
00640     Def2ops
00641     Op1(Register(get_xxr));
00642     Op2(get_xxxn);
00643     ADVANCE_PC(size_xxxX);
00644     nunify_with_num(op1,op2);
00645   XSB_End_Instr()
00646 
00647   XSB_Start_Instr(getfloat,_getfloat) /* PPR-F */
00648     //printf("\nGETFLOAT ENTERED!\n");
00649     Def2fops
00650     Op1(Register(get_xxr));
00651     Op2f(get_xxxf);
00652     ADVANCE_PC(size_xxxX);
00653     nunify_with_float_get(op1,fop2);
00654     //printf("\nGETFLOAT LEFT!\n");
00655   XSB_End_Instr()
00656 
00657   XSB_Start_Instr(putnumcon,_putnumcon) /* PPR-B */
00658     Def2ops
00659     Op1(get_xxr);
00660 /*      Op2(get_xxxn); */
00661     op2 = *(pw)(lpcreg+sizeof(Cell));
00662     ADVANCE_PC(size_xxxX);
00663     bld_oint((CPtr)op1, op2);
00664   XSB_End_Instr()
00665 
00666   XSB_Start_Instr(putfloat,_putfloat) /* PPR-F */
00667     //printf("\nPUTFLOAT ENTERED!\n");
00668     Def2fops
00669     Op1(get_xxr);
00670     Op2f(get_xxxf);
00671     ADVANCE_PC(size_xxxX);
00672     //    bld_float_tagged((CPtr)op1, fop2);
00673     bld_boxedfloat(CTXTc (CPtr)op1, fop2);
00674     //printf("\nPUTFLOAT DONE!\n");
00675   XSB_End_Instr()
00676 
00677   XSB_Start_Instr(putpvar,_putpvar) /* PVR */
00678     Def2ops
00679     Op1(get_xvx);
00680     Op2(get_xxr);
00681     ADVANCE_PC(size_xxx);
00682     bld_free((CPtr)op1);
00683     bld_ref((CPtr)op2, (CPtr)op1);
00684   XSB_End_Instr()
00685 
00686     /* does not dereference op1 (as opposed to putdval) */
00687   XSB_Start_Instr(putpval,_putpval) /* PVR */
00688     DefOps13
00689     Op1(get_xvx);
00690     Op3(get_xxr);
00691     ADVANCE_PC(size_xxx);
00692     bld_copy(op3, *((CPtr)op1));
00693   XSB_End_Instr()
00694 
00695   XSB_Start_Instr(puttvar,_puttvar) /* PRR */
00696     Def2ops
00697     Op1(get_xrx);
00698     Op2(get_xxr);
00699     ADVANCE_PC(size_xxx);
00700     bld_ref((CPtr)op1, hreg);
00701     bld_ref((CPtr)op2, hreg);
00702     new_heap_free(hreg); 
00703   XSB_End_Instr()
00704 
00705 /* TLS: Need trailing here: for a full explanation, see "A Note on
00706    Trailing in the SLGWAM on my web page. */
00707   XSB_Start_Instr(putstrv,_putstrv) /*  PPV-S */
00708     Def2ops
00709     Op1(get_xxv);
00710     Op2(get_xxxs);
00711     ADVANCE_PC(size_xxxX);
00712     bind_cs((CPtr)op1, (Pair)hreg);
00713     new_heap_functor(hreg, (Psc)op2); 
00714   XSB_End_Instr()
00715 
00716   XSB_Start_Instr(putcon,_putcon) /* PPR-C */
00717     Def2ops
00718     Op1(get_xxr);
00719     Op2(get_xxxc);
00720     ADVANCE_PC(size_xxxX);
00721     //printf("PUTCON entered! String is %s\n", (char *) op2);
00722     bld_string((CPtr)op1, (char *)op2);
00723   XSB_End_Instr()
00724 
00725   XSB_Start_Instr(putnil,_putnil) /* PPR */
00726     Def1op
00727     Op1(get_xxr);
00728     ADVANCE_PC(size_xxx);
00729     bld_nil((CPtr)op1);
00730   XSB_End_Instr()
00731 
00732 /* doc tls -- differs from putstrv since it pulls from a register.
00733    Thus the variable is already initialized.  */
00734   XSB_Start_Instr(putstr,_putstr) /* PPR-S */
00735     Def2ops
00736     Op1(get_xxr);
00737     Op2(get_xxxs);
00738     ADVANCE_PC(size_xxxX);
00739     bld_cs((CPtr)op1, (Pair)hreg);
00740     new_heap_functor(hreg, (Psc)op2); 
00741   XSB_End_Instr()
00742 
00743   XSB_Start_Instr(putlist,_putlist) /* PPR */
00744     Def1op
00745     Op1(get_xxr);
00746     ADVANCE_PC(size_xxx);
00747     bld_list((CPtr)op1, hreg);
00748   XSB_End_Instr()
00749 
00750   XSB_Start_Instr(putattv,_putattv) /* PPR */
00751     Def1op
00752     Op1(get_xxr);
00753     ADVANCE_PC(size_xxx);
00754     bld_attv((CPtr)op1, hreg);
00755     new_heap_free(hreg);
00756   XSB_End_Instr()
00757 
00758 /* TLS: Need trailing here: for a full explanation, see "A Note on
00759    Trailing in the SLGWAM on my web page. */
00760   XSB_Start_Instr(bldpvar,_bldpvar) /* PPV */
00761     Def1op
00762     Op1(get_xxv);
00763     ADVANCE_PC(size_xxx);
00764     bind_ref((CPtr)op1, hreg); /* trailing is needed: if o/w see ai_tests */
00765     new_heap_free(hreg);
00766   XSB_End_Instr()
00767 
00768   XSB_Start_Instr(bldpval,_bldpval) /* PPV */
00769     Def1op
00770     Op1(Variable(get_xxv));
00771     ADVANCE_PC(size_xxx);
00772     nbldval(op1);
00773   XSB_End_Instr()
00774 
00775   XSB_Start_Instr(bldtvar,_bldtvar) /* PPR */
00776     Def1op
00777     Op1(get_xxr);
00778     ADVANCE_PC(size_xxx);
00779     bld_ref((CPtr)op1, hreg);
00780     new_heap_free(hreg);
00781   XSB_End_Instr()
00782 
00783   XSB_Start_Instr(bldavar,_bldavar) /* PPR */
00784     ADVANCE_PC(size_xxx);
00785     new_heap_free(hreg);
00786   XSB_End_Instr()
00787 
00788   XSB_Start_Instr(bldtval,_bldtval) /* PPR */
00789     Def1op
00790     Op1(Register(get_xxr));
00791     ADVANCE_PC(size_xxx);
00792     nbldval(op1);
00793   XSB_End_Instr()
00794 
00795   XSB_Start_Instr(bldcon,_bldcon) /* PPP-C */
00796     Def1op
00797     Op1(get_xxxc);
00798     ADVANCE_PC(size_xxxX);
00799     new_heap_string(hreg, (char *)op1);
00800   XSB_End_Instr()
00801 
00802   XSB_Start_Instr(bldnil,_bldnil) /* PPP */
00803     ADVANCE_PC(size_xxx);
00804     new_heap_nil(hreg);
00805   XSB_End_Instr()
00806 
00807   XSB_Start_Instr(getlist_tvar_tvar,_getlist_tvar_tvar) /* RRR */
00808     Def3ops
00809     Op1(Register(get_rxx));
00810     Op2(get_xrx);
00811     Op3(get_xxr);
00812     ADVANCE_PC(size_xxx);
00813     XSB_Deref(op1);
00814     if (islist(op1)) {
00815       sreg = clref_val(op1);
00816       op1 = (Cell)op2;
00817       bld_ref((CPtr)op1, *(sreg));
00818       op1 = (Cell)op3;
00819       bld_ref((CPtr)op1, *(sreg+1));
00820     } else if (isref(op1)) {
00821       bind_list((CPtr)(op1), hreg);
00822       op1 = (Cell)op2;
00823       bld_ref((CPtr)op1, hreg);
00824       new_heap_free(hreg);
00825       op1 = (Cell)op3;
00826       bld_ref((CPtr)op1, hreg);
00827       new_heap_free(hreg);
00828      } else if (isattv(op1)) {
00829       attv_dbgmsg(">>>> getlist_tvar_tvar: ATTV interrupt needed\n");
00830       add_interrupt(CTXTc op1, makelist(hreg));
00831       op1 = (Cell)op2;
00832       bld_ref((CPtr)op1, hreg);
00833       new_heap_free(hreg);
00834       op1 = (Cell)op3;
00835       bld_ref((CPtr)op1, hreg);
00836       new_heap_free(hreg);
00837     }
00838     else Fail1;
00839   XSB_End_Instr()       /* end getlist_tvar_tvar */
00840 
00841   XSB_Start_Instr(uninumcon,_uninumcon) /* PPP-B */
00842     Def2ops
00843     Op2(get_xxxn); /* num in op2 */
00844     ADVANCE_PC(size_xxxX);
00845     if (flag) { /* if (flag == WRITE) */
00846       new_heap_num(hreg, makeint(op2));
00847     }
00848     else {  /* op2 set */
00849       op1 = *(sreg++);
00850       nunify_with_num(op1,op2);
00851     }
00852   XSB_End_Instr()
00853 
00854   XSB_Start_Instr(unifloat,_unifloat) /* PPPF */
00855     //printf("UNIFLOAT ENTERED\n");
00856     Def2fops
00857     Op2f(get_xxxf); /* num in fop2 */
00858     ADVANCE_PC(size_xxxX);
00859     if (flag) { /* if (flag == WRITE) */
00860       new_heap_float(hreg, makefloat(fop2));
00861     }
00862     else {  /* fop2 set */
00863       op1 = cell(sreg++);
00864       nunify_with_float(op1,fop2);
00865     }
00866     //printf("UNIFLOAT LEFT\n");
00867   XSB_End_Instr()
00868 
00869   XSB_Start_Instr(bldnumcon,_bldnumcon) /* PPP-B */
00870     Def1op
00871     Op1(get_xxxn);  /* num to op2 */
00872     ADVANCE_PC(size_xxxX);
00873     new_heap_num(hreg, (Integer)makeint(op1));
00874   XSB_End_Instr()
00875 
00876   XSB_Start_Instr(bldfloat,_bldfloat) /* PPP-F */
00877     //printf("BLDFLOAT ENTERED\n");
00878     Def1fop
00879     Op2f(get_xxxf); /* num to fop2 */
00880     ADVANCE_PC(size_xxxX);
00881     new_heap_float(hreg, makefloat(fop2));
00882     //printf("BLDFLOAT LEFT\n");
00883   XSB_End_Instr()
00884 
00885   XSB_Start_Instr(trymeelse,_trymeelse) /* PPA-L */
00886     Def2ops
00887     Op1(get_xxa);
00888     Op2(get_xxxl);
00889 #if 0
00890     { 
00891       Psc mypsc = *(CPtr)(cpreg-4);
00892       if (mypsc)
00893         if (get_type(mypsc) == T_PRED) {
00894           fprintf(stddbg,"creating_cp(trymeelse(%s/%d), %p).\n",
00895                   get_name(mypsc), get_arity(mypsc), breg);
00896         }
00897     }
00898 #endif
00899     ADVANCE_PC(size_xxxX);
00900     SUBTRYME
00901   XSB_End_Instr()
00902 
00903   XSB_Start_Instr(dyntrymeelse,_dyntrymeelse) /* PPA-L */
00904     Def2ops
00905     Op1(get_xxa);
00906     Op2(get_xxxl);
00907     ADVANCE_PC(size_xxxX);
00908     SUBTRYME
00909 #ifdef MULTI_THREAD
00910     if (i_have_dyn_mutex) {
00911       SYS_MUTEX_UNLOCK(MUTEX_DYNAMIC);
00912       i_have_dyn_mutex = 0;
00913     }
00914 #endif
00915   XSB_End_Instr()
00916 
00917   XSB_Start_Instr(retrymeelse,_retrymeelse) /* PPA-L */
00918     Def1op
00919     Op1(get_xxa);
00920     cp_pcreg(breg) = (byte *)get_xxxl;
00921     restore_type = 0;
00922     ADVANCE_PC(size_xxxX);
00923     RESTORE_SUB
00924   XSB_End_Instr()
00925 
00926       /* TLS: added to distinguish dynamic from static choice points when 
00927          gc-ing retracted clauses. */ 
00928 
00929   XSB_Start_Instr(dynretrymeelse,_dynretrymeelse) /* PPA-L */
00930     Def1op
00931     Op1(get_xxa);
00932     cp_pcreg(breg) = (byte *)get_xxxl;
00933     restore_type = 0;
00934     ADVANCE_PC(size_xxxX);
00935     RESTORE_SUB
00936   XSB_End_Instr()
00937 
00938       /* TLS: according to David.  It may be that a call to a
00939        *  predicate P performs a lot of shallow backtracking esp. to
00940        *  facts. If so, the interrupt might not be handled until the
00941        *  engine is not executing P any more.  Putting the handler in
00942        *  trusts means that any interrupt posted during the
00943        *  backtracking will be caught, and thus gives the profiler a
00944        *  better chance of accurately reflecting where the time is
00945        *  spent. */
00946 
00947   XSB_Start_Instr(trustmeelsefail,_trustmeelsefail) /* PPA */
00948     Def1op
00949     Op1(get_xxa);
00950     restore_type = 1;
00951     handle_xsb_profile_interrupt;
00952     ADVANCE_PC(size_xxx);
00953     RESTORE_SUB
00954   XSB_End_Instr()
00955 
00956   XSB_Start_Instr(try,_try) /* PPA-L */
00957     Def2ops
00958     Op1(get_xxa);
00959     op2 = (Cell)((Cell)lpcreg + sizeof(Cell)*2);
00960 #if 0
00961     { 
00962       Psc mypsc = *(CPtr)(cpreg-4);
00963       if (mypsc)
00964         if (get_type(mypsc) == T_PRED) {
00965           fprintf(stddbg,"creating_cp(try(%s/%d), %p).\n",
00966                   get_name(mypsc), get_arity(mypsc), breg);
00967         }
00968     }
00969 #endif
00970     lpcreg = *(pb *)(lpcreg+sizeof(Cell)); /* = *(pointer to byte pointer) */
00971     SUBTRYME
00972   XSB_End_Instr()
00973 
00974   XSB_Start_Instr(retry,_retry) /* PPA-L */
00975     Def1op
00976     Op1(get_xxa);
00977     cp_pcreg(breg) = lpcreg+sizeof(Cell)*2;
00978     lpcreg = *(pb *)(lpcreg+sizeof(Cell));
00979     restore_type = 0;
00980     RESTORE_SUB
00981   XSB_End_Instr()
00982 
00983   XSB_Start_Instr(trust,_trust) /* PPA-L */
00984     Def1op
00985     Op1(get_xxa);
00986     handle_xsb_profile_interrupt;
00987     lpcreg = *(pb *)(lpcreg+sizeof(Cell));
00988     restore_type = 1;
00989     RESTORE_SUB
00990   XSB_End_Instr()
00991 
00992       /* Used for tabling: puts a pointer to the subgoal_frame in the 
00993          local environment for a tabled subgoal */       
00994   XSB_Start_Instr(getVn,_getVn) /* PPV */
00995     Def1op
00996     Op1(get_xxv);
00997     ADVANCE_PC(size_xxx);
00998     cell((CPtr)op1) = (Cell)tcp_subgoal_ptr(breg);
00999   XSB_End_Instr()
01000 
01001   XSB_Start_Instr(getpbreg,_getpbreg) /* PPV */
01002     Def1op
01003     Op1(get_xxv);
01004     ADVANCE_PC(size_xxx);
01005     bld_int((CPtr)op1, ((pb)tcpstack.high - (pb)breg));
01006   XSB_End_Instr()
01007 
01008   XSB_Start_Instr(gettbreg,_gettbreg) /* PPR */
01009     Def1op
01010     Op1(get_xxr);
01011     ADVANCE_PC(size_xxx);
01012     bld_int((CPtr)op1, ((pb)tcpstack.high - (pb)breg));
01013   XSB_End_Instr()
01014 
01015   XSB_Start_Instr(putpbreg,_putpbreg) /* PPV */
01016     Def1op
01017     Op1(Variable(get_xxv));
01018     ADVANCE_PC(size_xxx);
01019     cut_code(op1);
01020   XSB_End_Instr()
01021 
01022   XSB_Start_Instr(puttbreg,_puttbreg) /* PPR */
01023     Def1op
01024     Op1(Register(get_xxr));
01025     ADVANCE_PC(size_xxx);
01026     cut_code(op1);
01027   XSB_End_Instr()
01028 
01029   XSB_Start_Instr(jumptbreg,_jumptbreg) /* PPR-L */     /* ??? */
01030     Def1op
01031     Op1(get_xxr);
01032     bld_int((CPtr)op1, ((pb)tcpstack.high - (pb)breg));
01033     lpcreg = *(byte **)(lpcreg+sizeof(Cell));
01034 #ifdef MULTI_THREAD
01035     if (i_have_dyn_mutex) xsb_abort("DYNAMIC MUTEX ERROR\n");
01036     SYS_MUTEX_LOCK(MUTEX_DYNAMIC);
01037     i_have_dyn_mutex = 1;
01038 #endif
01039   XSB_End_Instr()
01040 
01041   XSB_Start_Instr(test_heap,_test_heap) /* PPA-N */
01042     Def2ops
01043     Op1(get_xxa); /* op1 = the arity of the procedure */
01044     Op2(get_xxxn);
01045     ADVANCE_PC(size_xxxX);
01046 #ifdef GC_TEST
01047     if ((infcounter++ > GC_INFERENCES) || ((ereg - hreg) < (long)op2))
01048       {
01049         infcounter = 0;
01050         fprintf(stddbg, ".");
01051 #else
01052     if ((ereg - hreg) < (long)op2)
01053       {
01054 #endif
01055         if (gc_heap(CTXTc op1,FALSE)) { /* garbage collection potentially modifies hreg */
01056           if ((ereg - hreg) < (long)op2) {
01057             if (pflags[STACK_REALLOC]) {
01058               if (glstack_realloc(CTXTc resize_stack(glstack.size,(op2*sizeof(Cell))),op1) != 0) {
01059                 xsb_basic_abort(local_global_exception);
01060               }
01061             } else {
01062               xsb_warn("Reallocation is turned OFF !");
01063               xsb_basic_abort(local_global_exception);
01064             }
01065           }
01066         }
01067         /* are there any localy cached quantities that must be reinstalled ? */
01068       }
01069   XSB_End_Instr()
01070 
01071   XSB_Start_Instr(switchonterm,_switchonterm) /* PPR-L-L */
01072     Def1op
01073     Op1(Register(get_xxr));
01074     XSB_Deref(op1);
01075     switch (cell_tag(op1)) {
01076     case XSB_INT:
01077     case XSB_STRING:
01078     case XSB_FLOAT:
01079       lpcreg = *(pb *)(lpcreg+sizeof(Cell));        
01080       break;
01081     case XSB_FREE:
01082     case XSB_REF1:
01083     case XSB_ATTV:
01084       ADVANCE_PC(size_xxxXX);
01085       break;
01086     case XSB_STRUCT:
01087       if (isboxedfloat(op1))
01088       {
01089           lpcreg = *(pb *)(lpcreg+sizeof(Cell));
01090           break;
01091       }
01092       if (get_arity(get_str_psc(op1)) == 0) {
01093         lpcreg = *(pb *)(lpcreg+sizeof(Cell));
01094         break;
01095       }
01096     case XSB_LIST:      /* include structure case here */
01097       lpcreg = *(pb *)(lpcreg+sizeof(Cell)*2); 
01098       break;
01099     }
01100   XSB_End_Instr()
01101 
01102 #define struct_hash_value(op1) \
01103    (isboxedinteger(op1)?boxedint_val(op1): \
01104     (isboxedfloat(op1)?  \
01105      int_val(cell(clref_val(op1)+1)) ^ int_val(cell(clref_val(op1)+2)) ^ int_val(cell(clref_val(op1)+3)): \
01106      (Cell)get_str_psc(op1)))
01107 
01108   XSB_Start_Instr(switchonbound,_switchonbound) /* PPR-L-L */
01109     Def3ops
01110     /* op1 is register, op2 is hash table offset, op3 is modulus */
01111     Op1(get_xxr);
01112     XSB_Deref(op1);
01113     switch (cell_tag(op1)) {
01114     case XSB_STRUCT:
01115       op1 = struct_hash_value(op1);
01116       break;
01117     case XSB_STRING:    /* We should change the compiler to avoid this test */
01118       op1 = (Cell)(isnil(op1) ? 0 : string_val(op1));
01119       break;
01120     case XSB_INT: 
01121     case XSB_FLOAT:  /* cvt to double and use that indexing.... */
01122       op1 = (Cell)int_val(op1);
01123       break;
01124     case XSB_LIST:
01125       op1 = (Cell)(list_pscPair); 
01126       break;
01127     case XSB_FREE:
01128     case XSB_REF1:
01129     case XSB_ATTV:
01130       lpcreg += 3 * sizeof(Cell);
01131       XSB_Next_Instr();
01132     }
01133     op2 = (Cell)(*(byte **)(lpcreg+sizeof(Cell)));
01134     op3 = *(CPtr *)(lpcreg+sizeof(Cell)*2);
01135     /* doc tls -- op2 + (op1%size)*4 */
01136     lpcreg =
01137       *(byte **)((byte *)op2 + ihash((Cell)op1, (Cell)op3) * sizeof(Cell));
01138   XSB_End_Instr()
01139 
01140   XSB_Start_Instr(switchon3bound,_switchon3bound) /* RRR-L-L */
01141     Def3ops
01142     int  i, j = 0;
01143     int indexreg[3];
01144     Cell opa[3]; 
01145     /* op1 is register contents, op2 is hash table offset, op3 is modulus */
01146     indexreg[0] = get_axx;
01147     indexreg[1] = get_xax;
01148     indexreg[2] = get_xxa;
01149 
01150     if (*lpcreg == 0) { opa[0] = 0; }
01151     else opa[0] = Register((rreg + (indexreg[0] & 0x7f)));
01152     opa[1] = Register((rreg + (indexreg[1] & 0x7f)));
01153     opa[2] = Register((rreg + (indexreg[2] & 0x7f)));
01154     op2 = (Cell)(*(byte **)(lpcreg+sizeof(Cell)));
01155     op3 = *(CPtr *)(lpcreg+sizeof(Cell)*2); 
01156     /* This is not a good way to do this, but until we put retract into C,
01157        or add new builtins, it will have to do. */
01158     for (i = 0; i <= 2; i++) {
01159       if (indexreg[i] != 0) {
01160         if (indexreg[i] > 0x80) {
01161           int k, depth = 0;
01162           Cell *stk[MAXTOINDEX];
01163           int argsleft[MAXTOINDEX];
01164           stk[0] = &opa[i];
01165           argsleft[0] = 1;
01166 
01167           for (k = MAXTOINDEX; k > 0; k--) {
01168             if (depth < 0) break;
01169             op1 = *stk[depth];
01170             argsleft[depth]--;
01171             if (argsleft[depth] <= 0) depth--;
01172             else stk[depth]++;
01173             XSB_Deref(op1);
01174             switch (cell_tag(op1)) {
01175             case XSB_FREE:
01176             case XSB_REF1:
01177             case XSB_ATTV:
01178               ADVANCE_PC(size_xxxXX);
01179               XSB_Next_Instr();
01180             case XSB_INT: 
01181             case XSB_FLOAT:     /* Yes, use int_val to avoid conversion problem */
01182               op1 = (Cell)int_val(op1);
01183               break;
01184             case XSB_LIST:
01185               depth++;
01186               argsleft[depth] = 2;
01187               stk[depth] = clref_val(op1);
01188               op1 = (Cell)(list_pscPair); 
01189               break;
01190             case XSB_STRUCT:
01191               if (isboxedinteger(op1)) op1 = (Cell)boxedint_val(op1);
01192               else if (isboxedfloat(op1)) 
01193                 op1 = int_val(cell(clref_val(op1)+1)) ^
01194                   int_val(cell(clref_val(op1)+2)) ^
01195                   int_val(cell(clref_val(op1)+3));
01196               else {
01197                 depth++;
01198                 argsleft[depth] = get_arity(get_str_psc(op1));
01199                 stk[depth] = clref_val(op1)+1;
01200                 //op1 = (Cell)get_str_psc(op1);
01201                 op1 = struct_hash_value(op1);
01202               }
01203               break;
01204             case XSB_STRING:
01205               op1 = (Cell)string_val(op1);
01206               break;
01207             }
01208             j = (j<<1) + ihash((Cell)op1, (Cell)op3);
01209           }
01210       } else {
01211         op1 = opa[i];
01212         XSB_Deref(op1);
01213         switch (cell_tag(op1)) {
01214         case XSB_FREE:
01215         case XSB_REF1:
01216         case XSB_ATTV:
01217           ADVANCE_PC(size_xxxXX);
01218           XSB_Next_Instr();
01219         case XSB_INT: 
01220         case XSB_FLOAT: /* Yes, use int_val to avoid conversion problem */
01221           op1 = (Cell)int_val(op1);
01222           break;
01223         case XSB_LIST:
01224           op1 = (Cell)(list_pscPair); 
01225           break;
01226         case XSB_STRUCT:
01227           //      op1 = (Cell)get_str_psc(op1);
01228           op1 = struct_hash_value(op1);
01229           break;
01230         case XSB_STRING:
01231           op1 = (Cell)string_val(op1);
01232           break;
01233         default:
01234           xsb_error("Illegal operand in switchon3bound");
01235           break;
01236         }
01237         j = (j<<1) + ihash((Cell)op1, (Cell)op3);
01238       }
01239       }
01240     }
01241     lpcreg = *(byte **)((byte *)op2 + ((j % (Cell)op3) * sizeof(Cell)));
01242   XSB_End_Instr()
01243 
01244   XSB_Start_Instr(switchonthread,_switchonthread) /* PPP-L */
01245 #ifdef MULTI_THREAD
01246     Def1op
01247     Op1(get_xxxl);
01248     if (th->tid > *((long *)op1+2)) Fail1;
01249     //    fprintf(stderr,"switchonthread to %p\n",(pb)(*((long *)op1+3+(th->tid))));
01250     if (!(lpcreg = (pb)(*((long *)op1+3+(th->tid))))) Fail1;
01251 #else
01252     xsb_exit("Not configured for Multithreading");
01253 #endif
01254   XSB_End_Instr()
01255 
01256   XSB_Start_Instr(trymeorelse,_trymeorelse) /* PPA-L */
01257     Def2ops
01258     Op1(0);
01259     Op2(get_xxxl);
01260 #if 0
01261     { 
01262       Psc mypsc = *(CPtr)(cpreg-4);
01263       if (mypsc)
01264         if (get_type(mypsc) == T_PRED) {
01265           fprintf(stddbg,"creating_cp(trymeorelse(%s/%d), %p).\n",
01266                   get_name(mypsc), get_arity(mypsc), breg);
01267         }
01268     }
01269 #endif
01270     ADVANCE_PC(size_xxxX);
01271     cpreg = lpcreg; /* Another use of cpreg for inline try's for disjunctions */
01272     SUBTRYME
01273   XSB_End_Instr()
01274 
01275   XSB_Start_Instr(retrymeorelse,_retrymeorelse) /* PPA-L */
01276     Def1op
01277     Op1(0);
01278     cp_pcreg(breg) = *(byte **)(lpcreg+sizeof(Cell));
01279     ADVANCE_PC(size_xxxX);
01280     restore_type = 0;
01281     RESTORE_SUB
01282   XSB_End_Instr()
01283 
01284   XSB_Start_Instr(trustmeorelsefail,_trustmeorelsefail) /* PPA */
01285     Def1op
01286     Op1(0);
01287     handle_xsb_profile_interrupt;
01288     ADVANCE_PC(size_xxx);
01289     restore_type = 1;
01290     RESTORE_SUB
01291   XSB_End_Instr()
01292 
01293   XSB_Start_Instr(dyntrustmeelsefail,_dyntrustmeelsefail) /* PPA-L, second word ignored */
01294       gdb_dummy();
01295     Def1op
01296     Op1(get_xxa);
01297     handle_xsb_profile_interrupt;
01298     ADVANCE_PC(size_xxxX);
01299     restore_type = 1;
01300     RESTORE_SUB
01301   XSB_End_Instr()
01302 
01303 /*----------------------------------------------------------------------*/
01304 
01305 #include "slginsts_xsb_i.h"
01306 
01307 #include "tc_insts_xsb_i.h"
01308 
01309 /*----------------------------------------------------------------------*/
01310 
01311   XSB_Start_Instr(term_comp,_term_comp) /* RRR */
01312     Def3ops
01313     Op1(get_rxx);
01314     Op2(get_xrx);
01315     Op3(get_xxr);
01316     ADVANCE_PC(size_xxx);
01317     bld_int(op3, compare(CTXTc (void *)op1, (void *)op2));
01318   XSB_End_Instr()
01319 
01320   XSB_Start_Instr(movreg,_movreg) /* PRR */
01321     Def2ops
01322     Op1(get_xrx);
01323     Op2(get_xxr);
01324     ADVANCE_PC(size_xxx);
01325     bld_copy((CPtr) op2, *((CPtr)op1));
01326   XSB_End_Instr()
01327 
01328 #define ARITHPROC(OP, STROP)                                             \
01329     Op1(Register(get_xrx));                                              \
01330     Op3(get_xxr);                                                        \
01331     ADVANCE_PC(size_xxx);                                                \
01332     op2 = *(op3);                                                        \
01333     XSB_Deref(op1);                                                      \
01334     XSB_Deref(op2);                                                      \
01335     if (isinteger(op1)) {                                                \
01336         if (isinteger(op2)) {                                            \
01337                 Integer temp = int_val(op2) OP int_val(op1);             \
01338             bld_oint(op3, temp); }                                       \
01339         else if (isboxedfloat(op2)) {                                    \
01340                 Float temp = boxedfloat_val(op2) OP (Float)int_val(op1); \
01341             bld_boxedfloat(CTXTc op3, temp); }                           \
01342         else if (isfloat(op2)) {                                         \
01343             Float temp = float_val(op2) OP (Float)int_val(op1);          \
01344             bld_boxedfloat(CTXTc op3, temp); }                           \
01345         else if (isboxedinteger(op2)) {                                  \
01346             Integer temp = boxedint_val(op2) OP int_val(op1);            \
01347             bld_oint(op3, temp); }                                       \
01348         else { arithmetic_abort(CTXTc op2, STROP, op1); }                \
01349     }                                                                    \
01350     else if (isfloat(op1)) {                                             \
01351         if (isboxedfloat(op2)) {                                         \
01352             Float temp = boxedfloat_val(op2) OP float_val(op1);          \
01353             bld_boxedfloat(CTXTc op3, temp); }                           \
01354         else if (isfloat(op2)) {                                         \
01355             Float temp = float_val(op2) OP float_val(op1);               \
01356             bld_boxedfloat(CTXTc op3, temp); }                           \
01357         else if (isinteger(op2)) {                                       \
01358             Float temp = (Float)int_val(op2) OP float_val(op1);          \
01359             bld_boxedfloat(CTXTc op3, temp); }                           \
01360         else if (isboxedinteger(op2)) {                                  \
01361             Float temp = (Float)boxedint_val(op2) OP float_val(op1);     \
01362             bld_boxedfloat(CTXTc op3, temp); }                           \
01363         else { arithmetic_abort(CTXTc op2, STROP, op1); }                \
01364     }                                                                    \
01365     else if (isboxedfloat(op1)) {                                        \
01366         if (isboxedfloat(op2)) {                                         \
01367             Float temp = boxedfloat_val(op2) OP boxedfloat_val(op1);     \
01368             bld_boxedfloat(CTXTc op3, temp); }                           \
01369         else if (isfloat(op2)) {                                         \
01370             Float temp = float_val(op2) OP boxedfloat_val(op1);          \
01371             bld_boxedfloat(CTXTc op3, temp); }                           \
01372         else if (isinteger(op2)) {                                       \
01373             Float temp = (Float)int_val(op2) OP boxedfloat_val(op1);     \
01374             bld_boxedfloat(CTXTc op3, temp); }                           \
01375         else if (isboxedinteger(op2)) {                                  \
01376             Float temp = (Float)boxedint_val(op2) OP boxedfloat_val(op1);\
01377             bld_boxedfloat(CTXTc op3, temp); }                           \
01378         else { arithmetic_abort(CTXTc op2, STROP, op1); }                \
01379     }                                                                    \
01380     else if (isboxedinteger(op1)) {                                      \
01381         if (isinteger(op2)) {                                            \
01382             Integer temp = int_val(op2) OP boxedint_val(op1);            \
01383             bld_oint(op3, temp); }                                       \
01384         else if (isboxedinteger(op2)) {                                  \
01385             Integer temp = boxedint_val(op2) OP boxedint_val(op1);       \
01386             bld_oint(op3, temp); }                                       \
01387         else if (isboxedfloat(op2)) {                                    \
01388             Float temp = boxedfloat_val(op2) OP (Float)boxedint_val(op1);\
01389             bld_boxedfloat(CTXTc op3, temp); }                           \
01390         else if (isfloat(op2)) {                                         \
01391             Float temp = float_val(op2) OP (Float)boxedint_val(op1);     \
01392             bld_boxedfloat(CTXTc op3, temp); }                           \
01393         else { arithmetic_abort(CTXTc op2, STROP, op1); }                \
01394     }                                                                    \
01395     else { arithmetic_abort(CTXTc op2, STROP, op1); }
01396 
01397   XSB_Start_Instr(addreg,_addreg) /* PRR */
01398     Def3ops
01399     ARITHPROC(+, "+");
01400   XSB_End_Instr() 
01401 
01402   XSB_Start_Instr(subreg,_subreg) /* PRR */
01403     Def3ops
01404     ARITHPROC(-, "-");
01405   XSB_End_Instr() 
01406 
01407   XSB_Start_Instr(mulreg,_mulreg) /* PRR */
01408     Def3ops
01409     ARITHPROC(*, "*");
01410   XSB_End_Instr() 
01411 
01412    /* TLS: cant use ARITHPROC because int/int -> float */
01413   XSB_Start_Instr(divreg,_divreg) /* PRR */
01414     Def3ops
01415     Op1(Register(get_xrx));
01416     Op3(get_xxr);
01417     ADVANCE_PC(size_xxx);
01418     op2 = *(op3);
01419     XSB_Deref(op1);
01420     XSB_Deref(op2);
01421     if (isinteger(op1)) {
01422       if (isinteger(op2)) {
01423         Float temp = (Float)int_val(op2)/(Float)int_val(op1);
01424         bld_boxedfloat(CTXTc op3, temp); }
01425       else if (isofloat(op2)) {
01426         Float temp = ofloat_val(op2)/(Float)int_val(op1);
01427         bld_boxedfloat(CTXTc op3, temp); }
01428       else if (isboxedinteger(op2)) {
01429         Float temp = (Float)boxedint_val(op2)/(Float)int_val(op1);
01430         bld_boxedfloat(CTXTc op3, temp); }
01431       else { arithmetic_abort(CTXTc op2, "/", op1); }
01432     } else if (isofloat(op1)) {
01433       if (isofloat(op2)) {
01434         Float temp = ofloat_val(op2)/ofloat_val(op1);
01435         bld_boxedfloat(CTXTc op3, temp); }
01436       else if (isinteger(op2)) {
01437         Float temp = (Float)int_val(op2)/ofloat_val(op1);
01438         bld_boxedfloat(CTXTc op3, temp); }
01439       else if (isboxedinteger(op2)) {
01440         Float temp = (Float)boxedint_val(op2)/ofloat_val(op1);
01441         bld_boxedfloat(CTXTc op3, temp); }
01442       else { arithmetic_abort(CTXTc op2, "/", op1); }
01443     } else if (isboxedinteger(op1)) {
01444       if (isinteger(op2)) {
01445         Float temp = (Float)int_val(op2) / (Float)boxedint_val(op1);
01446         bld_boxedfloat(CTXTc op3, temp); }
01447       else if (isboxedinteger(op2)) {
01448         Integer temp = (Integer) ((Float)boxedint_val(op2) / (Float)boxedint_val(op1));
01449         bld_boxedfloat(CTXTc op3, temp); }
01450       else if (isofloat(op2)) {
01451         Float temp = (Float)ofloat_val(op2) / (Float)boxedint_val(op1);
01452         bld_boxedfloat(CTXTc op3, temp); }
01453       else { arithmetic_abort(CTXTc op2, "/", op1); }
01454     } else { arithmetic_abort(CTXTc op2, "/", op1); }
01455   XSB_End_Instr() 
01456 
01457   XSB_Start_Instr(idivreg,_idivreg) /* PRR */
01458     Def3ops
01459     Op1(Register(get_xrx));
01460     Op3(get_xxr);
01461     ADVANCE_PC(size_xxx);
01462     op2 = *(op3);
01463     XSB_Deref(op1);
01464     XSB_Deref(op2);
01465       if (isinteger(op1)) {
01466         if (int_val(op1) != 0) {
01467           if (isinteger(op2)) {
01468             Integer temp = int_val(op2) / int_val(op1);
01469             bld_oint(op3, temp); 
01470           } else if (isboxedinteger(op2)) {
01471             Integer temp = boxedint_val(op2) / int_val(op1);
01472             bld_oint(op3, temp); 
01473           } else { arithmetic_abort(CTXTc op2, "//", op1); }
01474         } else {
01475           err_handle(CTXTc ZERO_DIVIDE, 2,
01476                      "arithmetic expression involving is/2 or eval/2",
01477                      2, "non-zero number", op1);
01478           lpcreg = pcreg;
01479         }
01480       } else if (isboxedinteger(op1)) {
01481         if (isinteger(op2)) {
01482           Integer temp = int_val(op2) / boxedint_val(op1);
01483           bld_oint(op3, temp);
01484         } else if (isboxedinteger(op2)) {
01485           Integer temp = boxedint_val(op2) / boxedint_val(op1);
01486           bld_oint(op3, temp);
01487         }
01488       }
01489     else { arithmetic_abort(CTXTc op2, "//", op1); }
01490   XSB_End_Instr() 
01491 
01492   XSB_Start_Instr(int_test_z,_int_test_z)   /* PPR-B-L */
01493     Def3ops
01494     Op1(Register(get_xxr));
01495     Op2(get_xxxn);
01496     Op3(get_xxxxl);
01497     ADVANCE_PC(size_xxxXX);
01498     XSB_Deref(op1); 
01499     if (isnumber(op1)) {
01500       if (int_val(op1) == (Integer)op2)
01501         lpcreg = (byte *)op3;
01502     }
01503     else if (isboxedinteger(op1)) {
01504        if (oint_val(op1) == (Integer)op2)
01505           lpcreg = (byte *)op3;
01506     }     
01507     else if (isboxedfloat(op1)) {
01508       if (ofloat_val(op1) == (double)op2)
01509         lpcreg = (byte *) op3;
01510     }
01511     else {
01512       arithmetic_comp_abort(CTXTc op1, "=\\=", op2);
01513     }
01514   XSB_End_Instr()
01515 
01516   XSB_Start_Instr(int_test_nz,_int_test_nz)   /* PPR-B-L */
01517     Def3ops
01518     Op1(Register(get_xxr));
01519     Op2(get_xxxn);
01520     Op3(get_xxxxl);
01521     ADVANCE_PC(size_xxxXX);
01522     XSB_Deref(op1); 
01523     if (isnumber(op1)) {
01524       if (int_val(op1) != (Integer)op2)
01525         lpcreg = (byte *) op3;
01526     }
01527     else if (isboxedinteger(op1)) {
01528        if (oint_val(op1) != (Integer)op2)
01529           lpcreg = (byte *)op3;
01530     }     
01531     else if (isboxedfloat(op1)) {
01532       if (ofloat_val(op1) != (double)op2)
01533         lpcreg = (byte *) op3;
01534     }
01535     else {
01536       arithmetic_comp_abort(CTXTc op1, "=:=", op2);
01537     }
01538   XSB_End_Instr()
01539 
01540     /* Used for the @=/2 operator */
01541   XSB_Start_Instr(fun_test_ne,_fun_test_ne)   /* PRR-L */
01542     Def3ops
01543     Op1(Register(get_xrx));
01544     Op2(Register(get_xxr));
01545     XSB_Deref(op1);
01546     XSB_Deref(op2);
01547     if (isconstr(op1)) {
01548       if (!isconstr(op2) || get_str_psc(op1) != get_str_psc(op2)) {
01549         Op3(get_xxxl);
01550         lpcreg = (byte *) op3;
01551       } else {
01552         ADVANCE_PC(size_xxxX);
01553       }
01554     } else if (islist(op1)) {
01555       if (!islist(op2)) {
01556         Op3(get_xxxl);
01557         lpcreg = (byte *) op3;
01558       }
01559       else ADVANCE_PC(size_xxxX);
01560     } else {
01561       if (op1 != op2) {
01562         Op3(get_xxxl);
01563         lpcreg = (byte *) op3;
01564       }
01565       else ADVANCE_PC(size_xxxX);
01566     }
01567   XSB_End_Instr()
01568 
01569      /* TLS: so much work for such a little function! */
01570   XSB_Start_Instr(minreg,_minreg) /* PRR */
01571     Def3ops
01572     Op1(Register(get_xrx));
01573     Op3(get_xxr);
01574     ADVANCE_PC(size_xxx);
01575     op2 = *(op3);
01576     XSB_Deref(op1);
01577     XSB_Deref(op2);
01578     if (isinteger(op1)) {
01579          if (isinteger(op2)) {
01580               if (int_val(op2) < int_val(op1))  bld_copy(op3,op2); else bld_copy(op3,op1);
01581           }
01582          if (isboxedinteger(op2)) {
01583               if (boxedint_val(op2) < int_val(op1))  bld_copy(op3,op2); else bld_copy(op3,op1);
01584           }
01585          if (isofloat(op2)) {
01586               if (ofloat_val(op2) < int_val(op1))  bld_copy(op3,op2); else bld_copy(op3,op1);
01587           }
01588     } 
01589     else if (isboxedinteger(op1)) {
01590          if (isinteger(op2)) {
01591               if (int_val(op2) < boxedint_val(op1))  bld_copy(op3,op2); else bld_copy(op3,op1);
01592           }
01593          if (isboxedinteger(op2)) {
01594               if (boxedint_val(op2) < boxedint_val(op1))  bld_copy(op3,op2); else bld_copy(op3,op1);
01595           }
01596          if (isofloat(op2)) {
01597               if (ofloat_val(op2) < boxedint_val(op1))  bld_copy(op3,op2); else bld_copy(op3,op1);
01598           }
01599     } 
01600     else if (isofloat(op1)) {
01601          if (isinteger(op2)) {
01602               if (int_val(op2) < ofloat_val(op1))  bld_copy(op3,op2); else bld_copy(op3,op1);
01603           }
01604          if (isboxedinteger(op2)) {
01605               if (boxedint_val(op2) < ofloat_val(op1))  bld_copy(op3,op2); else bld_copy(op3,op1);
01606           }
01607          if (isofloat(op2)) {
01608               if (ofloat_val(op2) < ofloat_val(op1))  bld_copy(op3,op2); else bld_copy(op3,op1);
01609           }
01610     } 
01611    else { arithmetic_abort(CTXTc op2, "min", op1); }
01612   XSB_End_Instr() 
01613 
01614      /* TLS: so much work for such a little function! */
01615   XSB_Start_Instr(maxreg,_maxreg) /* PRR */
01616     Def3ops
01617     Op1(Register(get_xrx));
01618     Op3(get_xxr);
01619     ADVANCE_PC(size_xxx);
01620     op2 = *(op3);
01621     XSB_Deref(op1);
01622     XSB_Deref(op2);
01623     if (isinteger(op1)) {
01624          if (isinteger(op2)) {
01625               if (int_val(op2) > int_val(op1))  bld_copy(op3,op2); else bld_copy(op3,op1);
01626           }
01627          if (isboxedinteger(op2)) {
01628               if (boxedint_val(op2) > int_val(op1))  bld_copy(op3,op2); else bld_copy(op3,op1);
01629           }
01630          if (isofloat(op2)) {
01631               if (ofloat_val(op2) > int_val(op1))  bld_copy(op3,op2); else bld_copy(op3,op1);
01632           }
01633     } 
01634     else if (isboxedinteger(op1)) {
01635          if (isinteger(op2)) {
01636               if (int_val(op2) > boxedint_val(op1))  bld_copy(op3,op2); else bld_copy(op3,op1);
01637           }
01638          if (isboxedinteger(op2)) {
01639               if (boxedint_val(op2) > boxedint_val(op1))  bld_copy(op3,op2); else bld_copy(op3,op1);
01640           }
01641          if (isofloat(op2)) {
01642               if (ofloat_val(op2) > boxedint_val(op1))  bld_copy(op3,op2); else bld_copy(op3,op1);
01643           }
01644     } 
01645     else if (isofloat(op1)) {
01646          if (isinteger(op2)) {
01647               if (int_val(op2) > ofloat_val(op1))  bld_copy(op3,op2); else bld_copy(op3,op1);
01648           }
01649          if (isboxedinteger(op2)) {
01650               if (boxedint_val(op2) > ofloat_val(op1))  bld_copy(op3,op2); else bld_copy(op3,op1);
01651           }
01652          if (isofloat(op2)) {
01653               if (ofloat_val(op2) > ofloat_val(op1))  bld_copy(op3,op2); else bld_copy(op3,op1);
01654           }
01655     } 
01656    else { arithmetic_abort(CTXTc op2, "min", op1); }
01657   XSB_End_Instr() 
01658 
01659 
01660     /* dereferences op1 (as opposed to putpval) */
01661   XSB_Start_Instr(putdval,_putdval) /* PVR */
01662     Def2ops
01663     Op1(Variable(get_xvx));
01664     Op2(get_xxr);
01665     ADVANCE_PC(size_xxx);
01666     XSB_Deref(op1);
01667     bld_copy((CPtr)op2, op1);
01668   XSB_End_Instr()
01669 
01670   XSB_Start_Instr(putuval,_putuval) /* PVR */
01671     Def2ops
01672     Op1(Variable(get_xvx));
01673     Op2(get_xxr);
01674     ADVANCE_PC(size_xxx);
01675     XSB_Deref(op1);
01676     if (isnonvar(op1) || ((CPtr)(op1) < hreg) || ((CPtr)(op1) >= ereg)) {
01677       bld_copy((CPtr)op2, op1);
01678     } else {
01679       bld_ref((CPtr)op2, hreg);
01680       bind_ref((CPtr)(op1), hreg);
01681       new_heap_free(hreg);
01682     } 
01683   XSB_End_Instr()
01684 
01685   /*
01686    * Instruction `check_interrupt' is used before `new_answer_dealloc' to
01687    * handle the pending attv interrupts.  It is similar to `call' but the
01688    * second argument (S) is not used currently.
01689    */
01690   XSB_Start_Instr(check_interrupt,_check_interrupt)  /* PPA-S */
01691     Def1op
01692     
01693     Op1(get_xxxs);
01694     ADVANCE_PC(size_xxxX);
01695     if (int_val(cell(interrupt_reg)) > 0) {
01696       cpreg = lpcreg;
01697       bld_cs(reg + 2, hreg);    /* see subp.c: build_call() */
01698       new_heap_functor(hreg, true_psc);
01699       bld_copy(reg + 1, build_interrupt_chain(CTXT));
01700       lpcreg = get_ep((Psc) pflags[MYSIG_ATTV + INT_HANDLERS_FLAGS_START]);
01701     }
01702   XSB_End_Instr()
01703 
01704   XSB_Start_Instr(call,_call)  /* PPA-S */
01705     Def1op
01706     Psc psc;
01707 
01708     Op1(get_xxxs); /* the first arg is used later by alloc */
01709     ADVANCE_PC(size_xxxX);
01710     cpreg = lpcreg;
01711     psc = (Psc)op1;
01712 #ifdef CP_DEBUG
01713     pscreg = psc;
01714 #endif
01715 #ifdef MULTI_THREAD_LOGGING
01716     log_rec(CTXTc psc, "call");
01717 #endif
01718     call_sub(psc);
01719   XSB_End_Instr()
01720 
01721     /* If using the multi-threaded engine, call the function with the
01722        single argument, CTXT; otherwise call a parameterless
01723        funcion.  */
01724     XSB_Start_Instr(call_forn,_call_forn) {
01725     Def1op
01726     Op1(get_xxxl);
01727     ADVANCE_PC(size_xxxX);
01728 #ifdef MULTI_THREAD
01729     fp = op1;
01730     if (fp(CTXT))  /* call foreign function */
01731       lpcreg = cpreg;
01732     else Fail1;
01733 #else
01734     if (((PFI)op1)())  /* call foreign function */
01735       lpcreg = cpreg;
01736     else Fail1;
01737 #endif
01738   }
01739   XSB_End_Instr()
01740 
01741   XSB_Start_Instr(load_pred,_load_pred) /* PPP-S */
01742     Def1op
01743     Psc psc;
01744     
01745     Op1(get_xxxs);
01746     SYS_MUTEX_LOCK(MUTEX_LOAD_UNDEF);
01747     ADVANCE_PC(size_xxxX);
01748     psc = (Psc)op1;
01749     /* check env or type to give (better) error msgs? */
01750     switch (get_type(psc)) {
01751     case T_PRED:
01752     case T_DYNA:
01753     case T_FORN:
01754 #ifndef MULTI_THREAD
01755       xsb_abort("[EMULOOP] Trying to load an already loaded pred");
01756 #else
01757       /* predicate was loaded by another thread */
01758       /* fprintf(stderr,"Predicate loaded by other thread\n");
01759          fflush(stderr);
01760        */       
01761       SYS_MUTEX_UNLOCK(MUTEX_LOAD_UNDEF);
01762       lpcreg = get_ep(psc);             /* new ep of predicate */
01763       break;
01764 #endif
01765     default:
01766       /* xsb_dbgmsg("loading module %s for %s/%d\n",
01767          get_name(get_data(psc)),get_name(psc),get_arity(psc)); */
01768       bld_cs(reg+1, build_call(CTXTc psc));   /* put call-term in r1 */
01769       /* get psc of undef handler */
01770       psc = (Psc)pflags[MYSIG_UNDEF+INT_HANDLERS_FLAGS_START];
01771       bld_int(reg+2, MYSIG_UNDEF);      /* undef-pred code */
01772       lpcreg = get_ep(psc);             /* ep of undef handler */
01773       break;
01774     }
01775   XSB_End_Instr()
01776 
01777   XSB_Start_Instr(allocate_gc,_allocate_gc) /* PAA */
01778     Def3ops
01779     Op2(get_xax);
01780     Op3((CPtr) (Cell)get_xxa);
01781     ADVANCE_PC(size_xxx);
01782     if (efreg_on_top(ereg))
01783       op1 = (Cell)(efreg-1);
01784     else {
01785       if (ereg_on_top(ereg)) op1 = (Cell)(ereg - *(cpreg-2*sizeof(Cell)+3));
01786       else op1 = (Cell)(ebreg-1);
01787     }
01788     *(CPtr *)((CPtr) op1) = ereg;
01789     *((byte **) (CPtr)op1-1) = cpreg;
01790     ereg = (CPtr)op1; 
01791     {/* initialize all permanent variables not in the first chunk to unbound */
01792       int  i = ((Cell)op3) - op2;
01793       CPtr p = ((CPtr)op1) - op2;
01794       while (i--) {
01795         bld_free(p);
01796         p--;
01797       }
01798     }
01799   XSB_End_Instr()
01800 
01801 /* This is obsolete and is only kept for backwards compatibility for < 2.0 */
01802   XSB_Start_Instr(allocate,_allocate) /* PPP */
01803     Def1op
01804     ADVANCE_PC(size_xxx);
01805     if (efreg_on_top(ereg))
01806       op1 = (Cell)(efreg-1);
01807     else {
01808       if (ereg_on_top(ereg)) op1 = (Cell)(ereg - *(cpreg-2*sizeof(Cell)+3));
01809       else op1 = (Cell)(ebreg-1);
01810     }
01811     *(CPtr *)((CPtr) op1) = ereg;
01812     *((byte **) (CPtr)op1-1) = cpreg;
01813     ereg = (CPtr)op1; 
01814     { /* for old object files initialize pessimisticly but safely */
01815       int  i = 256;
01816       CPtr p = ((CPtr)op1)-2;
01817       while (i--) {
01818         bld_free(p);
01819         p--;
01820       }
01821     }
01822   XSB_End_Instr()
01823 
01824   XSB_Start_Instr(deallocate,_deallocate) /* PPP */
01825     ADVANCE_PC(size_xxx);
01826     cpreg = *((byte **)ereg-1);
01827     ereg = *(CPtr *)ereg;
01828   XSB_End_Instr()
01829 
01830   XSB_Start_Instr(proceed,_proceed)  /* PPP */
01831      proceed_sub;
01832   XSB_End_Instr()
01833 
01834     /* This is the WAM-execute.  Name was changed because of conflict
01835        with some system files for pthreads. */
01836   XSB_Start_Instr(xsb_execute,_xsb_execute) /* PPP-S */
01837     Def1op
01838     Psc psc;
01839 
01840     Op1(get_xxxs);
01841     ADVANCE_PC(size_xxxX);
01842     psc = (Psc)op1;
01843 #ifdef MULTI_THREAD_LOGGING
01844     log_rec(CTXTc psc, "exec");
01845 #endif
01846 #ifdef CP_DEBUG
01847     pscreg = psc;
01848 #endif
01849     call_sub(psc);
01850   XSB_End_Instr()
01851 
01852   XSB_Start_Instr(jump,_jump)   /* PPP-L */
01853     lpcreg = (byte *)get_xxxl;
01854   XSB_End_Instr()
01855 
01856   XSB_Start_Instr(jumpz,_jumpz)   /* PPR-L */
01857     Def1op
01858     Op1(Register(get_xxr));
01859     if (isinteger(op1)) {
01860         if (int_val(op1) == 0) {
01861             lpcreg = (byte *)get_xxxl;   
01862         } else {ADVANCE_PC(size_xxxX);}
01863     } else if (isofloat(op1)) {
01864         if (ofloat_val(op1) == 0.0) {
01865            lpcreg = (byte *)get_xxxl;
01866         } else {ADVANCE_PC(size_xxxX);}
01867     } else if (isboxedinteger(op1)){
01868         if (boxedint_val(op1) == 0){  
01869             lpcreg = (byte *)get_xxxl;
01870         } else {ADVANCE_PC(size_xxxX);}
01871     }
01872   XSB_End_Instr()
01873 
01874   XSB_Start_Instr(jumpnz,_jumpnz)    /* PPR-L */
01875     Def1op
01876     Op1(Register(get_xxr));
01877     if (isinteger(op1)) {
01878         if (int_val(op1) != 0) {
01879             lpcreg = (byte *)get_xxxl;   
01880         } else {ADVANCE_PC(size_xxxX);}
01881     } else if (isofloat(op1)) {
01882         if (ofloat_val(op1) != 0.0) {
01883            lpcreg = (byte *)get_xxxl;
01884         } else {ADVANCE_PC(size_xxxX);}
01885     } else if (isboxedinteger(op1)){
01886         if (boxedint_val(op1) != 0){  
01887             lpcreg = (byte *)get_xxxl;
01888         } else {ADVANCE_PC(size_xxxX);}
01889     }
01890   XSB_End_Instr()
01891 
01892   XSB_Start_Instr(jumplt,_jumplt)    /* PPR-L */
01893     Def1op
01894     Op1(Register(get_xxr));
01895     if (isinteger(op1)) {
01896       if (int_val(op1) < 0) lpcreg = (byte *)get_xxxl;
01897       else {ADVANCE_PC(size_xxxX);}
01898     } else if (isofloat(op1)) {
01899       if (ofloat_val(op1) < 0.0) lpcreg = (byte *)get_xxxl;
01900       else {ADVANCE_PC(size_xxxX);}
01901     } else if (isboxedinteger(op1)) {
01902       if (boxedint_val(op1) < 0) lpcreg = (byte *)get_xxxl;
01903       else {ADVANCE_PC(size_xxxX);}
01904     } 
01905   XSB_End_Instr() 
01906 
01907   XSB_Start_Instr(jumple,_jumple)    /* PPR-L */
01908     Def1op
01909     Op1(Register(get_xxr));
01910     if (isinteger(op1)) {
01911       if (int_val(op1) <= 0) lpcreg = (byte *)get_xxxl;
01912       else {ADVANCE_PC(size_xxxX);}
01913     } else if (isofloat(op1)) {
01914       if (ofloat_val(op1) <= 0.0) lpcreg = (byte *)get_xxxl;
01915       else {ADVANCE_PC(size_xxxX);}
01916     } else if (isboxedinteger(op1)) {
01917       if (boxedint_val(op1) <= 0) lpcreg = (byte *)get_xxxl;
01918       else {ADVANCE_PC(size_xxxX);}
01919     } 
01920   XSB_End_Instr() 
01921 
01922   XSB_Start_Instr(jumpgt,_jumpgt)    /* PPR-L */
01923     Def1op
01924     Op1(Register(get_xxr));
01925     if (isinteger(op1)) {
01926       if (int_val(op1) > 0) lpcreg = (byte *)get_xxxl;
01927       else {ADVANCE_PC(size_xxxX);}
01928     } else if (isofloat(op1)) {
01929       if (ofloat_val(op1) > 0.0) lpcreg = (byte *)get_xxxl;
01930       else {ADVANCE_PC(size_xxxX);}
01931     } else if (isboxedinteger(op1)) {
01932       if (boxedint_val(op1) > 0) lpcreg = (byte *)get_xxxl;
01933       else {ADVANCE_PC(size_xxxX);}
01934     } 
01935   XSB_End_Instr()
01936 
01937   XSB_Start_Instr(jumpge,_jumpge)    /* PPR-L */
01938     Def1op
01939     Op1(Register(get_xxr));
01940     if (isinteger(op1)) {
01941       if (int_val(op1) >= 0) lpcreg = (byte *)get_xxxl;
01942       else {ADVANCE_PC(size_xxxX);}
01943     } else if (isofloat(op1)) {
01944       if (ofloat_val(op1) >= 0.0) lpcreg = (byte *)get_xxxl;
01945       else {ADVANCE_PC(size_xxxX);}
01946     } else if (isboxedinteger(op1)) {
01947       if (boxedint_val(op1) >= 0) lpcreg = (byte *)get_xxxl;
01948       else {ADVANCE_PC(size_xxxX);}
01949     } 
01950   XSB_End_Instr() 
01951 
01952   XSB_Start_Instr(fail,_fail)    /* PPP */
01953     Fail1; 
01954   XSB_End_Instr()
01955 
01956   XSB_Start_Instr(dynfail,_dynfail)    /* PPP */
01957 #ifdef MULTI_THREAD
01958     if (i_have_dyn_mutex) {
01959       SYS_MUTEX_UNLOCK(MUTEX_DYNAMIC);
01960       i_have_dyn_mutex = 0;
01961     }
01962 #endif
01963     Fail1; 
01964   XSB_End_Instr()
01965 
01966   XSB_Start_Instr(noop,_noop)  /* PPA */
01967     Def1op
01968     Op1(get_xxa);
01969     ADVANCE_PC(size_xxx);
01970     lpcreg += (int)op1;
01971     lpcreg += (int)op1;
01972   XSB_End_Instr()
01973 
01974   XSB_Start_Instr(dynnoop,_dynnoop)  /* PPA */
01975     Def1op
01976     Op1(get_xxa);
01977     ADVANCE_PC(size_xxx);
01978     lpcreg += (int)op1;
01979     lpcreg += (int)op1;
01980 #ifdef MULTI_THREAD
01981     if (i_have_dyn_mutex) {
01982       SYS_MUTEX_UNLOCK(MUTEX_DYNAMIC);
01983       i_have_dyn_mutex = 0;
01984     }
01985 #endif
01986   XSB_End_Instr()
01987 
01988   XSB_Start_Instr(halt,_halt)  /* PPP */
01989     ADVANCE_PC(size_xxx);
01990     pcreg = lpcreg; 
01991     inst_begin_gl = lpcreg;  /* hack for the moment to make this a ``creturn'' */
01992     return(0);  /* not "goto contcase"! */
01993   XSB_End_Instr()
01994 
01995   XSB_Start_Instr(builtin,_builtin)
01996     Def1op
01997     Op1(get_xxa);
01998     ADVANCE_PC(size_xxx);
01999     pcreg=lpcreg; 
02000     if (builtin_call(CTXTc (byte)(op1))) {lpcreg=pcreg;}
02001     else Fail1;
02002   XSB_End_Instr()
02003 
02004 #define jump_cond_fail(Condition) \
02005       if (Condition) {ADVANCE_PC(size_xxxX);} else lpcreg = (byte *)get_xxxl
02006 
02007   XSB_Start_Instr(jumpcof,_jumpcof)
02008     Def2ops
02009     Op1(get_xax);
02010     Op2(get_xxr);
02011     XSB_Deref(op2);
02012     switch (op1) {
02013     case ATOM_TEST:
02014       jump_cond_fail(isatom(op2));
02015       break;
02016     case INTEGER_TEST:
02017       jump_cond_fail(isinteger(op2) || isboxedinteger(op2));
02018       break;
02019     case REAL_TEST:
02020       jump_cond_fail(isofloat(op2));
02021       break;
02022     case NUMBER_TEST:
02023       jump_cond_fail(isnumber(op2) || isboxedinteger(op2) || isboxedfloat(op2));
02024       break;
02025     case ATOMIC_TEST:
02026       jump_cond_fail(isatomic(op2) || isboxedinteger(op2) || isboxedfloat(op2));
02027       break;
02028     case COMPOUND_TEST:
02029       jump_cond_fail(((isconstr(op2) && get_arity(get_str_psc(op2))) ||
02030                       (islist(op2))) && !isboxedfloat(op2) && !isboxedinteger(op2));
02031       break;
02032     case CALLABLE_TEST:
02033       jump_cond_fail((isconstr(op2) && !isboxed(op2)) || isstring(op2) || islist(op2));
02034       break;
02035     case IS_LIST_TEST:
02036       jump_cond_fail(is_proper_list(op2));
02037       break;
02038     case IS_MOST_GENERAL_TERM_TEST:
02039       jump_cond_fail(is_most_general_term(op2));
02040       break;
02041     case IS_ATTV_TEST:
02042       jump_cond_fail(isattv(op2));
02043       break;
02044     case VAR_TEST:
02045       jump_cond_fail(isref(op2) || isattv(op2));
02046       break;
02047     case NONVAR_TEST:
02048       jump_cond_fail(isnonvar(op2) && !isattv(op2));
02049       break;
02050     default: 
02051       xsb_error("Undefined jumpcof condition");
02052       Fail1;
02053     }
02054   XSB_End_Instr()
02055 
02056   XSB_Start_Instr(unifunc,_unifunc)   /* PAR */
02057     Def2ops
02058     Op1(get_xax);
02059     Op2(get_xxr);
02060     ADVANCE_PC(size_xxx);
02061     if (unifunc_call(CTXTc (int)(op1), (CPtr)op2) == 0) {
02062       xsb_error("Error in unary function call");
02063       Fail1;
02064     }
02065   XSB_End_Instr()
02066 
02067     /* Calls internal code -- does not go through psc record and omits
02068        interrupt checks.  Not sure if profile_interrupt should be here...*/
02069   XSB_Start_Instr(calld,_calld)   /* PPA-L */
02070     ADVANCE_PC(size_xxx); /* this is ok */
02071     cpreg = lpcreg+sizeof(Cell); 
02072     /*check_glstack_overflow(MAX_ARITY, lpcreg,OVERFLOW_MARGIN);  try eliminating?? */
02073     handle_xsb_profile_interrupt;
02074     lpcreg = *(pb *)lpcreg;
02075   XSB_End_Instr()
02076 
02077   XSB_Start_Instr(logshiftr,_logshiftr)  /* PRR */
02078     Def3ops
02079     Op1(Register(get_xrx));
02080     Op3(get_xxr);
02081     ADVANCE_PC(size_xxx);
02082     op2 = *(op3);
02083     XSB_Deref(op1); 
02084     XSB_Deref(op2);
02085     if (isinteger(op1)) {
02086       if (isinteger(op2)) {
02087         Integer temp = int_val(op2) >> int_val(op1);
02088         bld_oint(op3, temp); 
02089       }
02090       else if (isboxedinteger(op2)) {
02091         Integer temp = boxedint_val(op2) >> int_val(op1);
02092         bld_oint(op3, temp); 
02093       }
02094       else {arithmetic_abort(CTXTc op2, "'>>'", op1);}
02095     }
02096     else if (isboxedinteger(op1)) {
02097       if (isinteger(op2)) {
02098         Integer temp = int_val(op2) >> boxedint_val(op1);
02099         bld_oint(op3, temp); 
02100       }
02101       else if (isboxedinteger(op2)) {
02102         Integer temp = boxedint_val(op2) >> boxedint_val(op1);
02103         bld_oint(op3, temp); 
02104       }
02105       else {arithmetic_abort(CTXTc op2, "'>>'", op1);}
02106     }
02107     else {arithmetic_abort(CTXTc op2, "'>>'", op1);}
02108   XSB_End_Instr() 
02109 
02110   XSB_Start_Instr(logshiftl,_logshiftl)   /* PRR */
02111     Def3ops
02112     Op1(Register(get_xrx));
02113     Op3(get_xxr);
02114     ADVANCE_PC(size_xxx);
02115     op2 = *(op3);
02116     XSB_Deref(op1); 
02117     XSB_Deref(op2);
02118     if (isinteger(op1)) {
02119       if (isinteger(op2)) {
02120         Integer temp = int_val(op2) << int_val(op1);
02121         bld_oint(op3, temp); 
02122       }
02123       else if (isboxedinteger(op2)) {
02124         Integer temp = boxedint_val(op2) << int_val(op1);
02125         bld_oint(op3, temp); 
02126       }
02127       else {arithmetic_abort(CTXTc op2, "'<<'", op1);}
02128     }
02129     else if (isboxedinteger(op1)) {
02130       if (isinteger(op2)) {
02131         Integer temp = int_val(op2) << boxedint_val(op1);
02132         bld_oint(op3, temp); 
02133       }
02134       else if (isboxedinteger(op2)) {
02135         Integer temp = boxedint_val(op2) << boxedint_val(op1);
02136         bld_oint(op3, temp); 
02137       }
02138       else {arithmetic_abort(CTXTc op2, "'<<'", op1);}
02139     }
02140     else {arithmetic_abort(CTXTc op2, "'<<'", op1);}
02141   XSB_End_Instr() 
02142 
02143   XSB_Start_Instr(or,_or)   /* PRR */
02144     Def3ops
02145     Op1(Register(get_xrx));
02146     Op3(get_xxr);
02147     ADVANCE_PC(size_xxx);
02148     op2 = *(op3);
02149     XSB_Deref(op1); 
02150     XSB_Deref(op2);
02151     if (isinteger(op1)) {
02152       if (isinteger(op2)) {
02153         Integer temp = (int_val(op2)) | (int_val(op1));
02154         bld_oint(op3, temp); 
02155       }
02156       else if (isboxedinteger(op2)) {
02157         Integer temp = (boxedint_val(op2)) | (int_val(op1));
02158         bld_oint(op3, temp);
02159       }
02160       else {arithmetic_abort(CTXTc op2, "'\\/'", op1);}
02161     }
02162     else if (isboxedinteger(op1)) {
02163       if (isinteger(op2)) {
02164         Integer temp = (int_val(op2)) | (boxedint_val(op1));
02165         bld_oint(op3, temp); 
02166       }
02167       else if (isboxedinteger(op2)) {
02168         Integer temp = (boxedint_val(op2)) | (boxedint_val(op1));
02169         bld_oint(op3, temp); 
02170       }
02171       else {arithmetic_abort(CTXTc op2, "'\\/'", op1);}
02172     }
02173     else {arithmetic_abort(CTXTc op2, "'\\/'", op1);}
02178   XSB_End_Instr() 
02179 
02180   XSB_Start_Instr(and,_and)   /* PRR */
02181     Def3ops
02182     Op1(Register(get_xrx));
02183     Op3(get_xxr);
02184     ADVANCE_PC(size_xxx);
02185     op2 = *(op3);
02186     XSB_Deref(op1); 
02187     XSB_Deref(op2);
02188     if (isinteger(op1)) {
02189       if (isinteger(op2)) {
02190         Integer temp = (int_val(op2)) & (int_val(op1));
02191         bld_oint(op3, temp); 
02192       }
02193       else if (isboxedinteger(op2)) {
02194         Integer temp = (boxedint_val(op2)) & (int_val(op1));
02195         bld_oint(op3, temp);
02196       }
02197       else {arithmetic_abort(CTXTc op2, "'/\\'", op1);}
02198     }
02199     else if (isboxedinteger(op1)) {
02200       if (isinteger(op2)) {
02201         Integer temp = (int_val(op2)) & (boxedint_val(op1));
02202         bld_oint(op3, temp); 
02203       }
02204       else if (isboxedinteger(op2)) {
02205         Integer temp = (boxedint_val(op2)) & (boxedint_val(op1));
02206         bld_oint(op3, temp); 
02207       }
02208       else {arithmetic_abort(CTXTc op2, "'/\\'", op1);}
02209     }
02210     else {arithmetic_abort(CTXTc op2, "'/\\'", op1);}
02211 
02216   XSB_End_Instr() 
02217 
02218   XSB_Start_Instr(negate,_negate)   /* PPR */
02219     DefOps13
02220     Op3(get_xxr);
02221     ADVANCE_PC(size_xxx);
02222     op1 = *(op3);
02223     XSB_Deref(op1);
02224     if (isinteger(op1)) { bld_oint(op3, ~(int_val(op1))); }
02225     else if (isboxedinteger(op1)) { 
02226       Integer temp = ~(boxedint_val(op1));
02227       bld_oint(op3, temp); 
02228     }
02229     else { arithmetic_abort1(CTXTc "'\\'", op1); }
02230   XSB_End_Instr() 
02231 
02232 #ifndef JUMPTABLE_EMULOOP
02233   default: {
02234     char message[80];
02235     sprintf(message, "Illegal opcode hex %x", *lpcreg); 
02236     xsb_exit(message);
02237   }
02238 } /* end of switch */
02239 #else
02240   _no_inst:
02241     {
02242       char message[80];
02243       sprintf(message, "Illegal opcode hex %x", *lpcreg);
02244       xsb_exit(message);
02245     }
02246 #endif
02247 
02248 return 0;
02249 
02250 } /* end of emuloop() */
02251 
02252 /*======================================================================*/
02253 /*======================================================================*/
02254 
02255 DllExport int call_conv xsb(CTXTdeclc int flag, int argc, char *argv[])
02256 { 
02257    char *startup_file;
02258    FILE *fd;
02259    unsigned int magic_num;
02260    static double realtime;      /* To retain its value across invocations */
02261 
02262    extern void dis(xsbBool);
02263    extern char *init_para(CTXTdeclc int, char **);
02264    extern void perform_IO_Redirect(CTXTdeclc int, char **);
02265    extern void init_machine(CTXTdeclc int, int, int, int), init_symbols(void);
02266 #ifdef FOREIGN
02267 #ifndef FOREIGN_ELF
02268 #ifndef FOREIGN_WIN32
02269    extern char tfile[];
02270 #endif
02271 #endif
02272 #endif
02273 
02274    if (flag == 0) {  /* initialize xsb */
02275      /* Set the name of the executable to the real name.
02276         The name of the executable could have been set in cinterf.c:xsb_init
02277         if XSB is called from C. In this case, we don't want `executable'
02278         to be overwritten, so we check if it is initialized. */
02279 
02280         perform_IO_Redirect(CTXTc argc, argv);
02281 
02282 #ifdef SIMPLESCALAR
02283      strcpy(executable_path_gl,argv[0]);
02284 #else
02285      if (executable_path_gl[0] == '\0')
02286        xsb_executable_full_path(argv[0]);
02287 #endif
02288 
02289      /* set install_dir, xsb_config_file and user_home */
02290      set_install_dir();
02291      set_config_file();
02292      set_user_home();
02293 
02294      realtime = real_time();
02295      setbuf(stdout, NULL);
02296      startup_file = init_para(CTXTc argc, argv);        /* init parameters */
02297 
02298      init_machine(CTXTc (int)NULL,(int)NULL,(int)NULL,(int)NULL);       /* init space, regs, stacks */
02299      init_inst_table();         /* init table of instruction types */
02300      init_symbols();            /* preset a few symbols in PSC table */
02301      init_interrupt();          /* catch ^C interrupt signal */
02302 
02303      /* "b" does nothing in UNIX, denotes binary file in Windows -- 
02304         needed in Windows for reading byte-code files */
02305      fd = fopen(startup_file, "rb");
02306 
02307      if (!fd) {
02308        char message[256];
02309        sprintf(message, "The startup file, %s, could not be found!",
02310                startup_file);
02311        xsb_exit(message);
02312      }
02313      magic_num = read_magic(fd);
02314      fclose(fd);
02315      if (magic_num == 0x11121307 || magic_num == 0x11121305)
02316        inst_begin_gl = loader(CTXTc startup_file,0);
02317      else
02318        xsb_exit("Incorrect startup file format");
02319 
02320      if (!inst_begin_gl)
02321        xsb_exit("Error in loading startup file");
02322 
02323      if (xsb_mode == DISASSEMBLE) {
02324        dis(1);
02325        exit(0);
02326      }
02327 
02328      /* do it after initialization, so that typing 
02329         xsb -v or xsb -h won't create .xsb directory */
02330      set_xsbinfo_dir();
02331 
02332      return(0);
02333 
02334    } else if (flag == 1) {  /* continue execution */
02335 
02336      return(emuloop(CTXTc inst_begin_gl));
02337 
02338    } else if (flag == 2) {  /* shutdown xsb */
02339 
02340 #ifdef FOREIGN
02341 #ifndef FOREIGN_ELF
02342 #ifndef FOREIGN_WIN32
02343      if (fopen(tfile, "r")) unlink(tfile);
02344 #endif
02345 #endif
02346 #endif
02347 
02348      if (xsb_mode != C_CALLING_XSB) {
02349        realtime = real_time() - realtime;
02350        fprintf(stdmsg, "\nEnd XSB (cputime %.2f secs, elapsetime ",
02351                cpu_time());
02352        if (realtime < 600.0)
02353          fprintf(stdmsg, "%.2f secs)\n", realtime);
02354        else
02355          fprintf(stdmsg, "%.2f mins)\n", realtime/60.0);
02356      }
02357      return(0);
02358    }
02359    return(1);
02360 }  /* end of xsb() */
02361 
02362 /*======================================================================*/

Generated on Wed Jul 26 13:30:40 2006 for XSB by  doxygen 1.4.5