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_COMMON_CONVERTER_H
00033 #define EMU_UTILITY_COMMON_CONVERTER_H
00034
00035 #include "Interface/OpClassCode.h"
00036
00037 namespace Onikiri {
00038
00039 namespace EmulatorUtility {
00040
00041
00042 template <class Traits>
00043 class CommonConverter : public ParamExchange
00044 {
00045 public:
00046
00047 typedef typename Traits::OpInfoType OpInfoType;
00048 typedef typename Traits::DecoderType DecoderType;
00049 typedef typename Traits::CodeWordType CodeWordType;
00050
00051 static const int MaxOpInfoInCode = Traits::MaxOpInfoDefs;
00052
00053 CommonConverter();
00054 virtual ~CommonConverter();
00055
00056
00057
00058 template<typename Iter>
00059 void Convert(CodeWordType codeWord, Iter out) const;
00060
00061
00062 typedef ParamExchange ParamExchangeType;
00063 using ParamExchangeType::LoadParam;
00064 using ParamExchangeType::ReleaseParam;
00065 using ParamExchangeType::GetRootPath;
00066 using ParamExchangeType::ParamEntry;
00067
00068 BEGIN_PARAM_MAP("/Session/Emulator/")
00069 BEGIN_PARAM_PATH("Converter/")
00070 PARAM_ENTRY("@EnableSplitLoadStore", m_enableSplitLoadStore)
00071 END_PARAM_PATH()
00072 END_PARAM_MAP()
00073
00074 protected:
00075
00076 static const int MaxOpInfoDefs = Traits::MaxOpInfoDefs;
00077 static const int MaxDstOperands = Traits::MaxDstOperands;
00078 static const int MaxSrcOperands = Traits::MaxSrcOperands;
00079
00080
00081 typedef typename DecoderType::DecodedInsn DecodedInsn;
00082 typedef typename OpInfoType::OperandType OperandType;
00083
00084 struct OpInfoDef
00085 {
00086 OpClassCode::OpClassCode Iclass;
00087
00088
00089 int DstTemplate[MaxDstOperands];
00090 int SrcTemplate[MaxSrcOperands];
00091
00092
00093 typename OpInfoType::EmulationFunc Func;
00094 };
00095
00096 struct OpDef {
00097 const char* Name;
00098 u32 Mask;
00099 u32 Opcode;
00100 int nOpInfoDefs;
00101 OpInfoDef OpInfoDefs[MaxOpInfoDefs];
00102 };
00103
00104
00105 bool IsSplitLoadStoreEnabled() const;
00106 void AddToOpMap(OpDef* opDefs, int count);
00107 const OpDef* FindOpDef(CodeWordType codeWord) const;
00108 OpInfoType ConvertOneOpInfo(
00109 const DecodedInsn& decoded,
00110 const OpInfoDef& opInfoDef,
00111 int microOpNum,
00112 int microOpIndex,
00113 const char* mnemonic
00114 ) const;
00115
00116 typedef std::map<CodeWordType, const OpDef *> OpcodeMap;
00117
00118 typedef std::map<CodeWordType, OpcodeMap, std::greater<CodeWordType> > MaskMap;
00119
00120
00121
00122
00123 virtual bool IsZeroReg(int reg) const = 0;
00124
00125
00126 virtual std::pair<OperandType, int> GetActualSrcOperand(int srcTemplate, const DecodedInsn& decoded) const = 0;
00127
00128
00129 virtual int GetActualRegNumber(int regTemplate, const DecodedInsn& decoded) const = 0;
00130
00131
00132 virtual const OpDef* GetOpDefUnknown() const = 0;
00133
00134 private:
00135 MaskMap m_opMap;
00136 bool m_enableSplitLoadStore;
00137
00138 };
00139
00140 template<class Traits>
00141 CommonConverter<Traits>::CommonConverter()
00142 {
00143 LoadParam();
00144 }
00145
00146 template<class Traits>
00147 CommonConverter<Traits>::~CommonConverter()
00148 {
00149 ReleaseParam();
00150 }
00151
00152 template<class Traits>
00153 template<typename Iter>
00154 void CommonConverter<Traits>::Convert(CodeWordType codeWord, Iter out) const
00155 {
00156 DecoderType decoder;
00157 DecodedInsn decoded;
00158 decoder.Decode(codeWord, &decoded);
00159 const OpDef* opdef = FindOpDef(codeWord);
00160
00161 for (int i = 0; i < opdef->nOpInfoDefs; i ++) {
00162 const OpInfoDef &opInfoDef = opdef->OpInfoDefs[i];
00163 *out++ =
00164 ConvertOneOpInfo(
00165 decoded,
00166 opInfoDef,
00167 opdef->nOpInfoDefs,
00168 i,
00169 opdef->Name
00170 );
00171 }
00172 }
00173
00174 template <class Traits>
00175 bool CommonConverter<Traits>::IsSplitLoadStoreEnabled() const
00176 {
00177 return m_enableSplitLoadStore;
00178 }
00179
00180 template <class Traits>
00181 void CommonConverter<Traits>::AddToOpMap(OpDef* opDefs, int count)
00182 {
00183 for (int i = 0; i < count; i ++) {
00184 const OpDef &opdef = opDefs[i];
00185
00186 ASSERT(m_opMap[opdef.Mask].find(opdef.Opcode) == m_opMap[opdef.Mask].end(), "opcode conflict detected");
00187 m_opMap[opdef.Mask][opdef.Opcode] = &opdef;
00188 }
00189 }
00190
00191
00192 template <class Traits>
00193 const typename CommonConverter<Traits>::OpDef* CommonConverter<Traits>::FindOpDef(CodeWordType codeWord) const
00194 {
00195
00196 for (typename MaskMap::const_iterator e = m_opMap.begin(); e != m_opMap.end(); ++e) {
00197 u32 mask = e->first;
00198 typename OpcodeMap::const_iterator i = e->second.find(codeWord & mask);
00199 if (i != e->second.end())
00200 return i->second;
00201 }
00202
00203 return GetOpDefUnknown();
00204 }
00205
00206
00207 template <class Traits>
00208 typename CommonConverter<Traits>::OpInfoType
00209 CommonConverter<Traits>::ConvertOneOpInfo(
00210 const DecodedInsn& decoded,
00211 const OpInfoDef& opInfoDef,
00212 int microNum,
00213 int microOpIndex,
00214 const char* mnemonic
00215 ) const
00216 {
00217 OpInfoType opInfo(OpClass(opInfoDef.Iclass));
00218
00219 ASSERT(opInfoDef.Func != 0, "opInfoDef.Func is null");
00220 opInfo.SetEmulationFunc(opInfoDef.Func);
00221 opInfo.SetMicroOpNum( microNum );
00222 opInfo.SetMicroOpIndex( microOpIndex );
00223 opInfo.SetMnemonic(mnemonic);
00224
00225
00226 if (opInfoDef.Iclass == OpClassCode::UNDEF) {
00227 opInfo.SetDstOpNum(0);
00228 opInfo.SetSrcOpNum(1);
00229 opInfo.SetImmNum(1);
00230
00231 opInfo.SetSrcRegNum(0);
00232 opInfo.SetDstRegNum(0);
00233
00234 opInfo.SetImmOpMap(0, 0);
00235 opInfo.SetImm(0, static_cast<s32>(decoded.CodeWord));
00236 return opInfo;
00237 }
00238
00239
00240
00241
00242
00243 int dstRegNum = 0;
00244 int dstOpNum = 0;
00245 for (int i = 0; i < MaxDstOperands; i ++) {
00246 int dstTemplate = opInfoDef.DstTemplate[i];
00247 if (dstTemplate == -1)
00248 break;
00249
00250 int dstReg = GetActualRegNumber( dstTemplate, decoded );
00251 ASSERT(dstReg != -1);
00252
00253 if (!IsZeroReg(dstReg)) {
00254 opInfo.SetDstRegOpMap(dstRegNum, i);
00255
00256 opInfo.SetDstReg(dstRegNum, dstReg);
00257 dstRegNum ++;
00258 }
00259 dstOpNum ++;
00260 }
00261 opInfo.SetDstOpNum(dstOpNum);
00262 opInfo.SetDstRegNum(dstRegNum);
00263
00264
00265 int srcRegNum = 0;
00266 int srcOpNum = 0;
00267 int immNum = 0;
00268 for (int i = 0; i < MaxSrcOperands; i ++) {
00269 int srcTemplate = opInfoDef.SrcTemplate[i];
00270 if (srcTemplate == -1)
00271 break;
00272
00273 std::pair<OperandType, int> operand = GetActualSrcOperand( srcTemplate, decoded );
00274 switch (operand.first) {
00275 case OpInfoType::REG:
00276 {
00277 int srcReg = operand.second;
00278 ASSERT(srcReg != -1);
00279
00280 if (IsZeroReg(srcReg)) {
00281
00282 opInfo.SetImmOpMap(immNum, i);
00283
00284 opInfo.SetImm(immNum, 0);
00285 immNum ++;
00286 }
00287 else {
00288 opInfo.SetSrcRegOpMap(srcRegNum, i);
00289
00290 opInfo.SetSrcReg(srcRegNum, srcReg);
00291 srcRegNum ++;
00292 }
00293 }
00294 break;
00295 case OpInfoType::IMM:
00296 {
00297 int immIndex = operand.second;
00298
00299 opInfo.SetImmOpMap(immNum, i);
00300
00301 opInfo.SetImm(immNum, decoded.Imm[immIndex]);
00302 immNum ++;
00303 }
00304 break;
00305 default:
00306 ASSERT(0, "Alpha64Converter Logic Error : invalid SrcType");
00307 }
00308
00309 srcOpNum ++;
00310 }
00311 opInfo.SetSrcOpNum(srcOpNum);
00312 opInfo.SetSrcRegNum(srcRegNum);
00313 opInfo.SetImmNum(immNum);
00314
00315 return opInfo;
00316 }
00317
00318 }
00319 }
00320
00321 #endif