src/Emu/AlphaLinux/Alpha64Decoder.cpp

説明を見る。
00001 // 
00002 // Copyright (c) 2005-2008 Kenichi Watanabe.
00003 // Copyright (c) 2005-2008 Yasuhiro Watari.
00004 // Copyright (c) 2005-2008 Hironori Ichibayashi.
00005 // Copyright (c) 2008-2009 Kazuo Horio.
00006 // Copyright (c) 2009-2013 Naruki Kurata.
00007 // Copyright (c) 2005-2013 Ryota Shioya.
00008 // Copyright (c) 2005-2013 Masahiro Goshima.
00009 // 
00010 // This software is provided 'as-is', without any express or implied
00011 // warranty. In no event will the authors be held liable for any damages
00012 // arising from the use of this software.
00013 // 
00014 // Permission is granted to anyone to use this software for any purpose,
00015 // including commercial applications, and to alter it and redistribute it
00016 // freely, subject to the following restrictions:
00017 // 
00018 // 1. The origin of this software must not be misrepresented; you must not
00019 // claim that you wrote the original software. If you use this software
00020 // in a product, an acknowledgment in the product documentation would be
00021 // appreciated but is not required.
00022 // 
00023 // 2. Altered source versions must be plainly marked as such, and must not be
00024 // misrepresented as being the original software.
00025 // 
00026 // 3. This notice may not be removed or altered from any source
00027 // distribution.
00028 // 
00029 // 
00030 
00031 
00032 #include <pch.h>
00033 
00034 #include "Emu/AlphaLinux/Alpha64Decoder.h"
00035 
00036 #include "SysDeps/Endian.h"
00037 #include "Emu/Utility/DecoderUtility.h"
00038 
00039 
00040 using namespace std;
00041 using namespace boost;
00042 using namespace Onikiri;
00043 using namespace Onikiri::EmulatorUtility;
00044 using namespace Onikiri::AlphaLinux;
00045 
00046 namespace {
00047     // 
00048     enum InsnType {
00049         UNDEF,              // `C\
00050         MEMORY_ADDR,        // `ョ (AhXvZ)
00051         MEMORY_LOAD,        // `ョ ([h)
00052         MEMORY_STORE,       // `ョ (XgA)
00053         MEMORY_LOAD_FLOAT,  // _`ョ ([h)
00054         MEMORY_STORE_FLOAT, // _`ョ (XgA)
00055         MEMORY_FUNC,        // @\R[hp`ョ (MB)
00056         MEMORY_JMP,         // Wv (JSR)
00057         BRANCH,             // `ョ
00058         BRANCH_FLOAT,       // `ョ (_)
00059         BRANCH_SAVE,        // PC`ョ (BR, BSR)
00060         OPERATION_INT,      // `ョ ()
00061         OPERATION_FLOAT,    // `ョ ()
00062         PAL                 // PALR[h`ョ
00063     };
00064 
00065     const InsnType UND = UNDEF;
00066     const InsnType LDA = MEMORY_ADDR;
00067     const InsnType LD = MEMORY_LOAD;
00068     const InsnType ST = MEMORY_STORE;
00069     const InsnType LDF = MEMORY_LOAD_FLOAT;
00070     const InsnType STF = MEMORY_STORE_FLOAT;
00071     const InsnType MEMF = MEMORY_FUNC;
00072     const InsnType MEMJ = MEMORY_JMP;
00073     const InsnType BR = BRANCH;
00074     const InsnType BRF = BRANCH_FLOAT;
00075     const InsnType BRS = BRANCH_SAVE;
00076     const InsnType OPI = OPERATION_INT;
00077     const InsnType OPF = OPERATION_FLOAT;
00078 
00079     // R[h
00080     InsnType OpCodeToInsnType[64] =
00081     {
00082         // 0x00
00083         PAL , UND , UND , UND , UND , UND , UND , UND ,
00084         // 0x08
00085         LDA , LDA , LD  , LD  , LD  , ST ,  ST ,  ST  , 
00086         // 0x10
00087         OPI , OPI , OPI , OPI , OPF , OPF , OPF , OPF , 
00088         // 0x18
00089         MEMF, UND , MEMJ, UND , OPI , UND , UND , UND , 
00090         // 0x20
00091         LDF , LDF , LDF , LDF , STF , STF , STF , STF , 
00092         // 0x28
00093         LD  , LD  , LD  , LD  , ST  , ST  , ST  , ST  , 
00094         // 0x30
00095         BRS , BRF , BRF , BRF , BRS , BRF , BRF , BRF , 
00096         // 0x38
00097         BR  , BR  , BR  , BR  , BR  , BR  , BR  , BR  , 
00098     };
00099 }
00100 
00101 Alpha64Decoder::DecodedInsn::DecodedInsn()
00102 {
00103     clear();
00104 }
00105 
00106 void Alpha64Decoder::DecodedInsn::clear()
00107 {
00108     CodeWord = 0;
00109 
00110     std::fill(Imm.begin(), Imm.end(), 0);
00111     std::fill(Reg.begin(), Reg.end(), -1);
00112 }
00113 
00114 
00115 Alpha64Decoder::Alpha64Decoder()
00116 {
00117 }
00118 
00119 void Alpha64Decoder::Decode(u32 codeWord, DecodedInsn* out)
00120 {
00121     out->clear();
00122 
00123     u32 opcode = (codeWord >> 26) & 0x3f;
00124     out->CodeWord = codeWord;
00125 
00126     InsnType type = OpCodeToInsnType[opcode];
00127 
00128     switch (type) {
00129     case PAL:
00130         out->Imm[1] = ExtractBits(codeWord, 0, 26);
00131         break;
00132     case UNDEF:
00133         break;
00134     case MEMORY_ADDR:
00135     case MEMORY_LOAD:
00136         out->Imm[0] = ExtractBits<u64>(codeWord, 0, 16, true);
00137         out->Reg[0] = ExtractBits(codeWord, 21, 5);
00138         out->Reg[1] = ExtractBits(codeWord, 16, 5);
00139         break;
00140     case MEMORY_STORE:
00141         out->Imm[0] = ExtractBits<u64>(codeWord, 0, 16, true);
00142         out->Reg[2] = ExtractBits(codeWord, 21, 5);
00143         out->Reg[1] = ExtractBits(codeWord, 16, 5);
00144         break;
00145     case MEMORY_LOAD_FLOAT:
00146         out->Imm[0] = ExtractBits<u64>(codeWord, 0, 16, true);
00147         out->Reg[0] = ExtractBits(codeWord, 21, 5)+32;  // fp register
00148         out->Reg[1] = ExtractBits(codeWord, 16, 5);
00149         break;
00150     case MEMORY_STORE_FLOAT:
00151         out->Imm[0] = ExtractBits<u64>(codeWord, 0, 16, true);
00152         out->Reg[2] = ExtractBits(codeWord, 21, 5)+32;  // fp register
00153         out->Reg[1] = ExtractBits(codeWord, 16, 5);
00154         break;
00155     case MEMORY_FUNC:
00156         out->Imm[1] = ExtractBits(codeWord, 0, 16);
00157         out->Reg[0] = ExtractBits(codeWord, 21, 5);
00158         out->Reg[1] = ExtractBits(codeWord, 16, 5);
00159         break;
00160     case MEMORY_JMP:
00161         out->Imm[0] = ExtractBits(codeWord, 0, 14);
00162         //out->Imm[0] = ExtractBits(codeWord, 14, 2);
00163         out->Reg[1] = ExtractBits(codeWord, 16, 5); // Rb
00164         out->Reg[0] = ExtractBits(codeWord, 21, 5); // Ra
00165         break;
00166     case BRANCH:
00167         out->Imm[0] = ExtractBits<u64>(codeWord, 0, 21, true);
00168         out->Reg[1] = ExtractBits(codeWord, 21, 5);
00169         break;
00170     case BRANCH_FLOAT:
00171         out->Imm[0] = ExtractBits<u64>(codeWord, 0, 21, true);
00172         out->Reg[1] = ExtractBits(codeWord, 21, 5)+32;  // fp register
00173         break;
00174     case BRANCH_SAVE:
00175         out->Imm[0] = ExtractBits<u64>(codeWord, 0, 21, true);
00176         out->Reg[0] = ExtractBits(codeWord, 21, 5);
00177         break;
00178     case OPERATION_INT:
00179         out->Reg[0] = ExtractBits(codeWord, 0, 5);
00180         out->Imm[1] = ExtractBits(codeWord, 5, 7);
00181         if (ExtractBits(codeWord, 12, 1))
00182             out->Imm[0] = ExtractBits(codeWord, 13, 8);
00183         else
00184             out->Reg[2] = ExtractBits(codeWord, 16, 5);
00185         if (ExtractBits(codeWord, 5, 3) == 0 && 
00186             ExtractBits(codeWord, 9, 3) == 7)   // FTOIx
00187             out->Reg[1] = ExtractBits(codeWord, 21, 5) + 32;    // fp register
00188         else
00189             out->Reg[1] = ExtractBits(codeWord, 21, 5);
00190         break;
00191     case OPERATION_FLOAT:
00192         out->Reg[0] = ExtractBits(codeWord, 0, 5) + 32;
00193         out->Imm[1] = ExtractBits(codeWord, 5, 11);
00194         out->Reg[2] = ExtractBits(codeWord, 16, 5) + 32;    // fp register
00195         if(ExtractBits(codeWord, 5, 4) == 4)    // ITOFx
00196             out->Reg[1] = ExtractBits(codeWord, 21, 5); // int register
00197         else
00198             out->Reg[1] = ExtractBits(codeWord, 21, 5) + 32;
00199         break;
00200     default:
00201         ASSERT(0);  // never reached
00202     }
00203 }
00204 

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