src/Emu/Utility/GenericOperation.cpp

説明を見る。
00001 // 
00002 // Copyright (c) 2005-2008 Kenichi Watanabe.
00003 // Copyright (c) 2005-2008 Yasuhiro Watari.
00004 // Copyright (c) 2005-2008 Hironori Ichibayashi.
00005 // Copyright (c) 2008-2009 Kazuo Horio.
00006 // Copyright (c) 2009-2013 Naruki Kurata.
00007 // Copyright (c) 2005-2013 Ryota Shioya.
00008 // Copyright (c) 2005-2013 Masahiro Goshima.
00009 // 
00010 // This software is provided 'as-is', without any express or implied
00011 // warranty. In no event will the authors be held liable for any damages
00012 // arising from the use of this software.
00013 // 
00014 // Permission is granted to anyone to use this software for any purpose,
00015 // including commercial applications, and to alter it and redistribute it
00016 // freely, subject to the following restrictions:
00017 // 
00018 // 1. The origin of this software must not be misrepresented; you must not
00019 // claim that you wrote the original software. If you use this software
00020 // in a product, an acknowledgment in the product documentation would be
00021 // appreciated but is not required.
00022 // 
00023 // 2. Altered source versions must be plainly marked as such, and must not be
00024 // misrepresented as being the original software.
00025 // 
00026 // 3. This notice may not be removed or altered from any source
00027 // distribution.
00028 // 
00029 // 
00030 
00031 
00032 #include <pch.h>
00033 #include "Emu/Utility/GenericOperation.h"
00034 
00035 using namespace std;
00036 using namespace Onikiri;
00037 using namespace Onikiri::EmulatorUtility;
00038 using namespace Onikiri::EmulatorUtility::Operation;
00039 
00040 //
00041 // high-order 64 bits of the 128-bit product of unsigned lhs and rhs
00042 //
00043 u64 Onikiri::EmulatorUtility::Operation::UnsignedMulHigh64(u64 lhs, u64 rhs)
00044 {
00045     // split to high and low part
00046     u64 lhs_h = lhs >> 32;
00047     u64 lhs_l = lhs & 0xffffffff;
00048     u64 rhs_h = rhs >> 32;
00049     u64 rhs_l = rhs & 0xffffffff;
00050 
00051     u64 result = lhs_h * rhs_h;
00052 
00053     u64 lhs_l_rhs_h = lhs_l * rhs_h;
00054     u64 lhs_h_rhs_l = lhs_h * rhs_l;
00055 
00056     u64 lhs_l_rhs_l = lhs_l * rhs_l;
00057 
00058     // Add to 'result' high-order 64 bits of '(lhs_l_rhs_h<<32) + (lhs_r_rhs_l<<32) + lhs_l_rhs_l'
00059     //
00060     // Now, low-order 32 bits of lhs_l_rhs_l does not affect the result (since it generates no carry),
00061     // so we can simply take high-order 32 bits of
00062     // 'lhs_l_rhs_h&0x00000000ffffffff + lhs_h_rhs_l&0x00000000ffffffff + lhs_l_rhs_l>>32'.
00063     // and high-order 64 bits of
00064     // '(lhs_l_rhs_h&0xffffffff00000000 + lhs_h_rhs_l&0xffffffff00000000) << 32'
00065 
00066     result += (lhs_l_rhs_h>>32) + (lhs_h_rhs_l>>32);
00067     result += ((lhs_l_rhs_h&0xffffffff) + (lhs_h_rhs_l&0xffffffff) + (lhs_l_rhs_l>>32))>>32;
00068 
00069     return result;
00070 }
00071 
00072 s64 Onikiri::EmulatorUtility::Operation::SignedMulHigh64(s64 lhs, s64 rhs)
00073 {
00074     // @CEZsC
00075     s64 resultSign = 1;
00076     if (lhs < 0) {
00077         lhs = -lhs;
00078         resultSign *= -1;
00079     }
00080     if (rhs < 0) {
00081         rhs = -rhs;
00082         resultSign *= -1;
00083     }
00084     s64 result = (s64)UnsignedMulHigh64((u64)lhs, (u64)rhs);
00085     return result*resultSign;
00086 }
00087 

Onikiri2に対してTue Jun 18 14:34:20 2013に生成されました。  doxygen 1.4.7