src/Emu/AlphaLinux/AlphaOperation.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 EMU_ALPHA_LINUX_ALPHALINUX_ALPHAOPERATION_H
00033 #define EMU_ALPHA_LINUX_ALPHALINUX_ALPHAOPERATION_H
00034 
00035 #include "SysDeps/fenv.h"
00036 #include "Utility/RuntimeError.h"
00037 #include "Emu/Utility/GenericOperation.h"
00038 #include "Emu/Utility/System/Syscall/SyscallConvIF.h"
00039 #include "Emu/Utility/System/ProcessState.h"
00040 
00041 
00042 namespace Onikiri {
00043 namespace AlphaLinux {
00044 namespace Operation {
00045 
00046 using namespace EmulatorUtility;
00047 using namespace EmulatorUtility::Operation;
00048 
00049 const RegisterType REG_VALUE_TRUE = 1;
00050 const RegisterType REG_VALUE_FALSE = 0;
00051 
00052 inline void AlphaPALHalt(EmulatorUtility::OpEmulationState* opState)
00053 {
00054     THROW_RUNTIME_ERROR("AlphaPALHalt called.");    // <TODO>
00055 }
00056 
00057 // memory barrier
00058 inline void AlphaPALIMB(EmulatorUtility::OpEmulationState* opState)
00059 {
00060     // VOXbh
00061 }
00062 
00063 // read thread-unique value
00064 inline void AlphaPALRdUniq(EmulatorUtility::OpEmulationState* opState)
00065 {
00066     DstOperand<0>::SetOperand( opState, opState->GetProcessState()->GetThreadUniqueValue() );
00067 }
00068 
00069 // write thread-unique value
00070 inline void AlphaPALWrUniq(EmulatorUtility::OpEmulationState* opState)
00071 {
00072     opState->GetProcessState()->SetThreadUniqueValue( SrcOperand<0>()(opState) );
00073 }
00074 
00075 inline void AlphaPALGenTrap(EmulatorUtility::OpEmulationState* opState)
00076 {
00077     THROW_RUNTIME_ERROR("AlphaPALGenTrap called."); // <TODO>
00078 }
00079 
00080 
00081 //
00082 // system call
00083 //
00084 // v0 = $0 
00085 // a0 = $16
00086 //
00087 // input:
00088 // v0: syscall number
00089 // a0-a4: arg1-arg5
00090 //
00091 // output:
00092 // a3 : error flag
00093 // v0 : return value or errno (if error)
00094 
00095 inline void AlphaSyscallSetArg(EmulatorUtility::OpEmulationState* opState)
00096 {
00097     EmulatorUtility::SyscallConvIF* syscallConv = opState->GetProcessState()->GetSyscallConv();
00098     syscallConv->SetArg(0, SrcOperand<0>()(opState));
00099     syscallConv->SetArg(1, SrcOperand<1>()(opState));
00100     syscallConv->SetArg(2, SrcOperand<2>()(opState));
00101 }
00102 
00103 // invoke syscall, get result&error and branch if any
00104 inline void AlphaSyscallCore(EmulatorUtility::OpEmulationState* opState)
00105 {
00106     EmulatorUtility::SyscallConvIF* syscallConv = opState->GetProcessState()->GetSyscallConv();
00107     syscallConv->SetArg(3, SrcOperand<0>()(opState));
00108     syscallConv->SetArg(4, SrcOperand<1>()(opState));
00109     syscallConv->SetArg(5, SrcOperand<2>()(opState));
00110     syscallConv->Execute(opState);
00111 
00112     DstOperand<0>::SetOperand(opState, syscallConv->GetResult(EmulatorUtility::SyscallConvIF::RetValueIndex) );
00113     DstOperand<1>::SetOperand(opState, syscallConv->GetResult(EmulatorUtility::SyscallConvIF::ErrorFlagIndex) );
00114 }
00115 
00116 
00117 // **********************************
00118 //              compare
00119 // **********************************
00120 template <typename TSrc1, typename TSrc2, typename Comp>
00121 struct AlphaCompare : public std::unary_function<EmulatorUtility::OpEmulationState*, u64>
00122 {
00123     u64 operator()(EmulatorUtility::OpEmulationState* opState)
00124     {
00125         if ( Comp()(TSrc1()(opState), TSrc2()(opState)) ) {
00126             return (u64)REG_VALUE_TRUE;
00127         }
00128         else {
00129             return (u64)REG_VALUE_FALSE;
00130         }
00131     }
00132 };
00133 
00134 template <typename TSrc1, typename TSrc2, typename Comp>
00135 struct AlphaTFloatCompare : public std::unary_function<EmulatorUtility::OpEmulationState*, u64>
00136 {
00137     u64 operator()(EmulatorUtility::OpEmulationState* opState)
00138     {
00139         if ( Comp()(TSrc1()(opState), TSrc2()(opState)) ) {
00140             return 0x4000000000000000LL;
00141         }
00142         else {
00143             return 0x0000000000000000LL;
00144         }
00145     }
00146 };
00147 
00148 // cmptun
00149 template<typename Type, typename ArgType = RegisterType>
00150 struct AlphaFPCondUnordered : public std::binary_function<ArgType, ArgType, bool>
00151 {
00152     bool operator()(const ArgType lhs, const ArgType rhs) const
00153     {
00154         return IsNAN(AsFPFunc<Type>(lhs)) || IsNAN(AsFPFunc<Type>(rhs));
00155     }
00156 };
00157 
00158 template<typename TSrc1, typename TSrc2>
00159 struct AlphaAddr : public std::unary_function<EmulatorUtility::OpEmulationState, RegisterType>
00160 {
00161     RegisterType operator()(EmulatorUtility::OpEmulationState* opState) const
00162     {
00163         return TSrc1()(opState) + EmulatorUtility::cast_to_signed( TSrc2()(opState) );
00164     }
00165 };
00166 
00167 // ldq_u, stq_u pAhXvZ
00168 template<typename TSrc1, typename TSrc2>
00169 struct AlphaAddrUnaligned : public std::unary_function<EmulatorUtility::OpEmulationState, RegisterType>
00170 {
00171     RegisterType operator()(EmulatorUtility::OpEmulationState* opState) const
00172     {
00173         return ( TSrc1()(opState) + EmulatorUtility::cast_to_signed( TSrc2()(opState) ) ) & ~(RegisterType)0x07;
00174     }
00175 };
00176 
00177 template<typename TSrc1, typename TSrc2>
00178 struct AlphaLdah : public std::unary_function<EmulatorUtility::OpEmulationState, RegisterType>
00179 {
00180     RegisterType operator()(EmulatorUtility::OpEmulationState* opState) const
00181     {
00182         return TSrc1()(opState) + EmulatorUtility::cast_to_signed( TSrc2()(opState) << 16);
00183     }
00184 };
00185 
00186 // **********************************
00187 //    byte-wise operations
00188 // **********************************
00189 
00190 // byte-wise compare
00191 template<typename TSrc1, typename TSrc2>
00192 struct AlphaCmpBge : public std::unary_function<EmulatorUtility::OpEmulationState, u64>
00193 {
00194     u64 operator()(EmulatorUtility::OpEmulationState* opState) const
00195     {
00196         u64 result = 0;
00197         u64 lhs = TSrc1()(opState);
00198         u64 rhs = TSrc2()(opState);
00199 
00200         for (int i = 0; i < 8; i ++) {
00201             if ((lhs & 0xff) >= (rhs & 0xff)) {
00202                 result |= 1 << 8;
00203             }
00204 
00205             lhs >>= 8;
00206             rhs >>= 8;
00207             result >>= 1;
00208         }
00209 
00210         return result;  
00211     }
00212 };
00213 
00214 template <typename Type, typename TSrc1, typename TSrc2>
00215 struct AlphaExtxl : public std::unary_function<EmulatorUtility::OpEmulationState, u64>
00216 {
00217     u64 operator()(EmulatorUtility::OpEmulationState* opState) const
00218     {
00219         u64 result = 0;
00220         u64 lhs = TSrc1()(opState);
00221         u64 rhs = TSrc2()(opState);
00222 
00223         int shift_cnt = static_cast<int>( (rhs & 0x7) << 3 );
00224         int byte_loc = shift_cnt;
00225         result = lhs >> byte_loc;
00226 
00227         return static_cast<Type>(result);
00228     }
00229 };
00230 
00231 template <typename Type, typename TSrc1, typename TSrc2>
00232 struct AlphaExtxh : public std::unary_function<EmulatorUtility::OpEmulationState, u64>
00233 {
00234     u64 operator()(EmulatorUtility::OpEmulationState* opState) const
00235     {
00236         u64 result = 0;
00237         u64 lhs = TSrc1()(opState);
00238         u64 rhs = TSrc2()(opState);
00239 
00240         int shift_cnt = static_cast<int>( (rhs & 0x7) << 3 );
00241         int byte_loc = 64 - shift_cnt;
00242         result = lhs << (byte_loc & 0x3f);
00243         
00244         // To avoid a optimization bug in VS2010 SP1.
00245         // Left shift is mistakenly done on u16 value...
00246         if( (size_t)( byte_loc & 0x3f ) >= sizeof(Type)*8 ){
00247             result = 0;
00248         }
00249 
00250         return  static_cast<Type>(result);
00251     }
00252 };
00253 
00254 template <typename Type, typename TSrc1, typename TSrc2>
00255 struct AlphaInsxl : public std::unary_function<EmulatorUtility::OpEmulationState, u64>
00256 {
00257     u64 operator()(EmulatorUtility::OpEmulationState* opState) const
00258     {
00259         u64 lhs = TSrc1()(opState);
00260         u64 rhs = TSrc2()(opState);
00261 
00262         int shift_cnt = static_cast<int>( (rhs & 0x7) << 3 );
00263         int byte_loc = shift_cnt;
00264 
00265         u64 result = static_cast<Type>(lhs);
00266         result <<= byte_loc;
00267 
00268         return result;
00269     }
00270 };
00271 
00272 template <typename Type, typename TSrc1, typename TSrc2>
00273 struct AlphaInsxh : public std::unary_function<EmulatorUtility::OpEmulationState, u64>
00274 {
00275     u64 operator()(EmulatorUtility::OpEmulationState* opState) const
00276     {
00277         u64 lhs = TSrc1()(opState);
00278         u64 rhs = TSrc2()(opState);
00279 
00280         int shift_cnt = static_cast<int>( (rhs & 0x7) << 3 );
00281         int byte_loc = 64 - shift_cnt;
00282         u64 bit_mask;
00283 
00284         if (shift_cnt + sizeof(Type)*8 > 64 ) {
00285             bit_mask = ~(~(u64)0 << (shift_cnt + sizeof(Type)*8 - 64));
00286         }
00287         else {
00288             bit_mask = 0;
00289         }
00290 
00291         u64 result;
00292         result = lhs >> (byte_loc & 0x3f);
00293         result &= bit_mask;
00294 
00295         return result;
00296     }
00297 };
00298 
00299 template <typename Type, typename TSrc1, typename TSrc2>
00300 struct AlphaMskxl : public std::unary_function<EmulatorUtility::OpEmulationState, u64>
00301 {
00302     u64 operator()(EmulatorUtility::OpEmulationState* opState) const
00303     {
00304         u64 lhs = TSrc1()(opState);
00305         u64 rhs = TSrc2()(opState);
00306 
00307         int shift_cnt = static_cast<int>( (rhs & 0x7) << 3 );
00308         u64 bit_mask;
00309         int type_bits = sizeof(Type) * 8;
00310         if (type_bits < 64)
00311             bit_mask = (((u64)1 << type_bits) - 1);
00312         else
00313             bit_mask = ~((u64)0);
00314         bit_mask <<= shift_cnt;
00315         bit_mask = ~bit_mask;
00316 
00317         u64 result;
00318         result = lhs & bit_mask;
00319 
00320         return result;
00321     }
00322 };
00323 
00324 template <typename Type, typename TSrc1, typename TSrc2>
00325 struct AlphaMskxh : public std::unary_function<EmulatorUtility::OpEmulationState, u64>
00326 {
00327     u64 operator()(EmulatorUtility::OpEmulationState* opState) const
00328     {
00329         u64 lhs = TSrc1()(opState);
00330         u64 rhs = TSrc2()(opState);
00331 
00332         int shift_cnt = static_cast<int>( (rhs & 0x7) << 3 );
00333         u64 bit_mask;
00334 
00335         if (shift_cnt + sizeof(Type)*8 > 64 ) {
00336             bit_mask = ~(u64)0 << (shift_cnt + sizeof(Type)*8 - 64);
00337         }
00338         else {
00339             bit_mask = ~(u64)0;
00340         }
00341 
00342         u64 result;
00343         result = lhs & bit_mask;
00344 
00345         return result;
00346     }
00347 };
00348 
00349 inline u64 AlphaZapNotBitMask(u64 byte_mask)
00350 {
00351     u64 result = 0;
00352     
00353     for (int i = 0; i < 8; i ++) {
00354         result <<= 8;
00355         result |= (((byte_mask & 0x80) >> 7) - 1) & 0xff;
00356         byte_mask <<= 1;
00357     }
00358 
00359     return result;
00360 }
00361 
00362 template <typename TSrc1, typename TSrc2>
00363 struct AlphaZap : public std::unary_function<EmulatorUtility::OpEmulationState, u64>
00364 {
00365     u64 operator()(EmulatorUtility::OpEmulationState* opState) const
00366     {
00367         u64 lhs = TSrc1()(opState);
00368         u64 rhs = TSrc2()(opState);
00369         
00370         return lhs & AlphaZapNotBitMask(rhs);
00371     }
00372 };
00373 
00374 template <typename TSrc1, typename TSrc2>
00375 struct AlphaZapNot : public std::unary_function<EmulatorUtility::OpEmulationState, u64>
00376 {
00377     u64 operator()(EmulatorUtility::OpEmulationState* opState) const
00378     {
00379         u64 lhs = TSrc1()(opState);
00380         u64 rhs = TSrc2()(opState);
00381         
00382         return lhs & ~AlphaZapNotBitMask(rhs);
00383     }
00384 };
00385 
00386 // BWX
00387 template <typename TSrc1>
00388 struct AlphaSextb : public std::unary_function<EmulatorUtility::OpEmulationState, u64>
00389 {
00390     u64 operator()(EmulatorUtility::OpEmulationState* opState) const
00391     {
00392         s64 val = EmulatorUtility::cast_to_signed((u8)TSrc1()(opState));
00393         return val;
00394     }
00395 };
00396 
00397 template <typename TSrc1>
00398 struct AlphaSextw : public std::unary_function<EmulatorUtility::OpEmulationState, u64>
00399 {
00400     u64 operator()(EmulatorUtility::OpEmulationState* opState) const
00401     {
00402         s64 val = EmulatorUtility::cast_to_signed((u16)TSrc1()(opState));
00403         return val;
00404     }
00405 };
00406 
00407 // FIX
00408 template <typename TSrc1>
00409 struct AlphaFtois : public std::unary_function<EmulatorUtility::OpEmulationState, u64>
00410 {
00411     u64 operator()(EmulatorUtility::OpEmulationState* opState) const
00412     {
00413         u64 va = TSrc1()(opState); 
00414         return (s32) (((va >> 32) & 0xc0000000) |
00415             ((va >> 29) & 0x3fffffff));
00416     }
00417 };
00418 
00419 template <typename TSrc1>
00420 struct AlphaItofs : public std::unary_function<EmulatorUtility::OpEmulationState*, u64>
00421 {
00422     u64 operator()(EmulatorUtility::OpEmulationState* opState)
00423     {
00424         u64 result;
00425         u64 va = TSrc1()(opState);
00426 
00427         result = ((va & 0x7fffffff) << 29) | ((va & 0x80000000) << 32);
00428         if ((va & 0x7f800000) == 0x7f800000) {       // exp = ~0
00429             result |= (u64)0x7ff << 52;
00430         }
00431         else if ((va & 0x7f800000) == 0x00000000) {  // exp = 0
00432             // do nothing
00433         }
00434         else {
00435             result += (u64)(1023-127) << 52;            // exp' = exp+896
00436         }
00437 
00438         return result;
00439     }
00440 };
00441 
00442 // MAX
00443 template <typename TSrc>
00444 struct AlphaPackLongWords : public std::unary_function<EmulatorUtility::OpEmulationState*, u64>
00445 {
00446     u64 operator()(EmulatorUtility::OpEmulationState* opState)
00447     {
00448         u64 val = TSrc()(opState);
00449 
00450         return (val & 0xff) | (((val >> 32) & 0xff) << 8);
00451     }
00452 };
00453 
00454 template <typename TSrc>
00455 struct AlphaPackWords : public std::unary_function<EmulatorUtility::OpEmulationState*, u64>
00456 {
00457     u64 operator()(EmulatorUtility::OpEmulationState* opState)
00458     {
00459         u64 val = TSrc()(opState);
00460 
00461         return (val & 0xff) | (((val >> 16) & 0xff) << 8) |
00462             (((val >> 32) & 0xff) << 16) | (((val >> 48) & 0xff) << 24);
00463     }
00464 };
00465 
00466 template <typename TSrc>
00467 struct AlphaUnpackLongWords : public std::unary_function<EmulatorUtility::OpEmulationState*, u64>
00468 {
00469     u64 operator()(EmulatorUtility::OpEmulationState* opState)
00470     {
00471         u64 val = TSrc()(opState);
00472 
00473         return (val & 0xff) | (((val >> 8) & 0xff) << 32);
00474     }
00475 };
00476 
00477 template <typename TSrc>
00478 struct AlphaUnpackWords : public std::unary_function<EmulatorUtility::OpEmulationState*, u64>
00479 {
00480     u64 operator()(EmulatorUtility::OpEmulationState* opState)
00481     {
00482         u64 val = TSrc()(opState);
00483 
00484         return (val & 0xff) | (((val >> 8) & 0xff) << 16) |
00485             (((val >> 16) & 0xff) << 32) | (((val >> 24) & 0xff) << 48);
00486     }
00487 };
00488 
00489 template <typename Type, typename TSrc1, typename TSrc2>
00490 struct AlphaVectorMin : public std::unary_function<EmulatorUtility::OpEmulationState*, u64>
00491 {
00492     u64 operator()(EmulatorUtility::OpEmulationState* opState)
00493     {
00494         u64 src1 = TSrc1()(opState);
00495         u64 src2 = TSrc2()(opState);
00496         u64 retval = 0;
00497         int vsize = sizeof(Type);
00498         
00499         for(int i = 0; i < 8/vsize; i++)
00500         {
00501             Type tempSrc1 = (Type)((src1>>(8*i*vsize)) & (0xff<<((vsize-1)*8) | 0xff));
00502             Type tempSrc2 = (Type)((src2>>(8*i*vsize)) & (0xff<<((vsize-1)*8) | 0xff));
00503             retval |= std::min<Type>(tempSrc1,tempSrc2) << 8*i*vsize;
00504         }
00505         return retval;
00506     }
00507 };
00508 
00509 template <typename Type, typename TSrc1, typename TSrc2>
00510 struct AlphaVectorMax : public std::unary_function<EmulatorUtility::OpEmulationState*, u64>
00511 {
00512     u64 operator()(EmulatorUtility::OpEmulationState* opState)
00513     {
00514         u64 src1 = TSrc1()(opState);
00515         u64 src2 = TSrc2()(opState);
00516         u64 retval = 0;
00517         int vsize = sizeof(Type);
00518 
00519         for(int i = 0; i < 8/vsize; i++)
00520         {
00521             Type tempSrc1 = (Type)((src1>>(8*i*vsize)) & (0xff<<((vsize-1)*8) | 0xff));
00522             Type tempSrc2 = (Type)((src2>>(8*i*vsize)) & (0xff<<((vsize-1)*8) | 0xff));
00523             retval |= std::max<Type>(tempSrc1,tempSrc2) << 8*i*vsize;
00524         }
00525         return retval;
00526     }
00527 };
00528 
00529 template <typename TSrc1, typename TSrc2>
00530 struct AlphaPixelError : public std::unary_function<EmulatorUtility::OpEmulationState*, u64>
00531 {
00532     u64 operator()(EmulatorUtility::OpEmulationState* opState)
00533     {
00534         u64 src1 = TSrc1()(opState);
00535         u64 src2 = TSrc2()(opState);
00536         u64 retval = 0;
00537         
00538         for(int i = 0; i < 8; i++)
00539         {
00540             u64 tempSrc1 = src1>>(8*i) & 0xff;
00541             u64 tempSrc2 = src2>>(8*i) & 0xff;
00542             retval += (tempSrc1 > tempSrc2) ? tempSrc1 - tempSrc2 :
00543                                                 tempSrc2 - tempSrc1;
00544         }
00545         return retval;
00546     }
00547 };
00548 
00549 // **********************************
00550 //    s-float load/store
00551 // **********************************
00552 
00553 template <typename TSrcFPCR>
00554 struct AlphaRoundModeFromFPCR : public std::unary_function<EmulatorUtility::OpEmulationState, u64>
00555 {
00556     int operator()(EmulatorUtility::OpEmulationState* opState) const
00557     {
00558         u64 fpcr = TSrcFPCR()(opState);
00559 
00560         switch ((fpcr >> 58) & 0x3) {   // FPCR 58:59rbg[h
00561         case 0x0:
00562             return FE_TOWARDZERO;
00563         case 0x1:
00564             return FE_DOWNWARD;
00565         case 0x2:
00566             return FE_TONEAREST;
00567         case 0x3:
00568             return FE_UPWARD;
00569         default:
00570             assert(0);  // never reached
00571             return FE_TOWARDZERO;
00572         }
00573     }
00574 };
00575 
00576 template <typename TSrc1>
00577 struct AlphaCvtLQ : public std::unary_function<EmulatorUtility::OpEmulationState, u64>
00578 {
00579     u64 operator()(EmulatorUtility::OpEmulationState* opState) const
00580     {
00581         u64 va = TSrc1()(opState);
00582         u64 result;
00583         
00584         result = ((va >> 32) & 0xc0000000) |
00585                  ((va >> 29) & 0x3fffffff);
00586         return (u64)(s64)(s32)result;   // sign extend
00587     }
00588 };
00589 
00590 template <typename TSrc1>
00591 struct AlphaCvtQL : public std::unary_function<EmulatorUtility::OpEmulationState, u64>
00592 {
00593     u64 operator()(EmulatorUtility::OpEmulationState* opState) const
00594     {
00595         u64 va = TSrc1()(opState);
00596         u64 result;
00597         
00598         result = ((va & 0xc0000000) << 32) |
00599                   ((va & 0x3fffffff) << 29);
00600         return result;
00601     }
00602 };
00603 
00604 template <typename TSrc1>
00605 struct AlphaCvtQS : public std::unary_function<EmulatorUtility::OpEmulationState, u64>
00606 {
00607     u64 operator()(EmulatorUtility::OpEmulationState* opState) const
00608     {
00609         s64 va = TSrc1()(opState);
00610 
00611         return AsIntFunc<u64>( (double)(float)(va) );
00612     }
00613 };
00614 
00615 template <typename TSrc1>
00616 struct AlphaCvtQT : public std::unary_function<EmulatorUtility::OpEmulationState, u64>
00617 {
00618     u64 operator()(EmulatorUtility::OpEmulationState* opState) const
00619     {
00620         s64 va = EmulatorUtility::cast_to_signed( TSrc1()(opState) );
00621 
00622         return AsIntFunc<u64>( (double)va );
00623     }
00624 };
00625 
00626 template <typename TSrc1>
00627 struct AlphaCvtTS : public std::unary_function<EmulatorUtility::OpEmulationState, u64>
00628 {
00629     u64 operator()(EmulatorUtility::OpEmulationState* opState) const
00630     {
00631         double va = AsFPFunc<double>( TSrc1()(opState) );
00632 
00633         return AsIntFunc<u64>( (double)(float)va );
00634     }
00635 };
00636 
00637 template <typename TSrc1>
00638 struct AlphaCvtTQ_c : public std::unary_function<EmulatorUtility::OpEmulationState, u64>
00639 {
00640     u64 operator()(EmulatorUtility::OpEmulationState* opState) const
00641     {
00642         double va = AsFPFunc<double>( TSrc1()(opState) );
00643 
00644         return (u64)(s64)va;
00645     }
00646 };
00647 
00648 template <typename TSrc1>
00649 struct AlphaCvtTQ_m : public std::unary_function<EmulatorUtility::OpEmulationState, u64>
00650 {
00651     u64 operator()(EmulatorUtility::OpEmulationState* opState) const
00652     {
00653         double va = AsFPFunc<double>( TSrc1()(opState) );
00654 
00655         return (u64)(s64)floor(va);
00656     }
00657 };
00658 
00659 // IEEE float -> IEEE double or load u32
00660 template <typename TAddr>
00661 struct AlphaLds : public std::unary_function<EmulatorUtility::OpEmulationState*, u64>
00662 {
00663     u64 operator()(EmulatorUtility::OpEmulationState* opState)
00664     {
00665         u64 result;
00666         u64 va = ReadMemory<u32>( opState, TAddr()(opState) );
00667 
00668         result = ((va & 0x7fffffff) << 29) | ((va & 0x80000000) << 32);
00669         if ((va & 0x7f800000) == 0x7f800000) {       // exp = ~0
00670             result |= (u64)0x7ff << 52;
00671         }
00672         else if ((va & 0x7f800000) == 0x00000000) {  // exp = 0
00673             // do nothing
00674         }
00675         else {
00676             result += (u64)(1023-127) << 52;            // exp' = exp+896
00677         }
00678 
00679         return result;
00680     }
00681 };
00682 
00683 // IEEE double -> IEEE float or store u32
00684 template <typename TSrc, typename TAddr>
00685 inline void AlphaSts(EmulatorUtility::OpEmulationState* opState)
00686 {
00687     u64 va = TSrc()(opState);
00688 
00689     WriteMemory<u32>( opState, TAddr()(opState), 
00690         (u32) (((va >> 32) & 0xc0000000) |
00691         ((va >> 29) & 0x3fffffff)));
00692 }
00693 
00694 } // namespace Operation {
00695 } // namespace AlphaLinux {
00696 } // namespace Onikiri
00697 
00698 #endif // #ifndef EMU_ALPHA_LINUX_ALPHALINUX_ALPHAOPERATION_H
00699 

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