src/Emu/PPC64Linux/PPC64Operation.h

説明を見る。
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 #ifndef PPC64_LINUX_PPC64LINUX_PPC64OPERATION_H
00033 #define PPC64_LINUX_PPC64LINUX_PPC64OPERATION_H
00034 
00035 #include "SysDeps/fenv.h"
00036 #include "Lib/shttl/bit.h"
00037 #include "Emu/Utility/GenericOperation.h"
00038 #include "Emu/Utility/System/Syscall/SyscallConvIF.h"
00039 #include "Emu/Utility/System/ProcessState.h"
00040 
00041 namespace Onikiri {
00042 namespace PPC64Linux {
00043 namespace Operation {
00044 
00045 using namespace EmulatorUtility;
00046 using namespace EmulatorUtility::Operation;
00047 
00048 // **********************************
00049 //              Utility
00050 // **********************************
00051 
00052 // tOvZDXER[SO] gp
00053 template <typename Type>
00054 inline int PPC64CalcFlag(Type lhs, Type rhs = 0)
00055 {
00056     if (lhs == rhs) {
00057         return 0x2;
00058     }
00059     else if (lhs > rhs) {
00060         return 0x4;
00061     }
00062     else if (lhs < rhs) {
00063         return 0x8;
00064     }
00065 
00066     return 0;   // never reached
00067 }
00068 
00069 // FP compare tOvZD
00070 template <typename Type>
00071 inline int PPC64CalcFlagFP(Type lhs, Type rhs = 0)
00072 {
00073     if (IsNAN(lhs) || IsNAN(rhs)) {
00074         return 0x1;
00075     }
00076     else if (lhs == rhs) {
00077         return 0x2;
00078     }
00079     else if (lhs > rhs) {
00080         return 0x4;
00081     }
00082     else if (lhs < rhs) {
00083         return 0x8;
00084     }
00085 
00086     return 0;   // never reached
00087 }
00088 
00089 // rlwinm }XN (MSB=0)
00090 template <typename Type>
00091 inline Type PPC64GenMask(unsigned int mb, unsigned int me)
00092 {
00093     unsigned int typeBits = sizeof(Type)*8;
00094 
00095     if (mb > me) {
00096         // rbgmembij0rbg
00097         return ~(Type)(shttl::mask(0, mb-me-1) << (typeBits-mb));
00098     }
00099     else {
00100         // rbgmbmeij1rbg
00101         return (Type)(shttl::mask(0, me-mb+1) << (typeBits-me-1));
00102     }
00103 }
00104 
00105 // FPSCRFEX, VX 
00106 inline u64 PPC64AdjustFPSCR(u64 fpscr)
00107 {
00108     fpscr &= 0x9fffffff;    // FEX, VXNA
00109 
00110     if (fpscr & 0x00000f80)
00111         fpscr |= 0x40000000;    // FEX Zbg
00112     if (fpscr & 0x01807000)
00113         fpscr |= 0x20000000;    // VX Zbg
00114 
00115     return fpscr;
00116 }
00117 
00118 // FPSCR  [h
00119 template <typename TFPSCR>
00120 struct PPC64FPSCRRoundMode : public std::unary_function<EmulatorUtility::OpEmulationState*, u64>
00121 {
00122     int operator()(EmulatorUtility::OpEmulationState* opState)
00123     {
00124         switch (TFPSCR()(opState) & 0x3) {
00125         case 0:
00126             return FE_TONEAREST;
00127         case 1:
00128             return FE_TOWARDZERO;
00129         case 2:
00130             return FE_UPWARD;
00131         case 3:
00132             return FE_DOWNWARD;
00133         default:
00134             ASSERT(0);  // never reached
00135             return FE_ROUNDDEFAULT;
00136         }
00137     }
00138 };
00139 
00140 
00141 
00142 // CR (TSrcCR)  TSrcBit  (MSB=0) 
00143 template <typename TSrcCR, typename TSrcBit>
00144 struct PPC64CRBit : public std::unary_function<EmulatorUtility::OpEmulationState*, u64>
00145 {
00146     u64 operator()(EmulatorUtility::OpEmulationState* opState)
00147     {
00148         ASSERT(TSrcBit()(opState) < 4);
00149         return (TSrcCR()(opState) >> (3-TSrcBit()(opState))) & 0x1;
00150     }
00151 };
00152 
00153 // CTR (TSrcCTR) fNgCTDestCTRCfNg
00154 template <typename TDestCTR, typename TSrcCTR>
00155 struct PPC64DecCTR : public std::unary_function<EmulatorUtility::OpEmulationState*, u64>
00156 {
00157     u64 operator()(EmulatorUtility::OpEmulationState* opState)
00158     {
00159         u64 result = TSrcCTR()(opState) - 1;
00160         TDestCTR::SetOperand(opState, result);
00161         return result;
00162     }
00163 };
00164 
00165 // **********************************
00166 //            system call
00167 // **********************************
00168 inline void PPC64SyscallSetArg(EmulatorUtility::OpEmulationState* opState)
00169 {
00170     EmulatorUtility::SyscallConvIF* syscallConv = opState->GetProcessState()->GetSyscallConv();
00171     syscallConv->SetArg(0, SrcOperand<0>()(opState));
00172     syscallConv->SetArg(1, SrcOperand<1>()(opState));
00173     syscallConv->SetArg(2, SrcOperand<2>()(opState));
00174 }
00175 
00176 // invoke syscall, get result&error and branch if any
00177 inline void PPC64SyscallCore(EmulatorUtility::OpEmulationState* opState)
00178 {
00179     EmulatorUtility::SyscallConvIF* syscallConv = opState->GetProcessState()->GetSyscallConv();
00180     syscallConv->SetArg(3, SrcOperand<0>()(opState));
00181     syscallConv->SetArg(4, SrcOperand<1>()(opState));
00182     syscallConv->SetArg(5, SrcOperand<2>()(opState));
00183     syscallConv->SetArg(6, SrcOperand<3>()(opState));
00184     syscallConv->Execute(opState);
00185 
00186     DstOperand<0>::SetOperand(opState, syscallConv->GetResult(EmulatorUtility::SyscallConvIF::RetValueIndex) );
00187     if (syscallConv->GetResult(EmulatorUtility::SyscallConvIF::ErrorFlagIndex))
00188         DstOperand<1>::SetOperand(opState, 1);  // set SO
00189     else
00190         DstOperand<1>::SetOperand(opState, 0);
00191 }
00192 
00193 // **********************************
00194 //              others
00195 // **********************************
00196 
00197 // cntlzw, cntlzd
00198 template <typename Type, typename TSrc>
00199 struct PPC64Cntlz : public std::unary_function<EmulatorUtility::OpEmulationState*, u64>
00200 {
00201     u64 operator()(EmulatorUtility::OpEmulationState* opState)
00202     {
00203         int lz = sizeof(Type)*8;    // leading zeros
00204         Type value = static_cast<Type>( TSrc()(opState) );  
00205 
00206         // value  n rbgEVtg0Cleading zeros  sizeof(Type)*8 - n
00207         while (value != 0) {
00208             lz --;
00209             value >>= 1;
00210         }
00211 
00212         return lz;
00213     }
00214 };
00215 
00216 // rlwinm
00217 template <typename Type, typename TSrc, typename TMaskBegin, typename TMaskEnd>
00218 struct PPC64Mask : public std::unary_function<EmulatorUtility::OpEmulationState*, Type>
00219 {
00220     Type operator()(EmulatorUtility::OpEmulationState* opState)
00221     {
00222         unsigned int typeBits = sizeof(Type)*8;
00223         unsigned int mb = static_cast<int>( TMaskBegin()(opState) & (typeBits-1) );
00224         unsigned int me = static_cast<int>( TMaskEnd()(opState) & (typeBits-1) );
00225 
00226         return static_cast<Type>(TSrc()(opState)) & PPC64GenMask<Type>(mb, me);
00227     }
00228 };
00229 
00230 // rldimi, rlwimi
00231 template <typename Type, typename TSrc1, typename TSrc2, typename TMaskBegin, typename TMaskEnd>
00232 struct PPC64MaskInsert : public std::unary_function<EmulatorUtility::OpEmulationState*, Type>
00233 {
00234     Type operator()(EmulatorUtility::OpEmulationState* opState)
00235     {
00236         unsigned int typeBits = sizeof(Type)*8;
00237         unsigned int mb = static_cast<int>( TMaskBegin()(opState) & (typeBits-1) );
00238         unsigned int me = static_cast<int>( TMaskEnd()(opState) & (typeBits-1) );
00239         Type mask = PPC64GenMask<Type>(mb, me);
00240 
00241         return (static_cast<Type>(TSrc2()(opState)) & mask) | (static_cast<Type>(TSrc1()(opState)) & ~mask);
00242     }
00243 };
00244 
00245 
00246 // **********************************
00247 //              compare
00248 // **********************************
00249 
00250 // Src1  Src2 rC Condition Register l
00251 template <typename Type, typename TSrc1, typename TSrc2>
00252 struct PPC64Compare : public std::unary_function<EmulatorUtility::OpEmulationState*, u64>
00253 {
00254     u64 operator()(EmulatorUtility::OpEmulationState* opState)
00255     {
00256         return PPC64CalcFlag(static_cast<Type>(TSrc1()(opState)), static_cast<Type>(TSrc2()(opState)));
00257     }
00258 };
00259 
00260 template <typename Type, typename TSrc1, typename TSrc2>
00261 struct PPC64FPCompare : public std::unary_function<EmulatorUtility::OpEmulationState*, u64>
00262 {
00263     u64 operator()(EmulatorUtility::OpEmulationState* opState)
00264     {
00265         return PPC64CalcFlagFP(static_cast<Type>(TSrc1()(opState)), static_cast<Type>(TSrc2()(opState)));
00266     }
00267 };
00268 
00269 // **********************************
00270 //       conversion
00271 // **********************************
00272 
00273 
00274 // TSrc _Typet^D
00275 // Type\llCllD
00276 template <typename Type, typename TSrc, typename RoundMode = IntConst<int, FE_ROUNDDEFAULT> >
00277 struct PPC64FPToInt : public std::unary_function<EmulatorUtility::OpEmulationState*, Type>
00278 {
00279     Type operator()(EmulatorUtility::OpEmulationState* opState)
00280     {
00281         typedef typename EmulatorUtility::signed_type<Type>::type SignedType;
00282         typedef typename TSrc::result_type FPType;
00283         // 2
00284         const SignedType maxValue = std::numeric_limits<SignedType>::max();
00285         const SignedType minValue = std::numeric_limits<SignedType>::min();
00286         FPType value = static_cast<FPType>( TSrc()(opState) );
00287         
00288         if (value > static_cast<FPType>(maxValue))
00289             return maxValue;
00290         else if (value < static_cast<FPType>(minValue))
00291             return minValue;
00292         else
00293             return static_cast<Type>(value);
00294     }
00295 };
00296 
00297 // floating round to integer nearest
00298 template <typename TSrc>
00299 struct PPC64FRIN : public std::unary_function<EmulatorUtility::OpEmulationState*, double>
00300 {
00301     double operator()(EmulatorUtility::OpEmulationState* opState)
00302     {
00303         double value = static_cast<double>( TSrc()(opState) );
00304 
00305         if (value > 0.0)
00306             return floor(value+0.5);
00307         else
00308             return ceil(value-0.5);
00309     }
00310 };
00311 
00312 // floating round to integer zero
00313 template <typename TSrc>
00314 struct PPC64FRIZ : public std::unary_function<EmulatorUtility::OpEmulationState*, double>
00315 {
00316     double operator()(EmulatorUtility::OpEmulationState* opState)
00317     {
00318         double value = static_cast<double>( TSrc()(opState) );
00319 
00320         if (value > 0.0)
00321             return floor(value);
00322         else
00323             return ceil(value);
00324     }
00325 };
00326 
00327 // floating round to integer plus
00328 template <typename TSrc>
00329 struct PPC64FRIP : public std::unary_function<EmulatorUtility::OpEmulationState*, double>
00330 {
00331     double operator()(EmulatorUtility::OpEmulationState* opState)
00332     {
00333         double value = static_cast<double>( TSrc()(opState) );
00334         return ceil(value);
00335     }
00336 };
00337 
00338 // floating round to integer minus
00339 template <typename TSrc>
00340 struct PPC64FRIM : public std::unary_function<EmulatorUtility::OpEmulationState*, double>
00341 {
00342     double operator()(EmulatorUtility::OpEmulationState* opState)
00343     {
00344         double value = static_cast<double>( TSrc()(opState) );
00345         return floor(value);
00346     }
00347 };
00348 
00349 
00350 // **********************************
00351 //    CR logical operations
00352 // **********************************
00353 // func(TSrcCR1[TSrcCI1rbg], TSrcCR2[TSrcCI2rbg])
00354 // CfbNXMSB=0
00355 template <typename TSrcCR1, typename TSrcCI1, typename TSrcCR2, typename TSrcCI2>
00356 struct PPC64CRAnd : public std::unary_function<EmulatorUtility::OpEmulationState*, u64>
00357 {
00358     u64 operator()(EmulatorUtility::OpEmulationState* opState)
00359     {
00360         return (shttl::test(TSrcCR1()(opState), 3-TSrcCI1()(opState)) & shttl::test(TSrcCR2()(opState), 3-TSrcCI2()(opState)));
00361     }
00362 };
00363 template <typename TSrcCR1, typename TSrcCI1, typename TSrcCR2, typename TSrcCI2>
00364 struct PPC64CRNand : public std::unary_function<EmulatorUtility::OpEmulationState*, u64>
00365 {
00366     u64 operator()(EmulatorUtility::OpEmulationState* opState)
00367     {
00368         return (shttl::test(TSrcCR1()(opState), 3-TSrcCI1()(opState)) & shttl::test(TSrcCR2()(opState), 3-TSrcCI2()(opState))) ^ 1;
00369     }
00370 };
00371 template <typename TSrcCR1, typename TSrcCI1, typename TSrcCR2, typename TSrcCI2>
00372 struct PPC64CROr : public std::unary_function<EmulatorUtility::OpEmulationState*, u64>
00373 {
00374     u64 operator()(EmulatorUtility::OpEmulationState* opState)
00375     {
00376         return (shttl::test(TSrcCR1()(opState), 3-TSrcCI1()(opState)) | shttl::test(TSrcCR2()(opState), 3-TSrcCI2()(opState)));
00377     }
00378 };
00379 template <typename TSrcCR1, typename TSrcCI1, typename TSrcCR2, typename TSrcCI2>
00380 struct PPC64CRNor : public std::unary_function<EmulatorUtility::OpEmulationState*, u64>
00381 {
00382     u64 operator()(EmulatorUtility::OpEmulationState* opState)
00383     {
00384         return (shttl::test(TSrcCR1()(opState), 3-TSrcCI1()(opState)) | shttl::test(TSrcCR2()(opState), 3-TSrcCI2()(opState))) ^ 1;
00385     }
00386 };
00387 template <typename TSrcCR1, typename TSrcCI1, typename TSrcCR2, typename TSrcCI2>
00388 struct PPC64CRXor : public std::unary_function<EmulatorUtility::OpEmulationState*, u64>
00389 {
00390     u64 operator()(EmulatorUtility::OpEmulationState* opState)
00391     {
00392         return (shttl::test(TSrcCR1()(opState), 3-TSrcCI1()(opState)) ^ shttl::test(TSrcCR2()(opState), 3-TSrcCI2()(opState)));
00393     }
00394 };
00395 template <typename TSrcCR1, typename TSrcCI1, typename TSrcCR2, typename TSrcCI2>
00396 struct PPC64CREqv : public std::unary_function<EmulatorUtility::OpEmulationState*, u64>
00397 {
00398     u64 operator()(EmulatorUtility::OpEmulationState* opState)
00399     {
00400         return (shttl::test(TSrcCR1()(opState), 3-TSrcCI1()(opState)) ^ shttl::test(TSrcCR2()(opState), 3-TSrcCI2()(opState))) ^ 1;
00401     }
00402 };
00403 template <typename TSrcCR1, typename TSrcCI1, typename TSrcCR2, typename TSrcCI2>
00404 struct PPC64CRAndC : public std::unary_function<EmulatorUtility::OpEmulationState*, u64>
00405 {
00406     u64 operator()(EmulatorUtility::OpEmulationState* opState)
00407     {
00408         return (shttl::test(TSrcCR1()(opState), 3-TSrcCI1()(opState)) | !shttl::test(TSrcCR2()(opState), 3-TSrcCI2()(opState)));
00409     }
00410 };
00411 template <typename TSrcCR1, typename TSrcCI1, typename TSrcCR2, typename TSrcCI2>
00412 struct PPC64CROrC : public std::unary_function<EmulatorUtility::OpEmulationState*, u64>
00413 {
00414     u64 operator()(EmulatorUtility::OpEmulationState* opState)
00415     {
00416         return (shttl::test(TSrcCR1()(opState), 3-TSrcCI1()(opState)) | !shttl::test(TSrcCR2()(opState), 3-TSrcCI2()(opState)));
00417     }
00418 };
00419 
00420 // **********************************
00421 //      shift operations
00422 // **********************************
00423 
00424 // carry of arithmetic right shift
00425 template <typename Type, typename TSrc1, typename TSrc2, unsigned int count_mask>
00426 struct PPC64CarryOfAShiftR : public std::unary_function<EmulatorUtility::OpEmulationState*, Type>
00427 {
00428     Type operator()(EmulatorUtility::OpEmulationState* opState)
00429     {
00430         Type value = static_cast<Type>( TSrc1()(opState) );
00431         size_t count = static_cast<size_t>( TSrc2()(opState) ) & count_mask;
00432         
00433         if ((value & ((Type)1 << (sizeof(Type)*8-1)))   // 
00434             && (value & shttl::mask(0, std::min(count, sizeof(Type)*8)))    // Vtg'1'フ
00435             )
00436             return 1;
00437         else
00438             return 0;
00439     }
00440 };
00441 
00442 
00443 // **********************************
00444 //    memory operations
00445 // **********************************
00446 template <typename Type, typename TAddrDest, typename TAddr>
00447 struct PPC64LoadWithUpdate : public std::unary_function<EmulatorUtility::OpEmulationState*, Type>
00448 {
00449     Type operator()(EmulatorUtility::OpEmulationState* opState)
00450     {
00451         u64 addr = TAddr()(opState);
00452         Type value = ReadMemory<Type>( opState, addr );
00453 
00454         TAddrDest::SetOperand( opState, addr );
00455         return value;
00456     }
00457 };
00458 
00459 template <typename Type, typename TAddrDest, typename TValue, typename TAddr>
00460 inline void PPC64StoreWithUpdate(EmulatorUtility::OpEmulationState* opState)
00461 {
00462     u64 addr = TAddr()(opState);
00463     WriteMemory<Type>(opState, addr, static_cast<Type>( TValue()(opState) ));
00464     TAddrDest::SetOperand( opState, addr );
00465 }
00466 
00467 // **********************************
00468 //    flag operations
00469 // **********************************
00470 template <typename TSrcFlag, typename TSrcField, typename TSrcValue>
00471 struct PPC64MTFSFI : public std::unary_function<EmulatorUtility::OpEmulationState*, u64 >
00472 {
00473     u64 operator()(EmulatorUtility::OpEmulationState* opState)
00474     {
00475         u64 fpscr = TSrcFlag()(opState);
00476         u64 value = TSrcValue()(opState) & shttl::mask(0, 4);
00477         int field = static_cast<int>(TSrcField()(opState));
00478         int bit_pos = 4*(7-field);
00479         u64 mask = ~shttl::mask(bit_pos, 4);
00480 
00481         return (fpscr & mask) | (value << bit_pos);
00482     }
00483 };
00484 
00485 template <typename TSrcFlag, typename TSrcFieldMask, typename TSrcValue>
00486 struct PPC64MTFSF : public std::unary_function<EmulatorUtility::OpEmulationState*, u64 >
00487 {
00488     u64 operator()(EmulatorUtility::OpEmulationState* opState)
00489     {
00490         u64 fpscr = TSrcFlag()(opState);
00491         u64 value = TSrcValue()(opState) & shttl::mask(0, 32);
00492         int fieldMask = static_cast<int>(TSrcFieldMask()(opState));
00493 
00494         u64 mask = 0;
00495         for (int i = 0; i < 8; i ++) {
00496             if (fieldMask & shttl::mask(i, 1)) {
00497                 mask |= shttl::mask(i*4, 4);
00498             }
00499         }
00500         mask = ~mask;
00501 
00502         return (fpscr & mask) | value;
00503     }
00504 };
00505 
00506 
00507 // **********************************
00508 //    result setting
00509 // **********************************
00510 
00511 // TDestCR[TDestCIrbg] = TFunc()()
00512 template <typename TDestCR, typename TDestCRI, typename TOrgCR, typename TFunc>
00513 inline void PPC64SetCRBit(EmulatorUtility::OpEmulationState* opState)
00514 {
00515     u64 value = TOrgCR()(opState);
00516 
00517     if (TFunc()(opState)) {
00518         value = shttl::set_bit(value, 3-TDestCRI()(opState));
00519     }
00520     else {
00521         value = shttl::reset_bit(value, 3-TDestCRI()(opState));
00522     }
00523 
00524     TDestCR::SetOperand(opState, value);
00525 }
00526 
00527 template <typename TDest, typename TFunc>
00528 inline void PPC64SetFPSCR(EmulatorUtility::OpEmulationState* opState)
00529 {
00530     typename TFunc::result_type result = PPC64AdjustFPSCR(TFunc()(opState));
00531     
00532     TDest::SetOperand(opState, result);
00533 }
00534 
00535 template <typename TDest, typename TDestFlag, typename TFunc>
00536 inline void PPC64SetFPSCRF(EmulatorUtility::OpEmulationState* opState)
00537 {
00538     typename TFunc::result_type result = PPC64AdjustFPSCR(TFunc()(opState));
00539     
00540     TDest::SetOperand(opState, result);
00541     TDestFlag::SetOperand(opState, result >> 27 & 0xf );
00542 }
00543 
00544 // TFuncl TDest ZbgClTDestFlagtO
00545 template <typename TDest, typename TDestFlag, typename TFunc>
00546 inline void PPC64SetF(EmulatorUtility::OpEmulationState* opState)
00547 {
00548     typename TFunc::result_type result = TFunc()(opState);  // rbg
00549 
00550     TDest::SetOperand(opState, result);
00551     TDestFlag::SetOperand(opState, PPC64CalcFlag(EmulatorUtility::cast_to_signed(result)) );
00552 }
00553 
00554 // TFuncl TDest ZbgClTDestFlagtO
00555 template <typename TDest, typename TDestFlag, typename TFPSCR, typename TFunc>
00556 inline void PPC64SetFPF(EmulatorUtility::OpEmulationState* opState)
00557 {
00558     typename TFunc::result_type result = TFunc()(opState);  // rbg
00559 
00560     TDest::SetOperand(opState, AsIntFunc<RegisterType>( result ));
00561     TDestFlag::SetOperand(opState, TFPSCR()(opState) >> 28 & 0xf );
00562 }
00563 
00564 // gsSetF
00565 template <typename TDest, typename TDestFlag, typename TFunc>
00566 inline void PPC64SetSextF(EmulatorUtility::OpEmulationState* opState)
00567 {
00568     typename EmulatorUtility::signed_type<typename TFunc::result_type>::type result = EmulatorUtility::cast_to_signed( TFunc()(opState) );  // rbg
00569 
00570     TDest::SetOperand(opState, result);
00571     TDestFlag::SetOperand(opState, PPC64CalcFlag(EmulatorUtility::cast_to_signed(result)) );
00572 }
00573 
00574 // **********************************
00575 //    branch operations
00576 // **********************************
00577 //
00578 // relative: current_pc + disp*sizeof(Code)
00579 // 
00580 // call saves next_pc to TDest
00581 //
00582 template <typename TSrcDisp>
00583 inline void PPC64BranchRelUncond(EmulatorUtility::OpEmulationState* opState)
00584 {
00585     u64 target = current_pc(opState) + 4*EmulatorUtility::cast_to_signed( TSrcDisp()(opState) );
00586     do_branch(opState, target);
00587 
00588     opState->SetTakenPC(target);
00589 }
00590 
00591 template <typename TSrcTarget>
00592 inline void PPC64BranchAbsUncond(EmulatorUtility::OpEmulationState* opState)
00593 {
00594     // <TODO> 0x03
00595     RegisterType addr = TSrcTarget()(opState) & ~(RegisterType)0x03;
00596     do_branch(opState, addr );
00597 
00598     opState->SetTakenPC(addr);
00599 }
00600 
00601 template <typename TSrcDisp, typename TCond>
00602 inline void PPC64BranchRelCond(EmulatorUtility::OpEmulationState* opState)
00603 {
00604     if ( TCond()(opState) ) {
00605         PPC64BranchRelUncond<TSrcDisp>(opState);
00606     }
00607     else {
00608         opState->SetTakenPC( current_pc(opState) + 4*EmulatorUtility::cast_to_signed( TSrcDisp()(opState) ));
00609     }
00610 }
00611 
00612 template <typename TSrcTarget, typename TCond>
00613 inline void PPC64BranchAbsCond(EmulatorUtility::OpEmulationState* opState)
00614 {
00615     if ( TCond()(opState) ) {
00616         PPC64BranchAbsUncond<TSrcTarget>(opState);
00617     }
00618     else {
00619         RegisterType addr = TSrcTarget()(opState) & ~(RegisterType)0x03;
00620         opState->SetTakenPC( addr );
00621     }
00622 }
00623 
00624 
00625 template <typename TDest, typename TSrcDisp>
00626 inline void PPC64CallRelUncond(EmulatorUtility::OpEmulationState* opState)
00627 {
00628     RegisterType ret_addr = static_cast<RegisterType>( next_pc(opState) );
00629     PPC64BranchRelUncond<TSrcDisp>(opState);
00630     TDest::SetOperand(opState, ret_addr );
00631 }
00632 
00633 template <typename TDest, typename TSrcTarget>
00634 inline void PPC64CallAbsUncond(EmulatorUtility::OpEmulationState* opState)
00635 {
00636     // <TODO> 0x03
00637     RegisterType ret_addr = static_cast<RegisterType>( next_pc(opState) );
00638     PPC64BranchAbsUncond<TSrcTarget>(opState);
00639     TDest::SetOperand(opState, ret_addr );
00640 }
00641 
00642 } // namespace Operation {
00643 } // namespace PPC64Linux {
00644 } // namespace Onikiri
00645 
00646 #endif
00647 

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