Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

ia64dis.cc

Go to the documentation of this file.
00001 /*
00002  *      HT Editor
00003  *      ia64dis.cc
00004  *
00005  *      Copyright (C) 1999-2002 Sebastian Biallas (sb@web-productions.de)
00006  *
00007  *      This program is free software; you can redistribute it and/or modify
00008  *      it under the terms of the GNU General Public License version 2 as
00009  *      published by the Free Software Foundation.
00010  *
00011  *      This program is distributed in the hope that it will be useful,
00012  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  *      GNU General Public License for more details.
00015  *
00016  *      You should have received a copy of the GNU General Public License
00017  *      along with this program; if not, write to the Free Software
00018  *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
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                         /* extensions in bits 0-5 */
00085                         // FIXME:redundant?
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                 // FIXME: ..
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 /*              if (strcmp(slot->opcode->name, "adds")==0) {
00124                         int as=0;
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                                 // fall-through
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 /*      byte data[] = {0x19, 0x18, 0x00, 0x18, 0x1e, 0x10, 0x00, 0x09, 0x79, 0xb0, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x20};
00412         code = data;*/
00413         cpu_addr = addr;
00414         insn.selected = 0;
00415         if (maxlen < 16) {
00416                 // invalid
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 01101011 11101011 10110111 00000000
00434 00100000 01011111 11111111 11111111
00435 11111111 11111111 11100001 00000000
00436 00011000 01000001 00010000 00000101
00437 
00438 
00439 
00440 
00441 
00442 orig:
00443 00000010 01100000 10000000 00011001
00444 00111111 00100011 00100000 00000010
00445 10000000 00000000 01000010 11000000
00446 00000001 00100000 00000001 10000100
00447 
00448 rev:
00449 10000100 00000001 00100000 00000001
00450 11000000 0.1000010 00000000 10000000
00451 00000010 00100000 00.100011 00111111
00452 00011001 10000000 01100000 000.00010
00453 
00454 10001100111111000110011000000001100000000
00455 10001100111111000110011000000001100000000
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));    // 32 bits
00463                         QWORD_SET_HI(insn.slot[0].data,
00464                                   ((dword)(code[4] >> 5))
00465                                 | (((dword)code[5] & 0x3f) << 3));     // +9 = 41 bits
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));    // 32 bits
00473                         QWORD_SET_HI(insn.slot[1].data,
00474                                   ((dword)(code[9] >> 6))
00475                                 | (((dword)code[10] & 0x7f) << 2));    // +9 = 41 bits
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));   // 32 bits
00483                         QWORD_SET_HI(insn.slot[2].data,
00484                                   ((dword)(code[14] >> 7))
00485                                 | (((dword)code[15]) << 1));           // +9 = 41 bits
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 //      const char *cs_string = get_cs(e_cs_string);
00535         const char *cs_comment = get_cs(e_cs_comment);
00536 
00537         IA64DisInsn *dis_insn = (IA64DisInsn *) disasm_insn;
00538         if (!dis_insn->valid) {
00539 //              is_invalid:
00540 //          assert(dis_insn->size==1);
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 //               if (i+1 != dis_insn->size) is += sprintf(is, "%s, ", cs_symbol);
00546                 }
00547         } else {
00548                 char *is = insnstr;
00549                 IA64SlotDisInsn *slot = &dis_insn->slot[dis_insn->selected];
00550                 is[0] = 0;
00551 //          char c[] = ".#'";
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 //              line += insn.slot[line].next;
00632 //              if (line > 2) line = 0;
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 //              is += ht_snprintf(is, 256, "                   t=%02x(%s) s0=%013Q s1=%013Q s2=%013Q", insn.tmplt_idx, tmplt_str, &insn.slot[0].data, &insn.slot[1].data, &insn.slot[2].data);
00666 /*          for (int i=0; i < dis_insn->size; i++) {
00667                         is += sprintf(is, "%s%02x", cs_number, dis_insn->data[i]);
00668                         if (i==7) is += sprintf(is, "-");
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 

Generated on Fri May 7 21:15:38 2004 by doxygen 1.3.5