00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #ifndef EMU_UTILITY_EMULATORUTILITY_GENERIC_OPERATION_H
00033 #define EMU_UTILITY_EMULATORUTILITY_GENERIC_OPERATION_H
00034
00035 #include "SysDeps/fenv.h"
00036 #include "Emu/Utility/Math.h"
00037 #include "Emu/Utility/OpEmulationState.h"
00038
00039 namespace Onikiri {
00040 namespace EmulatorUtility {
00041 namespace Operation {
00042
00043
00044
00045
00046 u64 UnsignedMulHigh64(u64 lhs, u64 rhs);
00047
00048 s64 SignedMulHigh64(s64 lhs, s64 rhs);
00049
00050 typedef u64 RegisterType;
00051
00052
00053
00054
00055
00056 inline void do_branch(OpEmulationState* opState, u64 target)
00057 {
00058 opState->SetTaken(true);
00059 }
00060
00061 inline u64 next_pc(OpEmulationState* opState)
00062 {
00063 return opState->GetPC()+4;
00064 }
00065
00066 inline u64 current_pc(OpEmulationState* opState)
00067 {
00068 return opState->GetPC();
00069 }
00070
00071 template <typename T>
00072 inline void WriteMemory(OpEmulationState* opState, u64 addr, const T &value)
00073 {
00074 Onikiri::MemAccess access;
00075 access.address.pid = opState->GetPID();
00076 access.address.address = addr;
00077 access.size = sizeof(T);
00078 access.sign = false;
00079 access.value = value;
00080 opState->GetOpState()->Write( &access );
00081 }
00082
00083 template <typename T>
00084 inline T ReadMemory(OpEmulationState* opState, u64 addr)
00085 {
00086 Onikiri::MemAccess access;
00087 access.address.pid = opState->GetPID();
00088 access.address.address = addr;
00089 access.size = sizeof(T);
00090 access.sign = false;
00091 access.value = 0;
00092 opState->GetOpState()->Read( &access );
00093 return static_cast<T>( access.value );
00094 }
00095
00096
00097
00098
00099
00100 template <typename FPType, typename IntType>
00101 inline FPType AsFPFunc(IntType value)
00102 {
00103 BOOST_STATIC_ASSERT(sizeof(IntType) == sizeof(FPType));
00104
00105 union {
00106 IntType i;
00107 FPType f;
00108 } intfp;
00109
00110 intfp.i = value;
00111 return intfp.f;
00112 }
00113
00114
00115 template <typename IntType, typename FPType>
00116 inline IntType AsIntFunc(FPType value)
00117 {
00118 BOOST_STATIC_ASSERT(sizeof(IntType) == sizeof(FPType));
00119 union {
00120 IntType i;
00121 FPType f;
00122 } intfp;
00123
00124 intfp.f = value;
00125 return intfp.i;
00126 }
00127
00128
00129 template <typename Type, typename TSrc>
00130 struct AsFP : public std::unary_function<OpEmulationState*, Type>
00131 {
00132 Type operator()(OpEmulationState* opState)
00133 {
00134 return AsFPFunc<Type>( TSrc()(opState) );
00135 }
00136 };
00137
00138
00139 template <typename Type, typename TSrc>
00140 struct AsInt : public std::unary_function<OpEmulationState*, Type>
00141 {
00142 Type operator()(OpEmulationState* opState)
00143 {
00144 return AsFPFunc<Type>( TSrc()(opState) );
00145 }
00146 };
00147
00148
00149
00150
00151
00152
00153
00154 template <int OperandIndex>
00155 class DstOperand
00156 {
00157 public:
00158 typedef RegisterType type;
00159 static void SetOperand(OpEmulationState* opState, RegisterType value)
00160 {
00161 opState->SetDst(OperandIndex, value);
00162 }
00163 };
00164
00165 template <int OperandIndex>
00166 struct SrcOperand : public std::unary_function<OpEmulationState, RegisterType>
00167 {
00168 typedef RegisterType type;
00169 RegisterType operator()(OpEmulationState* opState)
00170 {
00171 return opState->GetSrc(OperandIndex);
00172 }
00173 };
00174
00175 template <typename Type, Type value>
00176 struct IntConst : public std::unary_function<OpEmulationState*, Type>
00177 {
00178 Type operator()(OpEmulationState* opState)
00179 {
00180 return value;
00181 }
00182 };
00183
00184
00185
00186
00187
00188
00189
00190
00191 template<typename Type, typename ArgType = RegisterType>
00192 struct IntCondEqual : public std::binary_function<ArgType, ArgType, bool>
00193 {
00194 bool operator()(const ArgType lhs, const ArgType rhs) const
00195 {
00196 return static_cast<Type>(lhs) == static_cast<Type>(rhs);
00197 }
00198 };
00199
00200 template<typename Type, typename ArgType = RegisterType>
00201 struct IntCondNotEqual : public std::binary_function<ArgType, ArgType, bool>
00202 {
00203 bool operator()(const ArgType lhs, const ArgType rhs) const
00204 {
00205 return static_cast<Type>(lhs) != static_cast<Type>(rhs);
00206 }
00207 };
00208
00209 template<typename Type, typename ArgType = RegisterType>
00210 struct IntCondLessSigned : public std::binary_function<ArgType, ArgType, bool>
00211 {
00212 bool operator()(const ArgType lhs, const ArgType rhs) const
00213 {
00214 return cast_to_signed(static_cast<Type>(lhs)) < cast_to_signed(static_cast<Type>(rhs));
00215 }
00216 };
00217
00218 template<typename Type, typename ArgType = RegisterType>
00219 struct IntCondLessUnsigned : public std::binary_function<ArgType, ArgType, bool>
00220 {
00221 bool operator()(const ArgType lhs, const ArgType rhs) const
00222 {
00223 return cast_to_unsigned(static_cast<Type>(lhs)) < cast_to_unsigned(static_cast<Type>(rhs));
00224 }
00225 };
00226
00227 template<typename Type, typename ArgType = RegisterType>
00228 struct IntCondLessEqualSigned : public std::binary_function<ArgType, ArgType, bool>
00229 {
00230 bool operator()(const ArgType lhs, const ArgType rhs) const
00231 {
00232 return cast_to_signed(static_cast<Type>(lhs)) <= cast_to_signed(static_cast<Type>(rhs));
00233 }
00234 };
00235
00236 template<typename Type, typename ArgType = RegisterType>
00237 struct IntCondLessEqualUnsigned : public std::binary_function<ArgType, ArgType, bool>
00238 {
00239 bool operator()(const ArgType lhs, const ArgType rhs) const
00240 {
00241 return cast_to_unsigned(static_cast<Type>(lhs)) <= cast_to_unsigned(static_cast<Type>(rhs));
00242 }
00243 };
00244
00245 template<typename Type, typename ArgType = RegisterType>
00246 struct IntCondGreaterSigned : public std::binary_function<ArgType, ArgType, bool>
00247 {
00248 bool operator()(const ArgType lhs, const ArgType rhs) const
00249 {
00250 return cast_to_signed(static_cast<Type>(lhs)) > cast_to_signed(static_cast<Type>(rhs));
00251 }
00252 };
00253
00254 template<typename Type, typename ArgType = RegisterType>
00255 struct IntCondGreaterUnsigned : public std::binary_function<ArgType, ArgType, bool>
00256 {
00257 bool operator()(const ArgType lhs, const ArgType rhs) const
00258 {
00259 return cast_to_unsigned(static_cast<Type>(lhs)) > cast_to_unsigned(static_cast<Type>(rhs));
00260 }
00261 };
00262
00263 template<typename Type, typename ArgType = RegisterType>
00264 struct IntCondGreaterEqualSigned : public std::binary_function<ArgType, ArgType, bool>
00265 {
00266 bool operator()(const ArgType lhs, const ArgType rhs) const
00267 {
00268 return cast_to_signed(static_cast<Type>(lhs)) >= cast_to_signed(static_cast<Type>(rhs));
00269 }
00270 };
00271
00272 template<typename Type, typename ArgType = RegisterType>
00273 struct IntCondGreaterEqualUnsigned : public std::binary_function<ArgType, ArgType, bool>
00274 {
00275 bool operator()(const ArgType lhs, const ArgType rhs) const
00276 {
00277 return cast_to_unsigned(static_cast<Type>(lhs)) >= cast_to_unsigned(static_cast<Type>(rhs));
00278 }
00279 };
00280
00281 template<typename Type, int n, typename ArgType = RegisterType>
00282 struct IntCondEqualNthBit : public std::binary_function<ArgType, ArgType, bool>
00283 {
00284 bool operator()(const ArgType lhs, const ArgType rhs) const
00285 {
00286 return (static_cast<Type>(lhs) & ((Type)1 << n)) == (static_cast<Type>(rhs) & ((Type)1 << n));
00287 }
00288 };
00289
00290 template<typename Type, int n, typename ArgType = RegisterType>
00291 struct IntCondNotEqualNthBit : public std::binary_function<ArgType, ArgType, bool>
00292 {
00293 bool operator()(const ArgType lhs, const ArgType rhs) const
00294 {
00295 return (static_cast<Type>(lhs) & ((Type)1 << n)) != (static_cast<Type>(rhs) & ((Type)1 << n));
00296 }
00297 };
00298
00299
00300
00301
00302 template<typename Type, typename ArgType = RegisterType>
00303 struct FPCondEqual : public std::binary_function<ArgType, ArgType, bool>
00304 {
00305 bool operator()(const ArgType lhs, const ArgType rhs) const
00306 {
00307 return AsFPFunc<Type>(lhs) == AsFPFunc<Type>(rhs);
00308 }
00309 };
00310
00311 template<typename Type, typename ArgType = RegisterType>
00312 struct FPCondNotEqual : public std::binary_function<ArgType, ArgType, bool>
00313 {
00314 bool operator()(const ArgType lhs, const ArgType rhs) const
00315 {
00316 return AsFPFunc<Type>(lhs) != AsFPFunc<Type>(rhs);
00317 }
00318 };
00319
00320 template<typename Type, typename ArgType = RegisterType>
00321 struct FPCondLess : public std::binary_function<ArgType, ArgType, bool>
00322 {
00323 bool operator()(const ArgType lhs, const ArgType rhs) const
00324 {
00325 return AsFPFunc<Type>(lhs) < AsFPFunc<Type>(rhs);
00326 }
00327 };
00328
00329 template<typename Type, typename ArgType = RegisterType>
00330 struct FPCondLessEqual : public std::binary_function<ArgType, ArgType, bool>
00331 {
00332 bool operator()(const ArgType lhs, const ArgType rhs) const
00333 {
00334 return AsFPFunc<Type>(lhs) <= AsFPFunc<Type>(rhs);
00335 }
00336 };
00337
00338 template<typename Type, typename ArgType = RegisterType>
00339 struct FPCondGreater : public std::binary_function<ArgType, ArgType, bool>
00340 {
00341 bool operator()(const ArgType lhs, const ArgType rhs) const
00342 {
00343 return AsFPFunc<Type>(lhs) > AsFPFunc<Type>(rhs);
00344 }
00345 };
00346
00347 template<typename Type, typename ArgType = RegisterType>
00348 struct FPCondGreaterEqual : public std::binary_function<ArgType, ArgType, bool>
00349 {
00350 bool operator()(const ArgType lhs, const ArgType rhs) const
00351 {
00352 return AsFPFunc<Type>(lhs) >= AsFPFunc<Type>(rhs);
00353 }
00354 };
00355
00356 template <typename TSrc1, typename TSrc2>
00357 struct CondAnd : public std::unary_function<OpEmulationState*, bool>
00358 {
00359 bool operator()(OpEmulationState* opState)
00360 {
00361 bool lhs = TSrc1()(opState) != 0;
00362 bool rhs = TSrc2()(opState) != 0;
00363
00364 return lhs && rhs;
00365 }
00366 };
00367
00368 template <typename TSrc1, typename TSrc2>
00369 struct CondOr : public std::unary_function<OpEmulationState*, bool>
00370 {
00371 bool operator()(OpEmulationState* opState)
00372 {
00373 bool lhs = TSrc1()(opState) != 0;
00374 bool rhs = TSrc2()(opState) != 0;
00375
00376 return lhs || rhs;
00377 }
00378 };
00379
00380
00381
00382
00383 inline void UndefinedOperation(OpEmulationState* opState)
00384 {
00385
00386
00387 }
00388
00389
00390 inline void NoOperation(OpEmulationState* opState)
00391 {
00392
00393 }
00394
00395
00396 template <
00397 void (*Func1)(OpEmulationState *),
00398 void (*Func2)(OpEmulationState *)
00399 >
00400 inline void Sequence2(OpEmulationState* opState)
00401 {
00402 Func1(opState);
00403 Func2(opState);
00404 }
00405
00406 template <
00407 void (*Func1)(OpEmulationState *),
00408 void (*Func2)(OpEmulationState *),
00409 void (*Func3)(OpEmulationState *)
00410 >
00411 inline void Sequence3(OpEmulationState* opState)
00412 {
00413 Func1(opState);
00414 Func2(opState);
00415 Func3(opState);
00416 }
00417
00418
00419
00420
00421 template <typename TDest, typename TFunc>
00422 inline void SetSext(OpEmulationState* opState)
00423 {
00424 TDest::SetOperand(opState, cast_to_signed( TFunc()(opState) ) );
00425 }
00426
00427 template <typename TDest, typename TFunc>
00428 inline void Set(OpEmulationState* opState)
00429 {
00430 TDest::SetOperand(opState, TFunc()(opState) );
00431 }
00432
00433 template <typename TDest, typename TFunc>
00434 inline void SetFP(OpEmulationState* opState)
00435 {
00436 TDest::SetOperand(opState, AsIntFunc<RegisterType>( TFunc()(opState) ) );
00437 }
00438
00439 template <typename Type, typename TCond, typename TTrueValue, typename TFalseValue>
00440 struct Select : public std::unary_function<OpEmulationState*, Type>
00441 {
00442 Type operator()(OpEmulationState* opState)
00443 {
00444 if ( TCond()(opState) ) {
00445 return TTrueValue()(opState);
00446 }
00447 else {
00448 return TFalseValue()(opState);
00449 }
00450 }
00451 };
00452
00453
00454 template <typename Type, typename TValue>
00455 struct Cast : public std::unary_function<OpEmulationState*, Type>
00456 {
00457 Type operator()(OpEmulationState* opState)
00458 {
00459 return static_cast<Type>( TValue()(opState) );
00460 }
00461 };
00462
00463
00464 template <typename Type, typename TValue, typename RoundMode = IntConst<int, FE_ROUNDDEFAULT> >
00465 struct CastFP : public std::unary_function<OpEmulationState*, Type>
00466 {
00467 Type operator()(OpEmulationState* opState)
00468 {
00469 Onikiri::ScopedFESetRound sr( RoundMode()(opState) );
00470 volatile Type rvalue = static_cast<Type>( TValue()(opState) );
00471 return rvalue;
00472 }
00473 };
00474
00475
00476
00477
00478 template <typename Type, typename TAddr>
00479 struct Load : public std::unary_function<OpEmulationState*, Type>
00480 {
00481 Type operator()(OpEmulationState* opState)
00482 {
00483 return ReadMemory<Type>( opState, TAddr()(opState) );
00484 }
00485 };
00486
00487 template <typename Type, typename TValue, typename TAddr>
00488 inline void Store(OpEmulationState* opState)
00489 {
00490 WriteMemory<Type>(opState, TAddr()(opState), static_cast<Type>( TValue()(opState) ));
00491 }
00492
00493
00494
00495
00496
00497
00498 template <typename Type, typename TSrc1, typename TSrc2>
00499 struct IntAdd : public std::unary_function<OpEmulationState*, Type>
00500 {
00501 Type operator()(OpEmulationState* opState)
00502 {
00503 return static_cast<Type>(TSrc1()(opState)) + static_cast<Type>(TSrc2()(opState));
00504 }
00505 };
00506
00507 template <typename Type, typename TSrc1, typename TSrc2>
00508 struct IntSub : public std::unary_function<OpEmulationState*, Type>
00509 {
00510 Type operator()(OpEmulationState* opState)
00511 {
00512 return static_cast<Type>(TSrc1()(opState)) - static_cast<Type>(TSrc2()(opState));
00513 }
00514 };
00515
00516 template <typename Type, typename TSrc1, typename TSrc2>
00517 struct IntMul : public std::unary_function<OpEmulationState*, Type>
00518 {
00519 Type operator()(OpEmulationState* opState)
00520 {
00521 return static_cast<Type>(TSrc1()(opState)) * static_cast<Type>(TSrc2()(opState));
00522 }
00523 };
00524
00525 template <typename Type, typename TSrc1, typename TSrc2>
00526 struct IntDiv : public std::unary_function<OpEmulationState*, Type>
00527 {
00528 Type operator()(OpEmulationState* opState)
00529 {
00530 Type src2 = static_cast<Type>(TSrc2()(opState));
00531 if( src2 == 0 ){
00532 u64 addr = opState->GetOpState()->GetPC().address;
00533 RUNTIME_WARNING(
00534 "Division by zero occurred and returned 0 at PC: %08x%08x",
00535 (u32)(addr >> 32),
00536 (u32)(addr & 0xffffffff)
00537 );
00538 return 0;
00539 }
00540 return static_cast<Type>(TSrc1()(opState)) / static_cast<Type>(TSrc2()(opState));
00541 }
00542 };
00543
00544
00545 template <typename Type, int shift_count, typename TSrc1, typename TSrc2>
00546 struct IntScaledAdd : public std::unary_function<OpEmulationState*, Type>
00547 {
00548 Type operator()(OpEmulationState* opState)
00549 {
00550 return (static_cast<Type>(TSrc1()(opState)) << shift_count) + static_cast<Type>(TSrc2()(opState));
00551 }
00552 };
00553
00554
00555 template <typename Type, int shift_count, typename TSrc1, typename TSrc2>
00556 struct IntScaledSub : public std::unary_function<OpEmulationState*, Type>
00557 {
00558 Type operator()(OpEmulationState* opState)
00559 {
00560 return (static_cast<Type>(TSrc1()(opState)) << shift_count) - static_cast<Type>(TSrc2()(opState));
00561 }
00562 };
00563
00564
00565 template <typename TSrc1, typename TSrc2, typename Comp>
00566 struct Compare : public std::unary_function<OpEmulationState*, bool>
00567 {
00568 bool operator()(OpEmulationState* opState)
00569 {
00570 return Comp()(TSrc1()(opState), TSrc2()(opState));
00571 }
00572 };
00573
00574
00575 template <typename Type, typename TSrc1>
00576 struct IntNeg : public std::unary_function<OpEmulationState*, Type>
00577 {
00578 Type operator()(OpEmulationState* opState)
00579 {
00580 return cast_to_unsigned( -cast_to_signed( static_cast<Type>( TSrc1()(opState) ) ) );
00581 }
00582 };
00583
00584
00585 template <typename Type, typename TSrc1, typename TSrc2>
00586 struct CarryOfAdd : public std::unary_function<OpEmulationState*, RegisterType>
00587 {
00588 RegisterType operator()(OpEmulationState* opState)
00589 {
00590 Type lhs = static_cast<Type>( TSrc1()(opState) );
00591 Type rhs = static_cast<Type>( TSrc2()(opState) );
00592
00593 if (lhs + rhs < rhs)
00594 return 1;
00595 else
00596 return 0;
00597 }
00598 };
00599
00600
00601 template <typename Type, typename TSrc1, typename TSrc2, typename TSrcCarry>
00602 struct CarryOfAddWithCarry : public std::unary_function<OpEmulationState*, RegisterType>
00603 {
00604 RegisterType operator()(OpEmulationState* opState)
00605 {
00606 Type lhs = static_cast<Type>( TSrc1()(opState) );
00607 Type rhs = static_cast<Type>( TSrc2()(opState) );
00608 Type carry = static_cast<Type>( TSrcCarry()(opState) );
00609
00610 ASSERT(carry == 0 || carry == 1);
00611
00612 if (lhs + rhs < rhs || lhs + rhs + carry < rhs)
00613 return 1;
00614 else
00615 return 0;
00616 }
00617 };
00618
00619
00620 template <typename Type, typename TSrc1, typename TSrc2>
00621 struct BorrowOfSub : public std::unary_function<OpEmulationState*, RegisterType>
00622 {
00623 RegisterType operator()(OpEmulationState* opState)
00624 {
00625 Type lhs = static_cast<Type>( TSrc1()(opState) );
00626 Type rhs = static_cast<Type>( TSrc2()(opState) );
00627
00628 if (lhs < rhs)
00629 return 1;
00630 else
00631 return 0;
00632 }
00633 };
00634
00635
00636 template <typename Type, typename TSrc1, typename TSrc2, typename TSrcBorrow>
00637 struct BorrowOfSubWithBorrow : public std::unary_function<OpEmulationState*, RegisterType>
00638 {
00639 RegisterType operator()(OpEmulationState* opState)
00640 {
00641 Type lhs = static_cast<Type>( TSrc1()(opState) );
00642 Type rhs = static_cast<Type>( TSrc2()(opState) );
00643 Type borrow = static_cast<Type>( TSrcBorrow()(opState) );
00644
00645 ASSERT(borrow == 0 || borrow == 1);
00646
00647 if (rhs == ~(Type)0 || lhs < rhs + borrow)
00648 return 1;
00649 else
00650 return 0;
00651 }
00652 };
00653
00654 template <typename TSrc1, typename TSrc2>
00655 struct IntUMulh64 : public std::unary_function<EmulatorUtility::OpEmulationState, u64>
00656 {
00657 u64 operator()(OpEmulationState* opState) const
00658 {
00659 u64 lhs = TSrc1()(opState);
00660 u64 rhs = TSrc2()(opState);
00661
00662 return UnsignedMulHigh64(lhs, rhs);
00663 }
00664 };
00665
00666 template <typename TSrc1, typename TSrc2>
00667 struct IntSMulh64 : public std::unary_function<EmulatorUtility::OpEmulationState, u64>
00668 {
00669 s64 operator()(OpEmulationState* opState) const
00670 {
00671 s64 lhs = static_cast<s64>(TSrc1()(opState));
00672 s64 rhs = static_cast<s64>(TSrc2()(opState));
00673
00674 return SignedMulHigh64(lhs, rhs);
00675 }
00676 };
00677
00678
00679
00680
00681
00682
00683 template <typename Type, typename TSrc1, typename TSrc2, unsigned int count_mask>
00684 struct AShiftR : public std::unary_function<OpEmulationState*, Type>
00685 {
00686 Type operator()(OpEmulationState* opState)
00687 {
00688 Type value = static_cast<Type>( TSrc1()(opState) );
00689 typename TSrc2::result_type count = static_cast<typename TSrc2::result_type>( TSrc2()(opState) ) & count_mask;
00690
00691 if (count >= sizeof(Type)*8)
00692 return 0;
00693 else
00694 return static_cast<Type>( cast_to_unsigned( cast_to_signed(value) >> count ) );
00695 }
00696 };
00697
00698
00699 template <typename Type, typename TSrc1, typename TSrc2, unsigned int count_mask>
00700 struct LShiftR : public std::unary_function<OpEmulationState*, Type>
00701 {
00702 Type operator()(OpEmulationState* opState)
00703 {
00704 Type value = static_cast<Type>( TSrc1()(opState) );
00705 typename TSrc2::result_type count = static_cast<typename TSrc2::result_type>( TSrc2()(opState) ) & count_mask;
00706
00707 if (count >= sizeof(Type)*8)
00708 return 0;
00709 else
00710 return static_cast<Type>( cast_to_unsigned( cast_to_unsigned(value) >> count ) );
00711 }
00712 };
00713
00714 template <typename Type, typename TSrc1, typename TSrc2, unsigned int count_mask>
00715 struct LShiftL : public std::unary_function<OpEmulationState*, Type>
00716 {
00717 Type operator()(OpEmulationState* opState)
00718 {
00719 Type value = static_cast<Type>( TSrc1()(opState) );
00720 typename TSrc2::result_type count = static_cast<typename TSrc2::result_type>( TSrc2()(opState) ) & count_mask;
00721
00722 if (count >= sizeof(Type)*8)
00723 return 0;
00724 else
00725 return static_cast<Type>( cast_to_unsigned( cast_to_unsigned(value) << count ) );
00726 }
00727 };
00728
00729
00730 template <typename Type, typename TSrcValue, typename TSrcCount>
00731 struct RotateL : public std::unary_function<OpEmulationState*, Type>
00732 {
00733 Type operator()(OpEmulationState* opState)
00734 {
00735 const int typeBitCount = sizeof(Type)*8;
00736 Type value = static_cast<Type>( TSrcValue()(opState) );
00737 int count = static_cast<int>( TSrcCount()(opState) & (typeBitCount-1) );
00738
00739 if (count == 0)
00740 return value;
00741 else
00742 return (value << count) | (value >> (typeBitCount-count));
00743 }
00744 };
00745
00746 template <typename Type, typename TSrcValue, typename TSrcCount>
00747 struct RotateR : public std::unary_function<OpEmulationState*, Type>
00748 {
00749 Type operator()(OpEmulationState* opState)
00750 {
00751 const int typeBitCount = sizeof(Type)*8;
00752 Type value = static_cast<Type>( TSrcValue()(opState) );
00753 int count = static_cast<int>( TSrcCount()(opState) & (typeBitCount-1) );
00754
00755 if (count == 0)
00756 return value;
00757 else
00758 return (value >> count) | (value << (typeBitCount-count));
00759 }
00760 };
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770 template <typename Type, typename TSrc1, typename TSrc2>
00771 struct BitAnd : public std::unary_function<OpEmulationState*, Type>
00772 {
00773 Type operator()(OpEmulationState* opState)
00774 {
00775 Type lhs = static_cast<Type>( TSrc1()(opState) );
00776 Type rhs = static_cast<Type>( TSrc2()(opState) );
00777
00778 return lhs & rhs;
00779 }
00780 };
00781
00782
00783
00784 template <typename Type, typename TSrc1, typename TSrc2>
00785 struct BitAndNot : public std::unary_function<OpEmulationState*, Type>
00786 {
00787 Type operator()(OpEmulationState* opState)
00788 {
00789 Type lhs = static_cast<Type>( TSrc1()(opState) );
00790 Type rhs = static_cast<Type>( TSrc2()(opState) );
00791
00792 return lhs & ~rhs;
00793 }
00794 };
00795
00796
00797 template <typename Type, typename TSrc1, typename TSrc2>
00798 struct BitNand : public std::unary_function<OpEmulationState*, Type>
00799 {
00800 Type operator()(OpEmulationState* opState)
00801 {
00802 Type lhs = static_cast<Type>( TSrc1()(opState) );
00803 Type rhs = static_cast<Type>( TSrc2()(opState) );
00804
00805 return ~(lhs & rhs);
00806 }
00807 };
00808
00809
00810 template <typename Type, typename TSrc1, typename TSrc2>
00811 struct BitOr : public std::unary_function<OpEmulationState*, Type>
00812 {
00813 Type operator()(OpEmulationState* opState)
00814 {
00815 Type lhs = static_cast<Type>( TSrc1()(opState) );
00816 Type rhs = static_cast<Type>( TSrc2()(opState) );
00817
00818 return lhs | rhs;
00819 }
00820 };
00821
00822
00823 template <typename Type, typename TSrc1, typename TSrc2>
00824 struct BitOrNot : public std::unary_function<OpEmulationState*, Type>
00825 {
00826 Type operator()(OpEmulationState* opState)
00827 {
00828 Type lhs = static_cast<Type>( TSrc1()(opState) );
00829 Type rhs = static_cast<Type>( TSrc2()(opState) );
00830
00831 return lhs | ~rhs;
00832 }
00833 };
00834
00835
00836 template <typename Type, typename TSrc1, typename TSrc2>
00837 struct BitNor : public std::unary_function<OpEmulationState*, Type>
00838 {
00839 Type operator()(OpEmulationState* opState)
00840 {
00841 Type lhs = static_cast<Type>( TSrc1()(opState) );
00842 Type rhs = static_cast<Type>( TSrc2()(opState) );
00843
00844 return ~(lhs | rhs);
00845 }
00846 };
00847
00848
00849 template <typename Type, typename TSrc1, typename TSrc2>
00850 struct BitXor : public std::unary_function<OpEmulationState*, Type>
00851 {
00852 Type operator()(OpEmulationState* opState)
00853 {
00854 Type lhs = static_cast<Type>( TSrc1()(opState) );
00855 Type rhs = static_cast<Type>( TSrc2()(opState) );
00856
00857 return lhs ^ rhs;
00858 }
00859 };
00860
00861
00862 template <typename Type, typename TSrc1, typename TSrc2>
00863 struct BitXorNot : public std::unary_function<OpEmulationState*, Type>
00864 {
00865 Type operator()(OpEmulationState* opState)
00866 {
00867 Type lhs = static_cast<Type>( TSrc1()(opState) );
00868 Type rhs = static_cast<Type>( TSrc2()(opState) );
00869
00870 return lhs ^ ~rhs;
00871 }
00872 };
00873
00874 template <typename Type, typename TSrc1>
00875 struct BitNot : public std::unary_function<OpEmulationState*, Type>
00876 {
00877 Type operator()(OpEmulationState* opState)
00878 {
00879 Type lhs = static_cast<Type>( TSrc1()(opState) );
00880
00881 return ~lhs;
00882 }
00883 };
00884
00885 template <typename Type, typename TSrc, typename TBegin, typename TCount>
00886 struct BitExtract : public std::unary_function<OpEmulationState*, Type>
00887 {
00888 Type operator()(OpEmulationState* opState)
00889 {
00890 Type value = static_cast<Type>( TSrc()(opState) );
00891
00892 return (value >> (size_t)TBegin()(opState)) & shttl::mask(0, (size_t)TCount()(opState));
00893 }
00894 };
00895
00896
00897
00898
00899 template <typename Type, typename TSrc>
00900 struct NumberOfPopulations : public std::unary_function<OpEmulationState*, Type>
00901 {
00902 Type operator()(OpEmulationState* opState)
00903 {
00904 u64 value = static_cast<u64>( TSrc()(opState));
00905
00906 value = (value & 0x55555555) + (value >> 1 & 0x55555555);
00907 value = (value & 0x33333333) + (value >> 2 & 0x33333333);
00908 value = (value & 0x0f0f0f0f) + (value >> 4 & 0x0f0f0f0f);
00909 value = (value & 0x00ff00ff) + (value >> 8 & 0x00ff00ff);
00910 return static_cast<Type>((value & 0x0000ffff) + (value >>16 & 0x0000ffff));
00911 }
00912 };
00913
00914 template <typename Type, typename TSrc>
00915 struct NumberOfLeadingZeros : public std::unary_function<OpEmulationState*, Type>
00916 {
00917 Type operator()(OpEmulationState* opState)
00918 {
00919 u64 value = static_cast<u64>( TSrc()(opState));
00920
00921 value |= (value >> 1);
00922 value |= (value >> 2);
00923 value |= (value >> 4);
00924 value |= (value >> 8);
00925 value |= (value >> 16);
00926
00927 value = ~value;
00928
00929 value = (value & 0x55555555) + (value >> 1 & 0x55555555);
00930 value = (value & 0x33333333) + (value >> 2 & 0x33333333);
00931 value = (value & 0x0f0f0f0f) + (value >> 4 & 0x0f0f0f0f);
00932 value = (value & 0x00ff00ff) + (value >> 8 & 0x00ff00ff);
00933 return static_cast<Type>((value & 0x0000ffff) + (value >>16 & 0x0000ffff));
00934 }
00935 };
00936
00937 template <typename Type, typename TSrc>
00938 struct NumberOfTrailingZeros : public std::unary_function<OpEmulationState*, Type>
00939 {
00940 Type operator()(OpEmulationState* opState)
00941 {
00942 s64 value = static_cast<Type>( TSrc()(opState));
00943 value = (value&(-value))-1;
00944
00945 value = (value & 0x55555555) + (value >> 1 & 0x55555555);
00946 value = (value & 0x33333333) + (value >> 2 & 0x33333333);
00947 value = (value & 0x0f0f0f0f) + (value >> 4 & 0x0f0f0f0f);
00948 value = (value & 0x00ff00ff) + (value >> 8 & 0x00ff00ff);
00949 return static_cast<Type>((value & 0x0000ffff) + (value >>16 & 0x0000ffff));
00950 }
00951 };
00952
00953
00954
00955
00956
00957
00958
00959 template <typename TSrc1, typename TSrc2>
00960 struct FPDoubleCopySign : public std::unary_function<OpEmulationState*, u64>
00961 {
00962 u64 operator()(OpEmulationState* opState)
00963 {
00964 u64 lhs = static_cast<u64>( TSrc1()(opState) );
00965 u64 rhs = static_cast<u64>( TSrc2()(opState) );
00966
00967 return (lhs & (u64)0x8000000000000000ULL) | (rhs & ~(u64)0x8000000000000000ULL);
00968 }
00969 };
00970
00971 template <typename TSrc1, typename TSrc2>
00972 struct FPDoubleCopySignNeg : public std::unary_function<OpEmulationState*, u64>
00973 {
00974 u64 operator()(OpEmulationState* opState)
00975 {
00976 u64 lhs = static_cast<u64>( TSrc1()(opState) );
00977 u64 rhs = static_cast<u64>( TSrc2()(opState) );
00978
00979 return (~lhs & (u64)0x8000000000000000ULL) | (rhs & ~(u64)0x8000000000000000ULL);
00980 }
00981 };
00982
00983
00984 template <typename TSrc1, typename TSrc2>
00985 struct FPDoubleCopySignExp : public std::unary_function<OpEmulationState*, u64>
00986 {
00987 u64 operator()(OpEmulationState* opState)
00988 {
00989 u64 lhs = static_cast<u64>( TSrc1()(opState) );
00990 u64 rhs = static_cast<u64>( TSrc2()(opState) );
00991
00992 return (lhs & (u64)0xfff0000000000000ULL) | (rhs & ~(u64)0xfff0000000000000ULL);
00993 }
00994 };
00995
00996
00997 template <typename Type, typename TSrc1>
00998 struct FPNeg : public std::unary_function<OpEmulationState*, Type>
00999 {
01000 Type operator()(OpEmulationState* opState)
01001 {
01002 return -TSrc1()(opState);
01003 }
01004 };
01005
01006 template <typename Type, typename TSrc1>
01007 struct FPAbs : public std::unary_function<OpEmulationState*, Type>
01008 {
01009 Type operator()(OpEmulationState* opState)
01010 {
01011 return std::fabs( TSrc1()(opState) );
01012 }
01013 };
01014
01015 template <typename Type, typename TSrc1, typename TSrc2, typename RoundMode = IntConst<int, FE_ROUNDDEFAULT> >
01016 struct FPAdd : public std::unary_function<OpEmulationState*, Type>
01017 {
01018 Type operator()(OpEmulationState* opState)
01019 {
01020 Type lhs = TSrc1()(opState);
01021 Type rhs = TSrc2()(opState);
01022
01023 Onikiri::ScopedFESetRound sr( RoundMode()(opState) );
01024 volatile Type rvalue = lhs + rhs;
01025 return rvalue;
01026 }
01027 };
01028
01029 template <typename Type, typename TSrc1, typename TSrc2, typename RoundMode = IntConst<int, FE_ROUNDDEFAULT> >
01030 struct FPSub : public std::unary_function<OpEmulationState*, Type>
01031 {
01032 Type operator()(OpEmulationState* opState)
01033 {
01034 Type lhs = TSrc1()(opState);
01035 Type rhs = TSrc2()(opState);
01036
01037 Onikiri::ScopedFESetRound sr( RoundMode()(opState) );
01038 volatile Type rvalue = lhs - rhs;
01039 return rvalue;
01040 }
01041 };
01042
01043 template <typename Type, typename TSrc1, typename TSrc2, typename RoundMode = IntConst<int, FE_ROUNDDEFAULT> >
01044 struct FPMul : public std::unary_function<OpEmulationState*, Type>
01045 {
01046 Type operator()(OpEmulationState* opState)
01047 {
01048 Type lhs = TSrc1()(opState);
01049 Type rhs = TSrc2()(opState);
01050
01051 Onikiri::ScopedFESetRound sr( RoundMode()(opState) );
01052 volatile Type rvalue = lhs * rhs;
01053 return rvalue;
01054 }
01055 };
01056
01057 template <typename Type, typename TSrc1, typename TSrc2, typename RoundMode = IntConst<int, FE_ROUNDDEFAULT> >
01058 struct FPDiv : public std::unary_function<OpEmulationState*, Type>
01059 {
01060 Type operator()(OpEmulationState* opState)
01061 {
01062 Type lhs = TSrc1()(opState);
01063 Type rhs = TSrc2()(opState);
01064
01065 Onikiri::ScopedFESetRound sr( RoundMode()(opState) );
01066 volatile Type rvalue = lhs / rhs;
01067 return rvalue;
01068 }
01069 };
01070
01071 template <typename Type, typename TSrc1, typename RoundMode = IntConst<int, FE_ROUNDDEFAULT> >
01072 struct FPSqrt : public std::unary_function<OpEmulationState*, Type>
01073 {
01074 Type operator()(OpEmulationState* opState)
01075 {
01076 Onikiri::ScopedFESetRound sr( RoundMode()(opState) );
01077 volatile Type rvalue = std::sqrt( TSrc1()(opState) );
01078 return rvalue;
01079 }
01080 };
01081
01082 template <typename Type, typename TSrc1, typename TSrc2, typename RoundMode = IntConst<int, FE_ROUNDDEFAULT> >
01083 struct FPSubTest : public std::unary_function<OpEmulationState*, Type>
01084 {
01085 Type operator()(OpEmulationState* opState)
01086 {
01087 volatile Type lhs = TSrc1()(opState);
01088 volatile Type rhs = TSrc2()(opState);
01089
01090 Onikiri::ScopedFESetRound sr( RoundMode()(opState) );
01091 volatile Type rvalue = lhs - rhs;
01092 return rvalue;
01093 }
01094 };
01095
01096 template < int lhs, u64 rhs, int mode, u64 correct >
01097 static bool FpSubTestFunc( OpEmulationState* opState )
01098 {
01099 typedef double Dst;
01100 typedef Cast< double, IntConst< int, lhs > > Src1;
01101 typedef AsFP< double, IntConst< u64, rhs > > Src2;
01102 typedef IntConst< int, mode > Round;
01103
01104 Dst result = FPSubTest< Dst, Src1, Src2, Round >()( opState );
01105 return AsIntFunc< u64, double >( result ) == correct;
01106 }
01107
01108 inline void testroundmode(OpEmulationState* opState)
01109 {
01110 bool testResult;
01111
01112
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123
01124
01125 testResult = FpSubTestFunc< 1,0x3cac000000000000,FE_DOWNWARD,0x3feffffffffffffe >(opState)
01126 && FpSubTestFunc< 1,0x3cac000000000000,FE_UPWARD,0x3fefffffffffffff >(opState)
01127 && FpSubTestFunc< 1,0x3cac000000000000,FE_TONEAREST,0x3feffffffffffffe >(opState)
01128 && FpSubTestFunc< 1,0x3cac000000000000,FE_TOWARDZERO,0x3feffffffffffffe >(opState)
01129 && FpSubTestFunc< 1,0x3ca4000000000000,FE_DOWNWARD,0x3feffffffffffffe >(opState)
01130 && FpSubTestFunc< 1,0x3ca4000000000000,FE_UPWARD,0x3fefffffffffffff >(opState)
01131 && FpSubTestFunc< 1,0x3ca4000000000000,FE_TONEAREST,0x3fefffffffffffff >(opState)
01132 && FpSubTestFunc< 1,0x3ca4000000000000,FE_TOWARDZERO,0x3feffffffffffffe >(opState)
01133 && FpSubTestFunc< -1,0x3cac000000000000,FE_DOWNWARD,0xbff0000000000001 >(opState)
01134 && FpSubTestFunc< -1,0x3cac000000000000,FE_UPWARD,0xbff0000000000000 >(opState)
01135 && FpSubTestFunc< -1,0x3cac000000000000,FE_TONEAREST,0xbff0000000000001 >(opState)
01136 && FpSubTestFunc< -1,0x3cac000000000000,FE_TOWARDZERO,0xbff0000000000000 >(opState);
01137
01138 if (!testResult)
01139 {
01140 g_env.Print("\nFP rounding mode test failed. Programs may not be executed precisely.\n");
01141 }
01142 }
01143
01144
01145
01146
01147
01148
01149
01150
01151
01152 template <typename TSrcDisp>
01153 inline void BranchRelUncond(OpEmulationState* opState)
01154 {
01155 u64 target = next_pc(opState) + 4*cast_to_signed( TSrcDisp()(opState) );
01156 do_branch(opState, target);
01157
01158 opState->SetTakenPC(target);
01159 }
01160
01161 template <typename TSrcTarget>
01162 inline void BranchAbsUncond(OpEmulationState* opState)
01163 {
01164
01165 RegisterType addr = TSrcTarget()(opState) & ~(RegisterType)0x03;
01166 do_branch(opState, addr );
01167
01168 opState->SetTakenPC(addr);
01169 }
01170
01171 template <typename TSrcDisp, typename TCond>
01172 inline void BranchRelCond(OpEmulationState* opState)
01173 {
01174 if ( TCond()(opState) ) {
01175 BranchRelUncond<TSrcDisp>(opState);
01176 }
01177 else {
01178 opState->SetTakenPC( next_pc(opState) + 4*cast_to_signed( TSrcDisp()(opState) ));
01179 }
01180 }
01181
01182 template <typename TSrcTarget, typename TCond>
01183 inline void BranchAbsCond(OpEmulationState* opState)
01184 {
01185 if ( TCond()(opState) ) {
01186 BranchAbsUncond<TSrcTarget>(opState);
01187 }
01188 else {
01189 RegisterType addr = TSrcTarget()(opState) & ~(RegisterType)0x03;
01190 opState->SetTakenPC( addr );
01191 }
01192 }
01193
01194
01195 template <typename TDest, typename TSrcDisp>
01196 inline void CallRelUncond(OpEmulationState* opState)
01197 {
01198 RegisterType ret_addr = static_cast<RegisterType>( next_pc(opState) );
01199 BranchRelUncond<TSrcDisp>(opState);
01200 TDest::SetOperand(opState, ret_addr );
01201 }
01202
01203 template <typename TDest, typename TSrcTarget>
01204 inline void CallAbsUncond(OpEmulationState* opState)
01205 {
01206
01207 RegisterType ret_addr = static_cast<RegisterType>( next_pc(opState) );
01208 BranchAbsUncond<TSrcTarget>(opState);
01209 TDest::SetOperand(opState, ret_addr );
01210 }
01211
01212 }
01213 }
01214 }
01215
01216 #endif // #ifndef EMU_UTILITY_EMULATORUTILITY_GENERIC_OPERATION_H
01217