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