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 #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,
00050 MEMORY_ADDR,
00051 MEMORY_LOAD,
00052 MEMORY_STORE,
00053 MEMORY_LOAD_FLOAT,
00054 MEMORY_STORE_FLOAT,
00055 MEMORY_FUNC,
00056 MEMORY_JMP,
00057 BRANCH,
00058 BRANCH_FLOAT,
00059 BRANCH_SAVE,
00060 OPERATION_INT,
00061 OPERATION_FLOAT,
00062 PAL
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
00080 InsnType OpCodeToInsnType[64] =
00081 {
00082
00083 PAL , UND , UND , UND , UND , UND , UND , UND ,
00084
00085 LDA , LDA , LD , LD , LD , ST , ST , ST ,
00086
00087 OPI , OPI , OPI , OPI , OPF , OPF , OPF , OPF ,
00088
00089 MEMF, UND , MEMJ, UND , OPI , UND , UND , UND ,
00090
00091 LDF , LDF , LDF , LDF , STF , STF , STF , STF ,
00092
00093 LD , LD , LD , LD , ST , ST , ST , ST ,
00094
00095 BRS , BRF , BRF , BRF , BRS , BRF , BRF , BRF ,
00096
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;
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;
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
00163 out->Reg[1] = ExtractBits(codeWord, 16, 5);
00164 out->Reg[0] = ExtractBits(codeWord, 21, 5);
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;
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)
00187 out->Reg[1] = ExtractBits(codeWord, 21, 5) + 32;
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;
00195 if(ExtractBits(codeWord, 5, 4) == 4)
00196 out->Reg[1] = ExtractBits(codeWord, 21, 5);
00197 else
00198 out->Reg[1] = ExtractBits(codeWord, 21, 5) + 32;
00199 break;
00200 default:
00201 ASSERT(0);
00202 }
00203 }
00204