cell_xsb.h

00001 /* File:      cell_xsb.h
00002 ** Author(s): David S. Warren, Jiyang Xu, Terrance Swift
00003 ** Contact:   xsb-contact@cs.sunysb.edu
00004 ** 
00005 ** Copyright (C) The Research Foundation of SUNY, 1993-19989
00006 ** 
00007 ** XSB is free software; you can redistribute it and/or modify it under the
00008 ** terms of the GNU Library General Public License as published by the Free
00009 ** Software Foundation; either version 2 of the License, or (at your option)
00010 ** any later version.
00011 ** 
00012 ** XSB is distributed in the hope that it will be useful, but WITHOUT ANY
00013 ** WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00014 ** FOR A PARTICULAR PURPOSE.  See the GNU Library General Public License for
00015 ** more details.
00016 ** 
00017 ** You should have received a copy of the GNU Library General Public License
00018 ** along with XSB; if not, write to the Free Software Foundation,
00019 ** Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00020 **
00021 ** $Id: cell_xsb.h,v 1.27 2005/12/17 02:46:32 dwarren Exp $
00022 ** 
00023 */
00024 
00025 #ifndef __CELL_XSB_H__
00026 #define __CELL_XSB_H__
00027 
00028 #ifndef CONFIG_INCLUDED
00029 #error "File xsb_config.h must be included before this file"
00030 #endif
00031 
00032 /*======================================================================*/
00033 /* CELL: an element in the local stack or global stack (heap).          */
00034 /*                                                                      */
00035 /* Corresponds to the basic word type of the physical machine.          */
00036 /* This module also defines the basic INTEGER and REAL types to use     */
00037 /* by the Prolog interpreter                                            */
00038 /*                                                                      */
00039 /* Interface routines                                                   */
00040 /*      They are put in the different files indicated below, according  */
00041 /*      to the tagging scheme you used.                                 */
00042 /* The functions (macros, indeed) include:                              */
00043 /*      cell_tag(cell):         give any cell, return its tag           */
00044 /*      isnonvar(dcell):        check if the cell is a ref or a var.    */
00045 /*                              (an index in VARASINDEX)                */
00046 /*                              when used with derefed cell, check if   */
00047 /*                              the cell is instanciated                */
00048 /*      int_val(dcell):         assume derefed integer cell, return its */
00049 /*                              value in machine format                 */
00050 /*      clref_val(dcell):       assume derefed cs or list cell, return  */
00051 /*                              a CPtr to the address it points to.     */
00052 /*      cs_val(dcell):          assume derefed cs cell, return Pair     */
00053 /*      bld_int(addr, val):     build a new integer cell                */
00054 /*      bld_float(addr, val):   build a new float cell                  */
00055 /*      bld_ref(addr, val):     build a new reference cell              */
00056 /*      bld_cs(addr, str):      build a new cs cell                     */
00057 /*      bld_string(addr, str):  build a new string cell                 */
00058 /*      bld_list(addr, list):   build a new list cell                   */
00059 /*      bld_functor(addr, psc): build a functor cell for a new structure*/
00060 /*      bld_free(addr):         build a new free variable               */
00061 /*      bld_copy(dest, source): build a copy of the given cell.         */
00062 /*                      if the source is a free var, the copy is indeed */
00063 /*                      a ref cell. Need special checking when free var */
00064 /*                      is not a pointer to itself but a special tag.   */
00065 /*      bld_copy0(dest, src):   the same as bld_copy except assume      */
00066 /*                    non-var, or where semantics is to resume/set.     */
00067 /*                    (in set CP and resume CP)                         */
00068 /*                    For variable as selfpointer, no differnce.        */
00069 /*      bld_boxedint            builds an integer with no precision     */
00070 /*                      loss on the heap (hreg)                         */
00071 /*      bld_boxedfloat          builds a double float with no precision */
00072 /*                      loss on the heap (hreg)                         */
00073 /*======================================================================*/
00074 #include "xsb_config.h"
00075 #include "cell_def_xsb.h"
00076 #include "basictypes.h"
00077 #include "box_defines.h"
00078 
00079 /* ==== types of cells =================================================*/
00080 
00081 #include "celltags_xsb.h"
00082 
00083 /*======================================================================*/
00084 /* CELL: an element in the local stack or global stack (heap).          */
00085 /*======================================================================*/
00086 
00087 #define cell(cptr) *(cptr)
00088 #define follow(cell) (*(CPtr)(cell))
00089 
00090 /*======================================================================*/
00091 /* floating point conversions                                           */
00092 /*    The below 3 methods are to be used when floats and Cells are the  */
00093 /*    same size, in bytes, to convert between the two.                  */
00094 /*======================================================================*/
00095 
00096 /* lose some precision in conversions from 32 bit formats */
00097 #ifdef BITS64
00098 #define FLOAT_MASK 0xfffffffffffffff8
00099 #else
00100 #define FLOAT_MASK 0xfffffff8
00101 #endif
00102 extern inline float getfloatval(Cell);
00103 extern inline Cell makefloat(float);
00104 extern inline int sign(Float);
00105 
00106 #define isref(cell)  (!((word)(cell)&0x3))
00107 #define isnonvar(cell) ((word)(cell)&0x3)               /* dcell -> xsbBool */
00108 
00109 #define cell_tag(cell) ((word)(cell)&0x7)
00110 
00111 /*======================================================================*/
00112 /*======================================================================*/
00113 
00114 #if (defined(HP700) || defined(IBM) || defined(MIPS_BASED) || defined(SOLARIS_x86))
00115 #define GENERAL_TAGGING
00116 #endif
00117 
00118 #if defined(GENERAL_TAGGING)
00119 
00120 /* General Tagging for systems that return addresses in higher half
00121    (2-4GB) of virtual memory.  This builds a table for the high-order
00122    nibble of addresses and maps them to 0-7, to free up the 1st bit to
00123    allow it to be stolen. */
00124 
00125 extern unsigned long enc[], dec[];
00126 
00127 #define enc_int(val)  (((Integer)(val) << 3))
00128 #define dec_int(val)  ((Integer)(val) >> 3)
00129 
00130 #define enc_addr(addr) ((Cell)((enc[((unsigned long)(addr))>>28] | ((unsigned long)(addr) & 0x0ffffffc)) << 1))
00131 #define dec_addr(dcell) ((Cell)(dec[(unsigned long)(dcell)>>29] | (((unsigned long)(dcell) >> 1) & 0x0ffffffc)))
00132 
00133 #elif BITS64
00134 /* 64 bit, take bits 0, 61-63 */
00135 /* Encoded integers/addresses */
00136 #define enc_int(val) ((Integer)(val) << 3)
00137 #define dec_int(dcell) ((Integer)(dcell) >> 3)
00138 /* Fewer bit representation of pointers */
00139 #define enc_addr(addr) ((Cell)(addr))
00140 #define dec_addr(dcell) (((Cell)(dcell)) & 0xfffffffffffffff8)
00141 
00142 #else
00143 /* take bits 0-1, 31 */
00144 /* Steals bit 31 (high order).  If system allocates memory (malloc) in
00145    the upper 2 GB of virtual memory, then use GENERAL_TAGGING. */
00146 
00147 #define enc_int(val)  (((Integer)(val) << 3))
00148 #define dec_int(val)  ((Integer)(val) >> 3)
00149 
00150 #define enc_addr(addr) ((Cell)(addr) << 1)
00151 #define dec_addr(dcell) (((Cell)(dcell) >> 1) & 0x7ffffffc)
00152 
00153 #endif
00154 
00155 /*======================================================================*/
00156 
00157 /* integer manipulation */
00158 #define int_val(dcell) (Integer)dec_int(dcell)
00159 #define makeint(val) (Cell)((enc_int(val)) | XSB_INT)
00160 
00161 /* string manipulation */
00162 #define string_val(dcell) (char *)dec_addr(dcell)
00163 #define makestring(str) (Cell)(enc_addr(str) | XSB_STRING)
00164 
00165 /* special-case strings [] */
00166 #define makenil         makestring(nil_string)
00167 
00168 /* pointer manipulation */
00169 #define cs_val(dcell) (Pair)dec_addr(dcell)
00170 #define makecs(str) (Cell)(enc_addr(str) | XSB_STRUCT)
00171 #define clref_val(dcell) (CPtr)dec_addr(dcell)
00172 #define makelist(list) (Cell)(enc_addr(list) | XSB_LIST)
00173 #define makeattv(attv) (Cell)(enc_addr(attv) | XSB_ATTV)
00174 #define trievar_val(dcell) (Integer)dec_int(dcell)
00175 #define maketrievar(val) (Cell)(enc_int(val) | XSB_TrieVar)
00176 
00178 #define get_str_psc(dcell) (*((Psc *)dec_addr(dcell)))
00179 
00180 #define addr_val(dcell) string_val(dcell)
00181 #define makeaddr(val) makestring(val)
00182 
00183 /* #define addr_val(dcell) int_val(dcell) */
00184 /* #define makeaddr(val) makeint(val) */
00185 
00186 /* common representations */
00187 #define vptr(dcell) (CPtr)(dcell)
00188 #define float_val(dcell) getfloatval(dcell)
00189 #define ref_val(dcell) (CPtr)(dcell)
00190 
00191 #define bld_nil(addr) cell(addr) = makenil
00192 #define bld_string(addr, str) cell(addr) = makestring(str)
00193 #define bld_int_tagged(addr, val) cell(addr) = val
00194 #define bld_int(addr, val) cell(addr) = makeint(val)
00195 #define bld_float_tagged(addr, val) cell(addr) = val
00196 //Note: See section 'Miscellaneous' for implementation of bld_boxedfloat & bld_boxedint.
00197 #define bld_float(addr, val) cell(addr) = makefloat(val)
00198 #define bld_ref(addr, val) cell(addr) = (Cell)(val)
00199 #define bld_cs(addr, str) cell(addr) = makecs(str)
00200 #define bld_list(addr, list) cell(addr) = makelist(list)
00201 #define bld_attv(addr, attv) cell(addr) = makeattv(attv)
00202 #define bld_functor(addr, psc) cell(addr) = (word)psc
00203 #define bld_copy0(addr, val) cell(addr) = val
00204 #define bld_copy(addr, val) cell(addr) = val
00205 /* tls -- this bld_copy wont work for VARASINDEX */
00206 #define bld_free(addr) cell(addr) = (Cell)(addr) /* CPtr => XSB_FREE cell */
00207 
00208 #define isinteger(dcell) (cell_tag(dcell)==XSB_INT)     /* dcell -> xsbBool */
00209 //Note: See section 'Miscellaneous' for implementation of isboxedfloat.
00210 #define isfloat(dcell) (cell_tag(dcell)==XSB_FLOAT)     /* dcell -> xsbBool */
00211 #define isconstr(dcell) (cell_tag(dcell)==XSB_STRUCT)   /* dcell -> xsbBool */
00212 #define islist(dcell) (cell_tag(dcell)==XSB_LIST)       /* dcell -> xsbBool */
00213 #define isattv(dcell) (cell_tag(dcell)==XSB_ATTV)       /* dcell -> xsbBool */
00214 
00215 #define isstring(dcell) (cell_tag(dcell)==XSB_STRING)
00216 #define numequal(num1, num2) num1 == num2
00217 
00218 #define isnumber(dcell) ((isinteger(dcell)) || (isfloat(dcell)))
00219 #define isconstant(dcell)  ( isstring(dcell) || isnumber(dcell) )
00220 #define isatom(dcell)   ((isstring(dcell)) || \
00221                          (isconstr(dcell) && get_arity(get_str_psc(dcell))==0))
00222 #define isatomic(dcell) ((isstring(dcell)) || (isnumber(dcell)) || \
00223                          (isconstr(dcell) && get_arity(get_str_psc(dcell))==0))
00224 
00225 #define isnil(dcell) (isstring(dcell) && (char *)string_val(dcell) == nil_string)
00226 #define isboxed(term) (isconstr(term) && get_str_psc(term) == box_psc )
00227 #define box_has_id(dcell, box_identifier) (int_val(cell(clref_val(dcell)+1))>>16 == box_identifier)
00228 
00229 /*======================================================================*/
00230 /* Miscellaneous                                                        */
00231 /*======================================================================*/
00232 
00233 #define MAX_ARITY       255
00234 #define CELL_DEFS_INCLUDED
00235 
00236 #define arity_integer(dcell) \
00237    (isinteger(dcell) && int_val(dcell) >= 0 \
00238           && int_val(dcell) <= MAX_ARITY)
00239             
00240 #define isboxedinteger(dcell) (isboxed(dcell) && box_has_id(dcell, ID_BOXED_INT))
00241 
00242 #ifndef FAST_FLOATS
00243 #define isboxedfloat(dcell) (isboxed(dcell) && box_has_id(dcell, ID_BOXED_FLOAT))
00244 
00245 #else
00246 //If FAST_FLOATS is defined, there should be no boxed floats (only Cell floats). 
00247 //  isboxedfloat is therefore expanded to FALSE (0), in hopes that the optimizer will remove.
00248 //  any code exclusively dependent on it.
00249 
00250 #define isboxedfloat(dcell) 0
00251 #endif
00252 
00253 #define boxedint_val(dcell) \
00254        ((Integer)((((unsigned long)int_val(cell(clref_val(dcell)+2))<<24)   \
00255                   | int_val(cell(clref_val(dcell)+3))))) 
00256        
00257 #ifndef FAST_FLOATS
00258 //make_float_from_ints, defined in emuloop.c, is used by EXTRACT_FLOAT_FROM_16_24_24 to combine
00259 //    two UInteger values into a Float value that is twice the size the UInteger, in bytes. 
00260 
00261 // It assumes that the double type is twice the size of the integer type on the target machine.
00262 //    It is an inline function that joins the two ints in a struct, unions this struct with a 
00263 //    Float variable, and returns this Float.
00264 extern inline Float make_float_from_ints(UInteger, UInteger);
00265 
00266 // EXTRACT_FLOAT_FROM_16_24_24 works by first merging the three ints together into 
00267 //    two Integers (assuming high-order 16 bits are in the first, middle-24 bits in the 
00268 //    second, and low-24 bits in the third).
00269 #define EXTRACT_FLOAT_FROM_16_24_24(highInt, middleInt, lowInt)        \
00270       (make_float_from_ints(  (((((UInteger) highInt) & LOW_16_BITS_MASK) <<16) | (((UInteger) middleInt) >> 8)), \
00271                               ((((UInteger) middleInt)<<24) | (UInteger)lowInt)) )
00272 #define boxedfloat_val(dcell)                           \
00273     (                                                   \
00274      (Float)(    EXTRACT_FLOAT_FROM_16_24_24(           \
00275                    (int_val(cell(clref_val(dcell)+1))), \
00276                    (int_val(cell(clref_val(dcell)+2))), \
00277                    (int_val(cell(clref_val(dcell)+3)))  \
00278                  )                                      \
00279             )                                           \
00280     )
00281 #else 
00282 //if FAST_FLOATS is defined, then boxedfloat_val should never get called. To satisfy the 
00283 //  compiler, boxedfloat_val has been turned into an alias for float_val, since everything that 
00284 //  would have been a boxedfloat should now be a float.
00285 #define boxedfloat_val(dcell) float_val(dcell)
00286 #endif
00287 
00288 #define oint_val(dcell)      \
00289     (isinteger(dcell)        \
00290      ?int_val(dcell)         \
00291      :(isboxedinteger(dcell) \
00292        ?boxedint_val(dcell)  \
00293        :(Integer)0x80000000))
00294 
00295 
00296 #ifndef FAST_FLOATS
00297 /* below returns the error-code 12345.6789 if the macro is called on a non-float related cell. 
00298    One should be careful with this (possibly change?), since it ordinarily can return any double
00299    in the full floating point domain, including 12345.6789.*/
00300 #define ofloat_val(dcell)    \
00301     (isfloat(dcell)          \
00302      ?float_val(dcell)         \
00303      :(isboxedfloat(dcell) \
00304        ?boxedfloat_val(dcell)  \
00305        :12345.6789))
00306 #else
00307 //when FAST_FLOATS is defined, ofloat_val exists for the same reason that boxedfloat_val 
00308 //  does in the FAST_FLOATS defined case. See boxedfloat_val for comments.
00309 #define ofloat_val(dcell) float_val(dcell)
00310 #endif
00311 
00312 
00313 #ifndef FAST_FLOATS
00314 #define isofloat(val)  ( (isboxedfloat(val)) || (isfloat(val)) )
00315 #else
00316 #define isofloat(val) isfloat(val)
00317 #endif
00318 
00319 #define int_overflow(value)                 \
00320    (int_val(makeint(value)) != (value))
00321 
00322 #define bld_boxedint(addr, value)                                                   \
00323      {Cell binttemp = makecs(hreg);                                     \
00324       new_heap_functor(hreg,box_psc);                                           \
00325       bld_int(hreg,((ID_BOXED_INT << BOX_ID_OFFSET ) )); hreg++;        \
00326       bld_int(hreg,INT_LOW_24_BITS(value)); hreg++;                     \
00327       bld_int(hreg,((value) & LOW_24_BITS_MASK)); hreg++;                   \
00328       cell(addr) = binttemp;}
00329 
00330       
00331 #define bld_oint(addr, value)                                       \
00332     if (int_overflow(((Integer)value))) {                       \
00333       bld_boxedint(addr, ((Integer)value));                     \
00334     } else {bld_int(addr,((Integer)value));}
00335 
00336     
00337 //if FAST_FLOATS is defined, then bld_boxedfloat becomes an alias for bld_float. If it is
00338 //defined, bld_boxedfloat is a function declaired here and implemented in emuloop.c.
00339 #ifndef FAST_FLOATS
00340 
00341 #include "context.h"
00342 //Note: anything that includes cell_xsb.h in the multithreaded environment implicitly includes
00343 //context.h as well, since bld_boxedfloat references hreg.
00344 extern inline void bld_boxedfloat(CTXTdeclc CPtr, Float);
00345 #endif /*FAST_FLOATS*/
00346    
00347 #endif /* __CELL_XSB_H__ */

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