00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <string.h>
00022
00023 #include "global.h"
00024 #include "htendian.h"
00025 #include "ia64dis.h"
00026 #include "ia64opc.h"
00027 #include "snprintf.h"
00028
00029 IA64Disassembler::IA64Disassembler()
00030 {
00031 }
00032
00033 IA64Disassembler::~IA64Disassembler()
00034 {
00035 }
00036
00037 bool IA64Disassembler::selectNext(dis_insn *disasm_insn)
00038 {
00039 IA64DisInsn *insn = (IA64DisInsn *)disasm_insn;
00040 if (!insn->valid) return false;
00041 insn->selected += insn->slot[insn->selected].next;
00042 if (insn->selected > 2) {
00043 insn->selected = 0;
00044 return false;
00045 }
00046 return true;
00047 }
00048
00049 qword IA64Disassembler::signExtend(qword a, int length)
00050 {
00051 qword sign = (to_qword(1) << (length-1));
00052 if ((a & sign) != to_qword(0)) {
00053 sign <<= 1;
00054 sign -= to_qword(1);
00055 sign = ~sign;
00056 a |= sign;
00057 }
00058 return a;
00059 }
00060
00061 void IA64Disassembler::decodeSlot(int slot_nb)
00062 {
00063 IA64SlotDisInsn *slot = &insn.slot[slot_nb];
00064 byte role = (insn.tmplt->slot[slot_nb] & 0xf0);
00065 if (role==IA64_INST_ROLE_LONG) {
00066 qword tmp = insn.slot[slot_nb].data;
00067 insn.slot[slot_nb].data = insn.slot[slot_nb+1].data;
00068 insn.slot[slot_nb+1].data = tmp;
00069 slot->next = 2;
00070 } else {
00071 slot->next = 1;
00072 }
00073 role >>= 4;
00074
00075 dword major_opcode = QWORD_GET_LO((slot->data >> 37) & to_qword(0x0f));
00076 IA64DecisionTreeEntry dtree_entry = IA64DecisionTree[major_opcode * IA64_INST_ROLE_COUNT + role];
00077
00078 while (!IA64_DECISION_TREE_LEAF_NODE(dtree_entry)) {
00079 char pos = dtree_entry.pos - 6;
00080 char size = dtree_entry.size;
00081 dword value;
00082
00083 if (pos < 0) {
00084
00085
00086 pos += 6;
00087 value = QWORD_GET_LO(slot->data >> pos) & ((1 << size)-1);
00088 } else {
00089 value = QWORD_GET_LO(slot->data >> (pos+6)) & ((1 << size)-1);
00090 }
00091 word next = dtree_entry.next_node + value;
00092 dtree_entry = IA64DecisionTree[next];
00093 }
00094 word inst_id = dtree_entry.next_node;
00095
00096 if ((inst_id >= IA64_OPCODE_INST_LAST) || inst_id == IA64_OPCODE_ILLOP) {
00097
00098 slot->valid = false;
00099 } else {
00100 slot->valid = true;
00101 slot->opcode = &IA64OpcodeTable[inst_id];
00102 slot->qp = QWORD_GET_LO(slot->data) & 0x3f;
00103 for (int i=0; i<7; i++) slot->op[i].type = IA64_OPERAND_NO;
00104 int dest = 0;
00105 if (slot->opcode->op1.role == IA64_OPROLE_DST) {
00106 if (slot->opcode->op2.role == IA64_OPROLE_SRC) {
00107 dest = 2;
00108 } else {
00109 if (slot->opcode->op3.role == IA64_OPROLE_SRC) {
00110 dest = 3;
00111 } else {
00112 if (slot->opcode->op4.role == IA64_OPROLE_SRC) {
00113 dest = 4;
00114 } else {
00115
00116 }
00117 }
00118 }
00119 }
00120 if (dest) {
00121 slot->op[dest-1].type = IA64_OPERAND_EQUALS;
00122 }
00123
00124
00125
00126 switch (slot->opcode->format) {
00127 case IA64_FORMAT_A1:
00128 slot->op[0].type = IA64_OPERAND_REG;
00129 slot->op[0].reg = QWORD_GET_LO((slot->data >> 6) & to_qword(0x7f));
00130 slot->op[2].type = IA64_OPERAND_REG;
00131 slot->op[2].reg = QWORD_GET_LO((slot->data >> 13) & to_qword(0x7f));
00132 slot->op[3].type = IA64_OPERAND_REG;
00133 slot->op[3].reg = QWORD_GET_LO((slot->data >> 20) & to_qword(0x7f));
00134 if (slot->opcode->op1.type == IA64_OPTYPE_ONE) {
00135 slot->op[4].type = IA64_OPERAND_1;
00136 }
00137 break;
00138 case IA64_FORMAT_A3:
00139 slot->op[0].type = IA64_OPERAND_REG;
00140 slot->op[0].reg = QWORD_GET_LO((slot->data >> 6) & to_qword(0x7f));
00141 slot->op[2].type = IA64_OPERAND_IMM;
00142 slot->op[2].imm = ((slot->data >> 13) & to_qword(0x7f))
00143 |(((slot->data >> 36) & to_qword(1)) << 7);
00144 slot->op[2].imm = signExtend(slot->op[2].imm, 8);
00145 slot->op[3].type = IA64_OPERAND_REG;
00146 slot->op[3].reg = QWORD_GET_LO((slot->data >> 20) & to_qword(0x7f));
00147 break;
00148 case IA64_FORMAT_A4:
00149 slot->op[0].type = IA64_OPERAND_REG;
00150 slot->op[0].reg = QWORD_GET_LO((slot->data >> 6) & to_qword(0x7f));
00151 slot->op[2].type = IA64_OPERAND_IMM;
00152 slot->op[2].imm = ((slot->data >> 13) & to_qword(0x7f))
00153 | (((slot->data >> 27) & to_qword(0x3f)) << 7)
00154 |(((slot->data >> 36) & to_qword(1)) << 13);
00155 slot->op[2].imm = signExtend(slot->op[2].imm, 14);
00156 slot->op[3].type = IA64_OPERAND_REG;
00157 slot->op[3].reg = QWORD_GET_LO((slot->data >> 20) & to_qword(0x7f));
00158 break;
00159 case IA64_FORMAT_A5:
00160 slot->op[0].type = IA64_OPERAND_REG;
00161 slot->op[0].reg = QWORD_GET_LO((slot->data >> 6) & to_qword(0x7f));
00162 slot->op[2].type = IA64_OPERAND_IMM;
00163 slot->op[2].imm = ((slot->data >> 13) & to_qword(0x7f))
00164 | (((slot->data >> 22) & to_qword(0x7fff)) << 7);
00165 slot->op[2].imm = signExtend(slot->op[2].imm, 22);
00166 slot->op[3].type = IA64_OPERAND_REG;
00167 slot->op[3].reg = QWORD_GET_LO((slot->data >> 20) & to_qword(0x3));
00168 break;
00169 case IA64_FORMAT_A6:
00170 case IA64_FORMAT_A7:
00171 slot->op[0].type = IA64_OPERAND_PREG;
00172 slot->op[0].reg = QWORD_GET_LO((slot->data >> 6) & to_qword(0x3f));
00173 slot->op[1].type = IA64_OPERAND_PREG;
00174 slot->op[1].reg = QWORD_GET_LO((slot->data >> 27) & to_qword(0x3f));
00175 slot->op[3].type = IA64_OPERAND_REG;
00176 slot->op[3].reg = QWORD_GET_LO((slot->data >> 13) & to_qword(0x7f));
00177 slot->op[4].type = IA64_OPERAND_REG;
00178 slot->op[4].reg = QWORD_GET_LO((slot->data >> 20) & to_qword(0x7f));
00179 break;
00180 case IA64_FORMAT_A8:
00181 slot->op[0].type = IA64_OPERAND_PREG;
00182 slot->op[0].reg = QWORD_GET_LO((slot->data >> 6) & to_qword(0x3f));
00183 slot->op[1].type = IA64_OPERAND_PREG;
00184 slot->op[1].reg = QWORD_GET_LO((slot->data >> 27) & to_qword(0x3f));
00185 slot->op[3].type = IA64_OPERAND_IMM;
00186 slot->op[3].imm = (slot->data >> 13) & to_qword(0x7f)
00187 |(((slot->data >> 36) & to_qword(1)) << 7);
00188 slot->op[3].imm = signExtend(slot->op[3].imm, 8);
00189 slot->op[4].type = IA64_OPERAND_REG;
00190 slot->op[4].reg = QWORD_GET_LO((slot->data >> 20) & to_qword(0x7f));
00191 break;
00192 case IA64_FORMAT_B1:
00193 case IA64_FORMAT_B2:
00194 slot->op[0].type = IA64_OPERAND_ADDRESS;
00195 slot->op[0].ofs = ((slot->data >> 13) & to_qword((1<<20)-1))
00196 |(((slot->data >> 36) & to_qword(1)) << 20);
00197 slot->op[0].ofs = signExtend(slot->op[0].ofs, 21);
00198 slot->op[0].ofs <<= 4;
00199 slot->op[0].ofs += cpu_addr.flat64.addr;
00200 break;
00201 case IA64_FORMAT_B3:
00202 slot->op[0].type = IA64_OPERAND_BREG;
00203 slot->op[0].reg = QWORD_GET_LO((slot->data >> 6) & to_qword(0x7));
00204 slot->op[2].type = IA64_OPERAND_ADDRESS;
00205 slot->op[2].ofs = ((slot->data >> 13) & to_qword((1<<20)-1))
00206 |(((slot->data >> 36) & to_qword(1)) << 20);
00207 slot->op[2].ofs = signExtend(slot->op[2].ofs, 21);
00208 slot->op[2].ofs <<= 4;
00209 slot->op[2].ofs += cpu_addr.flat64.addr;
00210 break;
00211 case IA64_FORMAT_B4:
00212 slot->op[0].type = IA64_OPERAND_BREG;
00213 slot->op[0].reg = QWORD_GET_LO((slot->data >> 13) & to_qword(0x7));
00214 break;
00215 case IA64_FORMAT_B5:
00216 slot->op[0].type = IA64_OPERAND_BREG;
00217 slot->op[0].reg = QWORD_GET_LO((slot->data >> 6) & to_qword(0x7));
00218 slot->op[2].type = IA64_OPERAND_BREG;
00219 slot->op[2].reg = QWORD_GET_LO((slot->data >> 13) & to_qword(0x7));
00220 break;
00221 case IA64_FORMAT_B9:
00222 case IA64_FORMAT_F15:
00223 case IA64_FORMAT_I19:
00224 case IA64_FORMAT_M37:
00225 slot->op[0].type = IA64_OPERAND_IMM;
00226 slot->op[0].imm = ((slot->data >> 6) & to_qword((1<<20)-1))
00227 |(((slot->data >> 36) & to_qword(1)) << 20);
00228 break;
00229 case IA64_FORMAT_F2:
00230 slot->op[0].type = IA64_OPERAND_FREG;
00231 slot->op[0].reg = QWORD_GET_LO((slot->data >> 6) & to_qword(0x7f));
00232 slot->op[2].type = IA64_OPERAND_FREG;
00233 slot->op[2].reg = QWORD_GET_LO((slot->data >> 20) & to_qword(0x7f));
00234 slot->op[3].type = IA64_OPERAND_FREG;
00235 slot->op[3].reg = QWORD_GET_LO((slot->data >> 27) & to_qword(0x7f));
00236 slot->op[4].type = IA64_OPERAND_FREG;
00237 slot->op[4].reg = QWORD_GET_LO((slot->data >> 13) & to_qword(0x7f));
00238 break;
00239 case IA64_FORMAT_I21:
00240 slot->op[0].type = IA64_OPERAND_BREG;
00241 slot->op[0].reg = QWORD_GET_LO((slot->data >> 6) & to_qword(0x7));
00242 slot->op[2].type = IA64_OPERAND_REG;
00243 slot->op[2].reg = QWORD_GET_LO((slot->data >> 13) & to_qword(0x7f));
00244 slot->op[3].type = IA64_OPERAND_ADDRESS;
00245 slot->op[3].imm = (slot->data >> 24) & to_qword(0x1ff);
00246 slot->op[3].imm = (signExtend(slot->op[3].imm, 9)<<4)+cpu_addr.flat64.addr;
00247 break;
00248 case IA64_FORMAT_I22:
00249 slot->op[0].type = IA64_OPERAND_REG;
00250 slot->op[0].reg = QWORD_GET_LO((slot->data >> 6) & to_qword(0x7f));
00251 slot->op[2].type = IA64_OPERAND_BREG;
00252 slot->op[2].reg = QWORD_GET_LO((slot->data >> 13) & to_qword(0x7));
00253 break;
00254 case IA64_FORMAT_I23:
00255 slot->op[0].type = IA64_OPERAND_PRALL;
00256 slot->op[2].type = IA64_OPERAND_REG;
00257 slot->op[2].reg = QWORD_GET_LO((slot->data >> 13) & to_qword(0x7f));
00258 slot->op[3].type = IA64_OPERAND_IMM;
00259 slot->op[3].imm = (((slot->data >> 6) & to_qword(0x7f)) << 1)
00260 |(((slot->data >> 24) & to_qword(0xff)) << 8)
00261 |(((slot->data >> 36) & to_qword(1)) << 16);
00262 slot->op[3].imm = signExtend(slot->op[3].imm, 17);
00263 break;
00264 case IA64_FORMAT_I24:
00265 slot->op[0].type = IA64_OPERAND_PRROT;
00266 slot->op[2].type = IA64_OPERAND_IMM;
00267 slot->op[2].imm = (((slot->data >> 6) & to_qword(0x7ffffff)) << 16)
00268 |(((slot->data >> 36) & to_qword(1)) << 43);
00269 slot->op[2].imm = signExtend(slot->op[2].imm, 28);
00270 break;
00271 case IA64_FORMAT_I25:
00272 slot->op[0].type = IA64_OPERAND_REG;
00273 slot->op[0].reg = QWORD_GET_LO((slot->data >> 6) & to_qword(0x7f));
00274 if (slot->opcode->op2.type == IA64_OPTYPE_IP) {
00275 slot->op[2].type = IA64_OPERAND_IP;
00276 } else {
00277 slot->op[2].type = IA64_OPERAND_PRALL;
00278 }
00279 break;
00280 case IA64_FORMAT_I26:
00281 case IA64_FORMAT_M29:
00282 slot->op[0].type = IA64_OPERAND_AREG;
00283 slot->op[0].reg = QWORD_GET_LO((slot->data >> 20) & to_qword(0x7f));
00284 slot->op[2].type = IA64_OPERAND_REG;
00285 slot->op[2].reg = QWORD_GET_LO((slot->data >> 13) & to_qword(0x7f));
00286 break;
00287 case IA64_FORMAT_I27:
00288 case IA64_FORMAT_M31:
00289 slot->op[0].type = IA64_OPERAND_REG;
00290 slot->op[0].reg = QWORD_GET_LO((slot->data >> 6) & to_qword(0x7f));
00291 slot->op[2].type = IA64_OPERAND_AREG;
00292 slot->op[2].reg = QWORD_GET_LO((slot->data >> 20) & to_qword(0x7f));
00293 break;
00294 case IA64_FORMAT_I28:
00295 break;
00296 case IA64_FORMAT_I29:
00297 slot->op[0].type = IA64_OPERAND_REG;
00298 slot->op[0].reg = QWORD_GET_LO((slot->data >> 6) & to_qword(0x7f));
00299 slot->op[2].type = IA64_OPERAND_REG;
00300 slot->op[2].reg = QWORD_GET_LO((slot->data >> 20) & to_qword(0x7f));
00301 break;
00302 case IA64_FORMAT_M3:
00303 slot->op[3].type = IA64_OPERAND_IMM;
00304 slot->op[3].imm = ((slot->data >> 13) & to_qword(0x7f))
00305 |(((slot->data >> 27) & to_qword(1))<<7)
00306 |(((slot->data >> 36) & to_qword(1))<<8);
00307 slot->op[3].imm = signExtend(slot->op[3].imm, 9);
00308 goto m1;
00309 case IA64_FORMAT_M2:
00310 slot->op[3].type = IA64_OPERAND_REG;
00311 slot->op[3].reg = QWORD_GET_LO((slot->data >> 13) & to_qword(0x7f));
00312
00313 case IA64_FORMAT_M1:
00314 m1:
00315 slot->op[0].type = IA64_OPERAND_REG;
00316 slot->op[0].reg = QWORD_GET_LO((slot->data >> 6) & to_qword(0x7f));
00317 slot->op[2].type = IA64_OPERAND_MEM_REG;
00318 slot->op[2].reg = QWORD_GET_LO((slot->data >> 20) & to_qword(0x7f));
00319 break;
00320 case IA64_FORMAT_M5:
00321 slot->op[3].type = IA64_OPERAND_IMM;
00322 slot->op[3].imm = ((slot->data >> 6) & to_qword(0x7f))
00323 |(((slot->data >> 27) & to_qword(1))<<7)
00324 |(((slot->data >> 36) & to_qword(1))<<8);
00325 slot->op[3].imm = signExtend(slot->op[3].imm, 9);
00326 goto m4;
00327 case IA64_FORMAT_M4:
00328 m4:
00329 slot->op[0].type = IA64_OPERAND_MEM_REG;
00330 slot->op[0].reg = QWORD_GET_LO((slot->data >> 20) & to_qword(0x7f));
00331 slot->op[2].type = IA64_OPERAND_REG;
00332 slot->op[2].reg = QWORD_GET_LO((slot->data >> 13) & to_qword(0x7f));
00333 break;
00334 case IA64_FORMAT_M18:
00335 slot->op[0].type = IA64_OPERAND_FREG;
00336 slot->op[0].reg = QWORD_GET_LO((slot->data >> 6) & to_qword(0x7f));
00337 slot->op[2].type = IA64_OPERAND_REG;
00338 slot->op[2].reg = QWORD_GET_LO((slot->data >> 13) & to_qword(0x7f));
00339 break;
00340 case IA64_FORMAT_M19:
00341 slot->op[0].type = IA64_OPERAND_REG;
00342 slot->op[0].reg = QWORD_GET_LO((slot->data >> 6) & to_qword(0x7f));
00343 slot->op[2].type = IA64_OPERAND_FREG;
00344 slot->op[2].reg = QWORD_GET_LO((slot->data >> 13) & to_qword(0x7f));
00345 break;
00346 case IA64_FORMAT_M30:
00347 slot->op[0].type = IA64_OPERAND_AREG;
00348 slot->op[0].reg = QWORD_GET_LO((slot->data >> 20) & to_qword(0x7f));
00349 slot->op[2].type = IA64_OPERAND_IMM;
00350 slot->op[2].imm = (slot->data >> 13) & to_qword(0x7f)
00351 |(((slot->data >> 36) & to_qword(1)) << 7);
00352 slot->op[2].imm = signExtend(slot->op[2].imm, 8);
00353 break;
00354 case IA64_FORMAT_M32:
00355 break;
00356 case IA64_FORMAT_M33:
00357 break;
00358 case IA64_FORMAT_M34:
00359 slot->op[0].type = IA64_OPERAND_REG;
00360 slot->op[0].reg = QWORD_GET_LO((slot->data >> 6) & to_qword(0x7f));
00361 slot->op[2].type = IA64_OPERAND_AR_PFS;
00362 slot->op[3].type = IA64_OPERAND_IMM;
00363 slot->op[3].imm = (slot->data >> 20) & to_qword(0x7f);
00364 slot->op[4].type = IA64_OPERAND_IMM;
00365 slot->op[4].imm = to_qword(0);
00366 slot->op[5].type = IA64_OPERAND_IMM;
00367 slot->op[5].imm = (slot->data >> 13) & to_qword(0x7f)-slot->op[3].imm;
00368 slot->op[6].type = IA64_OPERAND_IMM;
00369 slot->op[6].imm = ((slot->data >> 27) & to_qword(0xf))<<3;
00370 break;
00371 case IA64_FORMAT_M35:
00372 break;
00373 case IA64_FORMAT_M36:
00374 break;
00375 case IA64_FORMAT_M42:
00376 slot->op[0].type = IA64_OPERAND_REG_FILE;
00377 slot->op[0].regfile.db = slot->opcode->op1.type - IA64_OPTYPE_PMC;
00378 slot->op[0].regfile.idx = QWORD_GET_LO((slot->data >> 20) & to_qword(0x7f));
00379
00380 slot->op[2].type = IA64_OPERAND_REG;
00381 slot->op[2].reg = QWORD_GET_LO((slot->data >> 13) & to_qword(0x7f));
00382 break;
00383 case IA64_FORMAT_M43:
00384 break;
00385 case IA64_FORMAT_M45:
00386 slot->op[0].type = IA64_OPERAND_REG;
00387 slot->op[0].reg = QWORD_GET_LO((slot->data >> 13) & to_qword(0x7f));
00388 slot->op[1].type = IA64_OPERAND_REG;
00389 slot->op[1].reg = QWORD_GET_LO((slot->data >> 20) & to_qword(0x7f));
00390 break;
00391 case IA64_FORMAT_X2:
00392 slot->op[0].type = IA64_OPERAND_REG;
00393 slot->op[0].reg = QWORD_GET_LO((slot->data >> 6) & to_qword(0x7f));
00394 slot->op[2].type = IA64_OPERAND_IMM;
00395 slot->op[2].imm = ((slot->data >> 13) & to_qword(0x7f))
00396 |(((slot->data >> 27) & to_qword(0x1ff)) << 7)
00397 |(((slot->data >> 22) & to_qword(0x1f)) << 16)
00398 |(((slot->data >> 21) & to_qword(1)) << 21)
00399 |(insn.slot[slot_nb+1].data << 22)
00400 |(((slot->data >> 36) & to_qword(1)) << 63);
00401 break;
00402 default:
00403 break;
00404 }
00405 }
00406
00407 }
00408
00409 dis_insn *IA64Disassembler::decode(byte *code, int maxlen, CPU_ADDR addr)
00410 {
00411
00412
00413 cpu_addr = addr;
00414 insn.selected = 0;
00415 if (maxlen < 16) {
00416
00417 insn.valid = false;
00418 insn.size = maxlen;
00419 if (maxlen) memcpy(insn.data, code, maxlen);
00420 } else {
00421 insn.valid = true;
00422 insn.size = 16;
00423 if (maxlen) memcpy(insn.data, code, maxlen);
00424
00425 insn.tmplt_idx = code[0] & 0x1f;
00426 insn.tmplt = &IA64Templates[insn.tmplt_idx];
00427
00428 if (insn.tmplt->slot[0] == IA64_SLOT_INVALID) {
00429 insn.valid = false;
00430 } else {
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457 QWORD_SET_LO(insn.slot[0].data,
00458 ((dword)(code[0] >> 5))
00459 | (((dword)code[1]) << 3)
00460 | (((dword)code[2]) << 11)
00461 | (((dword)code[3]) << 19)
00462 | (((dword)code[4] & 0x1f) << 27));
00463 QWORD_SET_HI(insn.slot[0].data,
00464 ((dword)(code[4] >> 5))
00465 | (((dword)code[5] & 0x3f) << 3));
00466
00467 QWORD_SET_LO(insn.slot[1].data,
00468 ((dword)(code[5] >> 6))
00469 | (((dword)code[6]) << 2)
00470 | (((dword)code[7]) << 10)
00471 | (((dword)code[8]) << 18)
00472 | (((dword)code[9] & 0x3f) << 26));
00473 QWORD_SET_HI(insn.slot[1].data,
00474 ((dword)(code[9] >> 6))
00475 | (((dword)code[10] & 0x7f) << 2));
00476
00477 QWORD_SET_LO(insn.slot[2].data,
00478 ((dword)(code[10] >> 7))
00479 | (((dword)code[11]) << 1)
00480 | (((dword)code[12]) << 9)
00481 | (((dword)code[13]) << 17)
00482 | (((dword)code[14] & 0x7f) << 25));
00483 QWORD_SET_HI(insn.slot[2].data,
00484 ((dword)(code[14] >> 7))
00485 | (((dword)code[15]) << 1));
00486 }
00487 for (int i=0; i<3; ) {
00488 insn.slot[i].valid = false;
00489 decodeSlot(i);
00490 i += insn.slot[i].next;
00491 }
00492 }
00493 return (dis_insn*)&insn;
00494 }
00495
00496 dis_insn *IA64Disassembler::duplicateInsn(dis_insn *disasm_insn)
00497 {
00498 IA64DisInsn *insn = (IA64DisInsn *)malloc(sizeof (IA64DisInsn));
00499 *insn = *(IA64DisInsn *)disasm_insn;
00500 return insn;
00501 }
00502
00503 void IA64Disassembler::getOpcodeMetrics(int &min_length, int &max_length, int &min_look_ahead, int &avg_look_ahead, int &addr_align)
00504 {
00505 min_length = 16;
00506 max_length = 16;
00507 min_look_ahead = 16;
00508 avg_look_ahead = 16;
00509 addr_align = 16;
00510 }
00511
00512 byte IA64Disassembler::getSize(dis_insn *disasm_insn)
00513 {
00514 return ((IA64DisInsn*)disasm_insn)->size;
00515 }
00516
00517 char *IA64Disassembler::getName()
00518 {
00519 return "IA64/Disassembler";
00520 }
00521
00522 char *IA64Disassembler::str(dis_insn *disasm_insn, int style)
00523 {
00524 return strf(disasm_insn, style, "");
00525 }
00526
00527 char *IA64Disassembler::strf(dis_insn *disasm_insn, int style, char *format)
00528 {
00529 if (style & DIS_STYLE_HIGHLIGHT) enable_highlighting();
00530
00531 const char *cs_default = get_cs(e_cs_default);
00532 const char *cs_number = get_cs(e_cs_number);
00533 const char *cs_symbol = get_cs(e_cs_symbol);
00534
00535 const char *cs_comment = get_cs(e_cs_comment);
00536
00537 IA64DisInsn *dis_insn = (IA64DisInsn *) disasm_insn;
00538 if (!dis_insn->valid) {
00539
00540
00541 char *is = insnstr + sprintf(insnstr, "db ");
00542 for (int i=0; i < dis_insn->size; i++) {
00543 is += sprintf(is, "%s%02x", cs_number, dis_insn->data[i]);
00544 if (i==7) is += sprintf(is, "-");
00545
00546 }
00547 } else {
00548 char *is = insnstr;
00549 IA64SlotDisInsn *slot = &dis_insn->slot[dis_insn->selected];
00550 is[0] = 0;
00551
00552 if (slot->valid) {
00553 char qp[6];
00554 if (slot->qp) {
00555 sprintf(qp, "(p%d)", slot->qp);
00556 } else {
00557 qp[0]=0;
00558 }
00559 is += ht_snprintf(is, 256, "%s%d %5s %s%-20s", cs_comment, dis_insn->selected, qp, cs_default, slot->opcode->name);
00560 for (int i=0; i<7; i++) {
00561 if (slot->op[i].type==IA64_OPERAND_NO) break;
00562 if (slot->op[i].type==IA64_OPERAND_EQUALS) {
00563 is += ht_snprintf(is, 256, " %s= ", cs_symbol);
00564 i++;
00565 goto w;
00566 } else {
00567 if (i!=0) is += ht_snprintf(is, 256, "%s, ", cs_symbol);
00568 }
00569 w:
00570 switch (slot->op[i].type) {
00571 case IA64_OPERAND_1:
00572 is += ht_snprintf(is, 256, "%s1", cs_number);
00573 break;
00574 case IA64_OPERAND_REG:
00575 is += ht_snprintf(is, 256, "%sr%d", cs_default, slot->op[i].reg);
00576 break;
00577 case IA64_OPERAND_BREG:
00578 is += ht_snprintf(is, 256, "%sbr%d", cs_default, slot->op[i].reg);
00579 break;
00580 case IA64_OPERAND_FREG:
00581 is += ht_snprintf(is, 256, "%sf%d", cs_default, slot->op[i].reg);
00582 break;
00583 case IA64_OPERAND_PREG:
00584 is += ht_snprintf(is, 256, "%sp%d", cs_default, slot->op[i].reg);
00585 break;
00586 case IA64_OPERAND_AREG:
00587 is += ht_snprintf(is, 256, "%sar%d", cs_default, slot->op[i].reg);
00588 break;
00589 case IA64_OPERAND_PRALL:
00590 is += ht_snprintf(is, 256, "%spr", cs_default);
00591 break;
00592 case IA64_OPERAND_PRROT:
00593 is += ht_snprintf(is, 256, "%spr.rot", cs_default);
00594 break;
00595 case IA64_OPERAND_AR_PFS:
00596 is += ht_snprintf(is, 256, "%sar.pfs", cs_default);
00597 break;
00598 case IA64_OPERAND_IP:
00599 is += ht_snprintf(is, 256, "%sip", cs_default);
00600 break;
00601 case IA64_OPERAND_MEM_REG:
00602 is += ht_snprintf(is, 256, "%s[%sr%d%s]", cs_symbol, cs_default, slot->op[i].reg, cs_symbol);
00603 break;
00604 case IA64_OPERAND_IMM:
00605 is += ht_snprintf(is, 256, "%s%qx", cs_number, &slot->op[i].imm);
00606 break;
00607 case IA64_OPERAND_ADDRESS: {
00608 CPU_ADDR caddr;
00609 caddr.flat64.addr = slot->op[i].ofs;
00610 int slen;
00611 char *s = (addr_sym_func) ? addr_sym_func(caddr, &slen, addr_sym_func_context) : NULL;
00612 if (s) {
00613 char *p = is;
00614 memmove(p, s, slen);
00615 p[slen] = 0;
00616 is += slen;
00617 } else {
00618 is += ht_snprintf(is, 256, "%s0x%qx", cs_number, &slot->op[i].ofs);
00619 }
00620 break;
00621 }
00622 case IA64_OPERAND_REG_FILE: {
00623 char *dbs[] = {"pmc", "pmd", "pkr", "rr", "ibr", "dbr", "itr", "dtr", "msr"};
00624 is += ht_snprintf(is, 256, "%s%s[%sr%d%s]", dbs[slot->op[i].regfile.db], cs_symbol, cs_default, slot->op[i].regfile.idx, cs_symbol);
00625 }
00626 }
00627 }
00628 } else {
00629 is += ht_snprintf(is, 256, "%s%d %-20s", cs_comment, dis_insn->selected, "invalid");
00630 }
00631
00632
00633
00634
00635 char tmplt_str[100];
00636 tmplt_str[0] = 0;
00637 char *t = tmplt_str;
00638 for (int i=0; i<3; i++) {
00639 switch (insn.tmplt->slot[i] & 0x0f) {
00640 case IA64_SLOT_INVALID:
00641 t+=sprintf(t, "*");
00642 goto e;
00643 break;
00644 case IA64_SLOT_M_UNIT:
00645 t+=sprintf(t, "M");
00646 break;
00647 case IA64_SLOT_I_UNIT:
00648 t+=sprintf(t, "I");
00649 break;
00650 case IA64_SLOT_L_UNIT:
00651 t+=sprintf(t, "L");
00652 break;
00653 case IA64_SLOT_X_UNIT:
00654 t+=sprintf(t, "X");
00655 break;
00656 case IA64_SLOT_F_UNIT:
00657 t+=sprintf(t, "F");
00658 break;
00659 case IA64_SLOT_B_UNIT:
00660 t+=sprintf(t, "B");
00661 break;
00662 }
00663 }
00664 e:;
00665
00666
00667
00668
00669
00670 }
00671
00672 disable_highlighting();
00673 return insnstr;
00674 }
00675
00676 OBJECT_ID IA64Disassembler::object_id() const
00677 {
00678 return ATOM_DISASM_IA64;
00679 }
00680
00681 bool IA64Disassembler::validInsn(dis_insn *disasm_insn)
00682 {
00683 return ((IA64DisInsn *)disasm_insn)->valid;
00684 }
00685
00686
00687