Main Page | Namespace List | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals | Related Pages

bytegames.c

Go to the documentation of this file.
00001 /*!
00002  * @file bytegames.c
00003  *
00004  * @brief Perform byte swapping, word swapping, byte-aligned accesses,
00005  * non-aligned multi-byte items, etc.
00006  *
00007  * General utilities for playing shell games with real machine bytes
00008  * for both the real machine and the Java virtual machine.
00009  *
00010  * Some machine architectures use little-endian versus big-endian byte
00011  * ordering, some architectures do not natively support 2-byte or
00012  * 4-byte or 8-byte word addressing on addesses that are not aligned
00013  * to those boundaries.  The JVM does not care about such things,
00014  * but must accomodate real machine implementations in a way that
00015  * they do not complain about it at run time.  There area also
00016  * functions here that provide such support.  They typically are
00017  * embedded in widely-used macros from
00018  * @link jvm/src/cfmacros.h cfmacros.h@endlink and
00019  * @link jvm/src/util.h util.h@endlink.
00020  *
00021  * @section Control
00022  *
00023  * \$URL: https://svn.apache.org/path/name/bytegames.c $ \$Id: bytegames.c 0 09/28/2005 dlydick $
00024  *
00025  * Copyright 2005 The Apache Software Foundation
00026  * or its licensors, as applicable.
00027  *
00028  * Licensed under the Apache License, Version 2.0 ("the License");
00029  * you may not use this file except in compliance with the License.
00030  * You may obtain a copy of the License at
00031  *
00032  *     http://www.apache.org/licenses/LICENSE-2.0
00033  *
00034  * Unless required by applicable law or agreed to in writing,
00035  * software distributed under the License is distributed on an
00036  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
00037  * either express or implied.
00038  *
00039  * See the License for the specific language governing permissions
00040  * and limitations under the License.
00041  *
00042  * @version \$LastChangedRevision: 0 $
00043  *
00044  * @date \$LastChangedDate: 09/28/2005 $
00045  *
00046  * @author \$LastChangedBy: dlydick $
00047  *         Original code contributed by Daniel Lydick on 09/28/2005.
00048  *
00049  * @section Reference
00050  *
00051  */
00052 
00053 #include "arch.h"
00054 ARCH_COPYRIGHT_APACHE(bytegames, c, "$URL: https://svn.apache.org/path/name/bytegames.c $ $Id: bytegames.c 0 09/28/2005 dlydick $");
00055 
00056  
00057 #include "jvmcfg.h"
00058 #include "util.h"
00059 
00060 /*!
00061  * @name Unions for 1- 2- and 4- and 8-byte value ordering conversions.
00062  *
00063  * @brief Load in a value in one format and extract them in another.
00064  *
00065  * These unions are generic enough to be able to support signed and
00066  * unsigned values for loading and storing 1-, 2-, 4-, and 8-byte
00067  * integers.
00068  *
00069  */
00070 
00071 /*@{ */ /* Begin grouped definitions */
00072 
00073 /*!
00074  * @brief Structure for shuffling two-byte values.
00075  *
00076  * Load into @b _usval as an rushort and extract as bytes,
00077  * or vice versa.
00078  *
00079  */
00080 typedef union
00081 {
00082     rushort _usval; /**< Unsigned short representation */
00083 
00084     struct
00085     {
00086         rbyte a;
00087         rbyte b;
00088 
00089     } _byteval;     /**< Unsigned byte representation */
00090 
00091 } twobyte;
00092 
00093 /*!
00094  * @brief Structure for shuffling four-byte values
00095  *
00096  * Load into @b _ruival as an ruint or @b _juival as a juint
00097  * and extract as bytes, or vice versa.
00098  *
00099  */
00100 typedef union
00101 {
00102     ruint _ruival;  /**< Real unsigned int representation */
00103 
00104     juint _juival;  /**< Java unsigned int representation */
00105 
00106     struct
00107     {
00108         rbyte a;
00109         rbyte b;
00110         rbyte c;
00111         rbyte d;
00112 
00113     } _byteval;     /**< Unsigned byte representation */
00114 
00115 } fourbyte;
00116 
00117 /*!
00118  * @brief Structure for shuffling eight-byte values
00119  *
00120  * This structure handles both real types @link #rlong rlong@endlink
00121  * @link #rdouble rdouble@endlink and Java types
00122  * @link #jlong jlong@endlink and @link #jdouble jdouble@endlink
00123  *
00124  * Load into one of @b _rulval, @b _rdval, @b _julval, or @b _jdval,
00125  * respectively, and extract as two unsigned integers from @b _intval
00126  * or as bytes from @b _byteval.  Any combination of loading and storing
00127  * is permissible, although only certain combinations are useful for 
00128  * a given context.  (Namely, storing as @link #jdouble jdouble@endlink
00129  * and extracting as two @link #ruint ruint@endlink values doe not
00130  * really make much sense.)
00131  *
00132  */
00133 typedef union
00134 {
00135     rulong  _rulval;  /**< Real unsigned long long representation */
00136 
00137     rdouble _rdval;   /**< Real double representation */
00138 
00139     rulong  _julval;  /**< Java unsigned long long representation */
00140 
00141     rdouble _jdval;   /**< Java double representation */
00142 
00143     struct
00144     {
00145 #ifdef ARCH_BIG_ENDIAN
00146         fourbyte ms;
00147         fourbyte ls;
00148 #else
00149         fourbyte ls;
00150         fourbyte ms;
00151 #endif
00152 
00153     } _intval;        /**< Unsigned int representation */
00154 
00155     struct
00156     {
00157         rbyte a;
00158         rbyte b;
00159         rbyte c;
00160         rbyte d;
00161         rbyte e;
00162         rbyte f;
00163         rbyte g;
00164         rbyte h;
00165 
00166     } _byteval;       /**< Unsigned byte representation */
00167 
00168 } eightbyte;
00169 
00170 /*@} */ /* End of grouped definitions */
00171 
00172 
00173 /**********************************************************************/
00174 /*!
00175  * @name Unaligned multi-byte access support.
00176  *
00177  * @brief Store and retrieve arbitrary 2- and 4-byte values from
00178  * unaligned addresses without causing @b SIGSEGV signals by performing
00179  * 1-byte addressing on these locations.
00180  *
00181  * The 2- and 4-byte functions are typically used for absorbing class
00182  * file stream data into a ClassFile structure.  Of particular
00183  * interest is
00184  * @link #classfile_loadclassdata() classfile_loadclassdata()@endlink,
00185  * where it is used to retrieve many different types of 2- and 4-byte
00186  * data.  The 8-byte functions are used by @link
00187    #class_get_constant_field_attribute()
00188    class_get_constant_field_attribute()@endlink for retrieving
00189  * @link #jlong jlong@endlink and @link #jdouble jdouble@endlink
00190  * constants.
00191  *
00192  */
00193 
00194 /*@{ */ /* Begin grouped definitions */
00195 
00196 /*!
00197  * @brief Retrieve any generic 2-byte value (16 bits), whether or not
00198  * its is aligned on a 2-byte (that is, even address) boundary.
00199  *
00200  * This function was written to suppress @b SIGSEGV issues on
00201  * GCC -m32 binaries on a Solaris 9.
00202  *
00203  * Typical usage is in a situation of:
00204  * @verbatim
00205   
00206        rshort *pshort;
00207        ...
00208        val = *pshort;   ... If pshort is at odd address, throw SIGSEGV.
00209   
00210    @endverbatim
00211  *
00212  * Thus convert to:
00213  * @verbatim
00214   
00215        rshort *pshort;
00216        ...
00217        val = getrs2(pshort);    ... No signal this way.
00218   
00219    @endverbatim
00220  *
00221  * This causes two one-byte accesses to happen instead of a single
00222  * two-byte access, eliminating the cause of @b SIGSEGV, unless, of
00223  * course, the pointer is off in the weeds instead of looking at
00224  * valid memory.
00225  *
00226  *
00227  * @param  ptr2   Pointer to @link #rushort rushort@endlink location.
00228  *
00229  *
00230  * @returns  16-bit value at *ptr2, properly byte swapped.
00231  *
00232  */
00233 rushort bytegames_getrs2(rushort *ptr2)
00234 {
00235     twobyte wholeval;
00236 
00237     rbyte *ptr1 = (rbyte *) ptr2;
00238 
00239     wholeval._byteval.a = *ptr1++;
00240     wholeval._byteval.b = *ptr1;
00241 
00242 #ifdef ARCH_LITTLE_ENDIAN
00243     wholeval._usval = swap2(wholeval._usval);
00244 #endif
00245 
00246     return(wholeval._usval);
00247 
00248 } /* END of bytegames_getrs2() */
00249 
00250 
00251 /*!
00252  * @brief Store any generic 2-byte value (16 bits), whether or not
00253  * its is aligned on a 2-byte (that is, even address) boundary.
00254  *
00255  * This function is the inverse of
00256  * @link #bytegames_getrs2() bytegames_getrs2()@endlink
00257  * above, which see for further explanation.
00258  *
00259  *
00260  * @param  ptr2   Pointer to @link #rushort rushort@endlink location.
00261  *
00262  * @param  val2   A @link #rushort rushort@endlink value to be stored.
00263  *
00264  *
00265  * @returns @link #rvoid rvoid@endlink
00266  *
00267  */
00268 rvoid bytegames_putrs2(rushort *ptr2, rushort val2)
00269 {
00270     twobyte wholeval;
00271 
00272     rbyte *ptr1 = (rbyte *) ptr2;
00273 
00274     wholeval._usval = val2;
00275 
00276 #ifdef ARCH_LITTLE_ENDIAN
00277     wholeval._usval = swap2(wholeval._usval);
00278 #endif
00279 
00280     *ptr1++ = wholeval._byteval.a;
00281     *ptr1   = wholeval._byteval.b;
00282 
00283     return;
00284 
00285 } /* END of bytegames_putrs2() */
00286 
00287 
00288 /*!
00289  * @brief 4-byte version of
00290  * @link #bytegames_getrs2() bytegames_getrs2()@endlink, but
00291  * performs two odd-byte accesses, not just one.
00292  *
00293  * This causes four one-byte accesses to happen instead of a single
00294  * four-byte access, eliminating the cause of @b SIGSEGV.
00295  *
00296  * @param   ptr4   Pointer to @link #ruint ruint@endlink location.
00297  *
00298  *
00299  * @returns 32-bit value at *ptr4, properly byte swapped.
00300  *
00301  */
00302 ruint bytegames_getri4(ruint *ptr4)
00303 {
00304     fourbyte wholeval;
00305 
00306     rbyte *ptr1 = (rbyte *) ptr4;
00307 
00308     wholeval._byteval.a = *ptr1++;
00309     wholeval._byteval.b = *ptr1++;
00310     wholeval._byteval.c = *ptr1++;
00311     wholeval._byteval.d = *ptr1;
00312 
00313 #ifdef ARCH_LITTLE_ENDIAN
00314     wholeval._ruival = swap4(wholeval._ruival);
00315 #endif
00316 
00317     return(wholeval._ruival);
00318 
00319 } /* END of bytegames_getri4() */
00320 
00321 
00322 /*!
00323  * @brief Store any generic 4-byte value (32 bits), whether or not
00324  * its is aligned on a 2-byte (that is, even address) boundary.
00325  *
00326  * This function is the inverse of
00327  * @link #bytegames_getri4() bytegames_getri4()@endlink
00328  * above, which see for further explanation.
00329  *
00330  *
00331  * @param  ptr4   Pointer to @link #ruint ruint@endlink location.
00332  *
00333  * @param  val4   An @link #ruint ruint@endlink value to be stored.
00334  *
00335  *
00336  * @returns @link #rvoid rvoid@endlink
00337  *
00338  */
00339 rvoid bytegames_putri4(ruint *ptr4, ruint val4)
00340 {
00341     fourbyte wholeval;
00342 
00343     rbyte *ptr1 = (rbyte *) ptr4;
00344 
00345     wholeval._ruival = val4;
00346 
00347 #ifdef ARCH_LITTLE_ENDIAN
00348     wholeval._ruival = swap4(wholeval._ruival);
00349 #endif
00350 
00351     *ptr1++ = wholeval._byteval.a;
00352     *ptr1++ = wholeval._byteval.b;
00353     *ptr1++ = wholeval._byteval.c;
00354     *ptr1   = wholeval._byteval.d;
00355 
00356     return;
00357 
00358 } /* END of bytegames_putri4() */
00359 
00360 
00361 /*!
00362  * @brief 8-byte version of
00363  * @link #bytegames_getri4() bytegames_getri4()@endlink, but
00364  * performs four odd-byte accesses, not just one.
00365  *
00366  * This causes eight one-byte accesses to happen instead of a single
00367  * eight-byte access, eliminating the cause of @b SIGSEGV.
00368  *
00369  *
00370  * @param  ptr8   Pointer to @link #rulong rulong@endlink location.
00371  *
00372  *
00373  * @returns  64-bit value from *ptr8, properly byte swapped.
00374  *
00375  */
00376 rulong bytegames_getrl8(rulong *ptr8)
00377 {
00378     eightbyte wholeval;
00379 
00380     rbyte *ptr1 = (rbyte *) ptr8;
00381 
00382     wholeval._byteval.a = *ptr1++;
00383     wholeval._byteval.b = *ptr1++;
00384     wholeval._byteval.c = *ptr1++;
00385     wholeval._byteval.d = *ptr1++;
00386     wholeval._byteval.e = *ptr1++;
00387     wholeval._byteval.f = *ptr1++;
00388     wholeval._byteval.g = *ptr1++;
00389     wholeval._byteval.h = *ptr1;
00390 
00391 #ifdef ARCH_LITTLE_ENDIAN
00392     wholeval._rulval = bytegames_swap8(wholeval._rulval);
00393 #endif
00394 
00395     return(wholeval._rulval);
00396 
00397 } /* END of bytegames_getrl8() */
00398 
00399 
00400 /*!
00401  * @brief Store any generic 8-byte value (64 bits), whether or not
00402  * its is aligned on a 2-byte (that is, even address) boundary.
00403  *
00404  * @brief This function is the inverse of
00405  * @link #bytegames_getrl8() bytegames_getrl8()@endlink above, which see
00406  * for further explanation.
00407  *
00408  * @attention NOTICE THAT THE TERM "long" and THE CAST @b (long) ARE
00409  *            FASTIDIOUSLY AVOIDED IN ORDER TO REMOVE ANY DOUBT AS
00410  *            TO WHAT IS A 32-BIT VALUE AND WHAT IS A 64-BIT VALUE!
00411  *
00412  *
00413  * @param  ptr8   Pointer to @link #rulong rulong@endlink location.
00414  *
00415  * @param  val8   A @link #rulong rulong@endlink value to be stored.
00416  *
00417  *
00418  * @returns @link #rvoid rvoid@endlink
00419  *
00420  */
00421 rvoid bytegames_putrl8(rulong *ptr8, rulong val8)
00422 {
00423     eightbyte wholeval;
00424 
00425     rbyte *ptr1 = (rbyte *) ptr8;
00426 
00427     wholeval._rulval = val8;
00428 
00429 #ifdef ARCH_LITTLE_ENDIAN
00430     wholeval._rulval = bytegames_swap8(wholeval._rulval);
00431 #endif
00432 
00433     *ptr1++ = wholeval._byteval.a;
00434     *ptr1++ = wholeval._byteval.b;
00435     *ptr1++ = wholeval._byteval.c;
00436     *ptr1++ = wholeval._byteval.d;
00437     *ptr1++ = wholeval._byteval.e;
00438     *ptr1++ = wholeval._byteval.f;
00439     *ptr1++ = wholeval._byteval.g;
00440     *ptr1   = wholeval._byteval.h;
00441 
00442     return;
00443 
00444 } /* END of bytegames_putrl8() */
00445 
00446 /*@} */ /* End of grouped definitions */
00447 
00448 
00449 /**********************************************************************/
00450 /*!
00451  * @name Byte swapping support.
00452  *
00453  * @brief Swap 2- and 4- and 8-byte values, especially for support of
00454  * little-endian real machines.
00455  *
00456  * Since the Java virtual machine is defined as a big-endian
00457  * architecture, these functions are supplied to map between the
00458  * big-endian JVM and a little-endian real machine implementation.
00459  *
00460  * The 2- and 4-byte functions are typically used for swapping class
00461  * file stream data as it is being absorbed into a ClassFile structure,
00462  * as well as for other general uses.  Of particular interest is
00463  * @link #classfile_loadclassdata() classfile_loadclassdata()@endlink,
00464  * where they are used to swap many different types of 2- and 4-byte
00465  * data.  The 8-byte functions are provided for completeness.
00466  *
00467  */
00468 
00469 /*@{ */ /* Begin grouped definitions */
00470 
00471 /*!
00472  * @brief Swap 2 bytes for a little-endian machine
00473  * @link #rushort rushort@endlink value to a big-endian
00474  * Java real machine implementation @link #rushort rushort@endlink
00475  * value.
00476  *
00477  * Available but not used in big-endian architectures.
00478  *
00479  * This routine is mapped for little-endian machines to
00480  * @link #MACHINE_JSHORT_SWAP MACHINE_JSHORT_SWAP()@endlink.
00481  *
00482  * @verbatim
00483   
00484    INPUT BYTE ORDER:    (a) (b)     rshort: (ab)
00485   
00486    OUTPUT BYTE ORDER:   (b) (a)     rshort: (ba)
00487   
00488    @endverbatim
00489  *
00490  *
00491  * @param    val    two-byte @link #rushort rushort@endlink to swap
00492  *
00493  *
00494  * @returns  swapped byte version of @b val
00495  *
00496  */
00497 rushort bytegames_swap2(rushort val)
00498 {
00499     twobyte wholeval;
00500 
00501     rbyte tmp;
00502 
00503     wholeval._usval = val;
00504 
00505     tmp = wholeval._byteval.a;
00506     wholeval._byteval.a = wholeval._byteval.b;
00507     wholeval._byteval.b = tmp;
00508 
00509     return(wholeval._usval);
00510 
00511 } /* END of bytegames_swap2() */
00512 
00513 /*!
00514  * @brief Swap 4 bytes for a little-endian machine
00515  * @link #ruint ruint@endlink value to a big-endian
00516  * Java real machine implementation
00517  * @link #ruint ruint@endlink value.
00518  *
00519  * Available but not used in big-endian architectures.
00520  *
00521  * This routine is mapped for little-endian machines to
00522  * @link #MACHINE_JINT_SWAP MACHINE_JINT_SWAP()@endlink.
00523  *
00524  * @verbatim
00525   
00526    INPUT BYTE ORDER:    (a) (b) (c) (d)     rint: (abcd)
00527   
00528    OUTPUT BYTE ORDER:   (d) (c) (b) (a)     rint: (dcba)
00529   
00530    @endverbatim
00531  *
00532  *
00533  * @param    val    four-byte @link #ruint ruint@endlink to swap
00534  *
00535  *
00536  * @returns  swapped byte version of @b val
00537  *
00538  */
00539 ruint bytegames_swap4(ruint  val)
00540 {
00541     fourbyte wholeval;
00542 
00543     rbyte tmp;
00544 
00545     wholeval._ruival = val;
00546 
00547     tmp = wholeval._byteval.a;
00548     wholeval._byteval.a = wholeval._byteval.d;
00549     wholeval._byteval.d = tmp;
00550 
00551     tmp = wholeval._byteval.b;
00552     wholeval._byteval.b = wholeval._byteval.c;
00553     wholeval._byteval.c = tmp;
00554 
00555     return(wholeval._ruival);
00556 
00557 } /* END of bytegames_swap4() */
00558 
00559 
00560 /*!
00561  * @brief Swap 8 bytes for a little-endian machine
00562  * @link #rulong rulong@endlink value to a big-endian
00563  * Java real machine implementation
00564  * @link #rulong rulong@endlink value.
00565  *
00566  * Available but not used in big-endian architectures.
00567  *
00568  * This routine is mapped for little-endian machines to
00569  * @link #MACHINE_JLONG_SWAP MACHINE_JLONG_SWAP()@endlink.
00570  *
00571  * @verbatim
00572   
00573    INPUT BYTE ORDER:  (a) (b) (c) (d) (e) (f) (g) (h)  rlong: (abcdefgh)
00574   
00575    OUTPUT BYTE ORDER: (h) (g) (f) (e) (d) (c) (b) (a)  rlong: (hgfedcba)
00576   
00577    @endverbatim
00578  *
00579  *
00580  * @param    val    eight-byte @link #rulong rulong@endlink to swap
00581  *
00582  *
00583  * @returns  swapped byte version of @b val
00584  *
00585  */
00586 rulong bytegames_swap8(rulong val)
00587 {
00588     eightbyte wholeval;
00589 
00590     rbyte tmp;
00591 
00592     wholeval._rulval = val;
00593 
00594     tmp = wholeval._byteval.a;
00595     wholeval._byteval.a = wholeval._byteval.h;
00596     wholeval._byteval.h = tmp;
00597 
00598     tmp = wholeval._byteval.b;
00599     wholeval._byteval.b = wholeval._byteval.g;
00600     wholeval._byteval.g = tmp;
00601 
00602     tmp = wholeval._byteval.c;
00603     wholeval._byteval.c = wholeval._byteval.f;
00604     wholeval._byteval.f = tmp;
00605 
00606     tmp = wholeval._byteval.d;
00607     wholeval._byteval.d = wholeval._byteval.e;
00608     wholeval._byteval.e = tmp;
00609 
00610     return(wholeval._rulval);
00611 
00612 } /* END of bytegames_swap8() */
00613 
00614 
00615 /*!
00616  * @brief Mix up 8 bytes for a little-endian machine
00617  * @link #rushort rushort@endlink value to a big-endian
00618  * Java real machine implementation
00619  * @link #rushort rushort@endlink value in the same way as
00620  * @link #bytegames_swap8() bytegames_swap8()@endlink,
00621  * but store the words MS first, LS second.
00622  *
00623  * Available but not used in big-endian architectures.
00624  *
00625  * This routine is mapped for little-endian machines to
00626  * @link #MACHINE_JLONG_MIX MACHINE_JLONG_MIX()@endlink.
00627  *
00628  * @verbatim
00629   
00630    INPUT BYTE ORDER:  (a) (b) (c) (d) (e) (f) (g) (h)  rlong: (abcdefgh)
00631   
00632    OUTPUT BYTE ORDER: (d) (c) (b) (a) (h) (g) (f) (e)  rlong: (dcbahgfe)
00633   
00634    @endverbatim
00635  *
00636  *
00637  *
00638  * @param    val    eight-byte @link #rulong rulong@endlink to swap/mix
00639  *
00640  * @returns  swapped/mixed byte version of @b val
00641  *
00642  */
00643 rulong bytegames_mix8(rulong val)
00644 {
00645     eightbyte wholeval;
00646 
00647     rbyte tmp;
00648 
00649     wholeval._rulval = val;
00650 
00651     tmp = wholeval._byteval.a;
00652     wholeval._byteval.a = wholeval._byteval.d;
00653     wholeval._byteval.d = tmp;
00654 
00655     tmp = wholeval._byteval.b;
00656     wholeval._byteval.b = wholeval._byteval.c;
00657     wholeval._byteval.c = tmp;
00658 
00659     tmp = wholeval._byteval.e;
00660     wholeval._byteval.e = wholeval._byteval.h;
00661     wholeval._byteval.h = tmp;
00662 
00663     tmp = wholeval._byteval.f;
00664     wholeval._byteval.f = wholeval._byteval.e;
00665     wholeval._byteval.e = tmp;
00666 
00667     return(wholeval._rulval);
00668 
00669 } /* END of bytegames_mix8() */
00670 
00671 /*@} */ /* End of grouped definitions */
00672 
00673 
00674 /**********************************************************************/
00675 /*!
00676  * @name Combine/split support for (jlong) and (jdouble).
00677  *
00678  * The @b combine operation takes two @link #jint jint@endlink words
00679  * as the MS and LS words of a @link #jlong jlong@endlink or 
00680  * @link #jdouble jdouble@endlink and returns a combined result.
00681  * This is typically used for retrieving JVM local variables or
00682  * operand stack parameters.
00683  *
00684  * The @b split operation is the reverse.  It takes a
00685  * @link #jlong jlong@endlink or @link #jdouble jdouble@endlink and
00686  * extracts two @link #jint jint@endlink words, typically for storage
00687  * into a JVM local variable or operand stack parameter.
00688  *
00689  * @todo Verify that @e all references to these routines load and
00690  * store the results in the proper order!  The MS word @e must be stored
00691  * first (local variable 'n' or first @link #PUSH() PUSH()@endlink
00692  * to operand stack).  The LS word @e must be stored second (local
00693  * variable 'n+1' or second @link #PUSH() PUSH()@endlink to
00694  * operand stack).  The retrieval from the operand stack @e must
00695  * be LS word as the first @link #POP() POP()@endlink, MS word
00696  * as the second @link #POP() POP()@endlink operation.  This
00697  * problem may occur especially in
00698  * @link jvm/src/native.c native.c@endlink and
00699  * @link jvm/src/opcode.c opcode.c@endlink.
00700  *
00701  */
00702 
00703 /*@{ */ /* Begin grouped definitions */
00704 
00705 /*!
00706  * @brief Combine two @link #jint jint@endlink words
00707  * into a @link #jlong jlong@endlink.
00708  *
00709  * Pass in two sequential words as @link #jint jint@endlink from
00710  * the JVM stack frame or operand stack or any other appropriate
00711  * source and return a result as @link #jlong jlong@endlink
00712  *
00713  *
00714  * @param msword  Java integer at first index.
00715  *
00716  * @param lsword  Java integer at second index, directly subsequent
00717  *                to @b msword.
00718  *
00719  * @returns  concatenation as @link #jlong jlong@endlink, properly
00720  *           byte ordered.
00721  */
00722 jlong bytegames_combine_jlong(jint msword, jint lsword)
00723 {
00724     eightbyte wholeval;
00725 
00726     wholeval._intval.ms._juival = msword;
00727     wholeval._intval.ls._juival = lsword;
00728 
00729     return(wholeval._julval);
00730 
00731 } /* END of bytegames_combine_jlong() */
00732 
00733 
00734 /*!
00735  * @brief Combine two @link #jint jint@endlink words
00736  * into a @link #jdouble jdouble@endlink
00737  *
00738  * Pass in two sequential words as @link #jint jint@endlink from the
00739  * JVM stack frame or operand stack or any other appropriate source
00740  * and return a result as @link #jdouble jdouble@endlink.
00741  *
00742  *
00743  * @param msword  Java integer at first index.
00744  *
00745  * @param lsword  Java integer at second index, directly subsequent
00746  *                to @b msword.
00747  *
00748  * @returns  concatenation as @link #jdouble jdouble@endlink ,
00749  *           properly byte ordered.
00750  *
00751  */
00752 jdouble bytegames_combine_jdouble(jint msword, jint lsword)
00753 {
00754     eightbyte wholeval;
00755 
00756     wholeval._intval.ms._juival = msword;
00757     wholeval._intval.ls._juival = lsword;
00758 
00759     return(wholeval._jdval);
00760 
00761 } /* END of bytegames_combine_jdouble() */
00762 
00763 
00764 /*!
00765  * @brief Split a @link #jlong jlong@endlink into
00766  * two @link #jint jint@endlink words.
00767  *
00768  * Pass in a @link #jlong jlong@endlink and return two words
00769  * suitable for storing into a JVM stack frame as a pair of local
00770  * variables or into the operand stack as two sequential
00771  * words.  The first receives the MS word, the second
00772  * receives the LS word, which should be the next sequential
00773  * stack frame local variable or operand stack location.
00774  *
00775  *
00776  * @param[in]     splitlong Java long integer to split.
00777  *
00778  * @param[out]    msword    Address of MS half of split value.
00779  *
00780  * @param[out]    lsword    Address of LS half of split value.
00781  *
00782  * @returns @link #rvoid rvoid@endlink
00783  *
00784  */
00785 rvoid bytegames_split_jlong(jlong splitlong, jint *msword, jint *lsword)
00786 {
00787     eightbyte wholeval;
00788 
00789     wholeval._julval = splitlong;
00790 
00791     *msword = wholeval._intval.ms._juival;
00792     *lsword = wholeval._intval.ls._juival;
00793 
00794     return;
00795 
00796 } /* END of bytegames_split_jlong() */
00797 
00798 
00799 /*!
00800  * @brief Split a @link #jdouble jdouble@endlink into
00801  * two @link #jint jint@endlink words.
00802  *
00803  * Pass in a @link #jlong jlong@endlink and return two words
00804  * suitable for storing into a JVM stack frame as a pair of local
00805  * variables or into the operand stack as two sequential
00806  * words.  The first receives the MS word, the second
00807  * receives the LS word, which should be the next sequential
00808  * stack frame local variable or operand stack location.
00809  *
00810  *
00811  * @param[in]     splitdouble Java double float to split.
00812  *
00813  * @param[out]    msword    Address of MS half of split value.
00814  *
00815  * @param[out]    lsword    Address of LS half of split value.
00816  *
00817  * @returns @link #rvoid rvoid@endlink
00818  *
00819  */
00820 rvoid bytegames_split_jdouble(jdouble  splitdouble,
00821                               jint    *msword,
00822                               jint    *lsword)
00823 {
00824     eightbyte wholeval;
00825 
00826     wholeval._jdval = splitdouble;
00827 
00828     *msword = wholeval._intval.ms._juival;
00829     *lsword = wholeval._intval.ls._juival;
00830 
00831     return;
00832 
00833 } /* END of bytegames_split_jdouble() */
00834 
00835 /*@} */ /* End of grouped definitions */
00836 
00837 
00838 /* EOF */
00839 

Generated on Fri Sep 30 18:59:25 2005 by  doxygen 1.4.4