📄 ia64dis.cc
字号:
/* * HT Editor * ia64dis.cc * * Copyright (C) 1999-2002 Sebastian Biallas (sb@biallas.net) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */#include <string.h>#include "data.h"#include "endianess.h"#include "ia64dis.h"#include "ia64opc.h"#include "snprintf.h"bool IA64Disassembler::selectNext(dis_insn *disasm_insn){ IA64DisInsn *insn = (IA64DisInsn *)disasm_insn; if (!insn->valid) return false; insn->selected += insn->slot[insn->selected].next; if (insn->selected > 2) { insn->selected = 0; return false; } return true;}uint64 IA64Disassembler::signExtend(uint64 a, int length){ uint64 sign = 1ULL << (length-1); if (a & sign) { sign <<= 1; sign -= 1; sign = ~sign; a |= sign; } return a;}void IA64Disassembler::decodeSlot(int slot_nb){ IA64SlotDisInsn *slot = &insn.slot[slot_nb]; byte role = insn.tmplt->slot[slot_nb] & 0xf0; if (role == IA64_INST_ROLE_LONG) { uint64 tmp = insn.slot[slot_nb].data; insn.slot[slot_nb].data = insn.slot[slot_nb+1].data; insn.slot[slot_nb+1].data = tmp; slot->next = 2; } else { slot->next = 1; } role >>= 4; uint32 major_opcode = (slot->data >> 37) & 0x0f; IA64DecisionTreeEntry dtree_entry = IA64DecisionTree[major_opcode * IA64_INST_ROLE_COUNT + role]; while (!IA64_DECISION_TREE_LEAF_NODE(dtree_entry)) { char pos = dtree_entry.pos - 6; char size = dtree_entry.size; uint32 value; if (pos < 0) { /* extensions in bits 0-5 */ // FIXME:redundant? pos += 6; value = (slot->data >> pos) & ((1 << size)-1); } else { value = (slot->data >> (pos+6)) & ((1 << size)-1); } uint16 next = dtree_entry.next_node + value; dtree_entry = IA64DecisionTree[next]; } uint16 inst_id = dtree_entry.next_node; if (inst_id >= IA64_OPCODE_INST_LAST || inst_id == IA64_OPCODE_ILLOP) { // FIXME: .. slot->valid = false; } else { slot->valid = true; slot->opcode = &IA64OpcodeTable[inst_id]; slot->qp = slot->data & 0x3f; for (int i=0; i<7; i++) slot->op[i].type = IA64_OPERAND_NO; int dest = 0; if (slot->opcode->op1.role == IA64_OPROLE_DST) { if (slot->opcode->op2.role == IA64_OPROLE_SRC) { dest = 2; } else { if (slot->opcode->op3.role == IA64_OPROLE_SRC) { dest = 3; } else { if (slot->opcode->op4.role == IA64_OPROLE_SRC) { dest = 4; } else { // ... } } } } if (dest) { slot->op[dest-1].type = IA64_OPERAND_EQUALS; }/* if (strcmp(slot->opcode->name, "adds")==0) { int as=0; }*/ switch (slot->opcode->format) { case IA64_FORMAT_A1: slot->op[0].type = IA64_OPERAND_REG; slot->op[0].reg = (slot->data >> 6) & 0x7f; slot->op[2].type = IA64_OPERAND_REG; slot->op[2].reg = (slot->data >> 13) & 0x7f; slot->op[3].type = IA64_OPERAND_REG; slot->op[3].reg = (slot->data >> 20) & 0x7f; if (slot->opcode->op1.type == IA64_OPTYPE_ONE) { slot->op[4].type = IA64_OPERAND_1; } break; case IA64_FORMAT_A3: slot->op[0].type = IA64_OPERAND_REG; slot->op[0].reg = (slot->data >> 6) & 0x7f; slot->op[2].type = IA64_OPERAND_IMM; slot->op[2].imm = ((slot->data >> 13) & 0x7f) | (((slot->data >> 36) & 1) << 7); slot->op[2].imm = signExtend(slot->op[2].imm, 8); slot->op[3].type = IA64_OPERAND_REG; slot->op[3].reg = ((slot->data >> 20) & 0x7f); break; case IA64_FORMAT_A4: slot->op[0].type = IA64_OPERAND_REG; slot->op[0].reg = ((slot->data >> 6) & 0x7f); slot->op[2].type = IA64_OPERAND_IMM; slot->op[2].imm = ((slot->data >> 13) & (0x7f)) | (((slot->data >> 27) & (0x3f)) << 7) |(((slot->data >> 36) & (1)) << 13); slot->op[2].imm = signExtend(slot->op[2].imm, 14); slot->op[3].type = IA64_OPERAND_REG; slot->op[3].reg = ((slot->data >> 20) & (0x7f)); break; case IA64_FORMAT_A5: slot->op[0].type = IA64_OPERAND_REG; slot->op[0].reg = ((slot->data >> 6) & (0x7f)); slot->op[2].type = IA64_OPERAND_IMM; slot->op[2].imm = ((slot->data >> 13) & (0x7f)) | (((slot->data >> 22) & (0x7fff)) << 7); slot->op[2].imm = signExtend(slot->op[2].imm, 22); slot->op[3].type = IA64_OPERAND_REG; slot->op[3].reg = ((slot->data >> 20) & 0x3); break; case IA64_FORMAT_A6: case IA64_FORMAT_A7: slot->op[0].type = IA64_OPERAND_PREG; slot->op[0].reg = ((slot->data >> 6) & 0x3f); slot->op[1].type = IA64_OPERAND_PREG; slot->op[1].reg = ((slot->data >> 27) & 0x3f); slot->op[3].type = IA64_OPERAND_REG; slot->op[3].reg = ((slot->data >> 13) & 0x7f); slot->op[4].type = IA64_OPERAND_REG; slot->op[4].reg = ((slot->data >> 20) & 0x7f); break; case IA64_FORMAT_A8: slot->op[0].type = IA64_OPERAND_PREG; slot->op[0].reg = ((slot->data >> 6) & 0x3f); slot->op[1].type = IA64_OPERAND_PREG; slot->op[1].reg = ((slot->data >> 27) & 0x3f); slot->op[3].type = IA64_OPERAND_IMM; slot->op[3].imm = ((slot->data >> 13) & 0x7f) |(((slot->data >> 36) & (1)) << 7); slot->op[3].imm = signExtend(slot->op[3].imm, 8); slot->op[4].type = IA64_OPERAND_REG; slot->op[4].reg = ((slot->data >> 20) & 0x7f); break; case IA64_FORMAT_B1: case IA64_FORMAT_B2: slot->op[0].type = IA64_OPERAND_ADDRESS; slot->op[0].ofs = ((slot->data >> 13) & ((1<<20)-1)) |(((slot->data >> 36) & (1)) << 20); slot->op[0].ofs = signExtend(slot->op[0].ofs, 21); slot->op[0].ofs <<= 4; slot->op[0].ofs += cpu_addr.flat64.addr; break; case IA64_FORMAT_B3: slot->op[0].type = IA64_OPERAND_BREG; slot->op[0].reg = ((slot->data >> 6) & (0x7)); slot->op[2].type = IA64_OPERAND_ADDRESS; slot->op[2].ofs = ((slot->data >> 13) & ((1<<20)-1)) |(((slot->data >> 36) & (1)) << 20); slot->op[2].ofs = signExtend(slot->op[2].ofs, 21); slot->op[2].ofs <<= 4; slot->op[2].ofs += cpu_addr.flat64.addr; break; case IA64_FORMAT_B4: slot->op[0].type = IA64_OPERAND_BREG; slot->op[0].reg = ((slot->data >> 13) & (0x7)); break; case IA64_FORMAT_B5: slot->op[0].type = IA64_OPERAND_BREG; slot->op[0].reg = ((slot->data >> 6) & (0x7)); slot->op[2].type = IA64_OPERAND_BREG; slot->op[2].reg = ((slot->data >> 13) & (0x7)); break; case IA64_FORMAT_B9: case IA64_FORMAT_F15: case IA64_FORMAT_I19: case IA64_FORMAT_M37: slot->op[0].type = IA64_OPERAND_IMM; slot->op[0].imm = ((slot->data >> 6) & ((1<<20)-1)) |(((slot->data >> 36) & (1)) << 20); break; case IA64_FORMAT_F2: slot->op[0].type = IA64_OPERAND_FREG; slot->op[0].reg = ((slot->data >> 6) & (0x7f)); slot->op[2].type = IA64_OPERAND_FREG; slot->op[2].reg = ((slot->data >> 20) & (0x7f)); slot->op[3].type = IA64_OPERAND_FREG; slot->op[3].reg = ((slot->data >> 27) & (0x7f)); slot->op[4].type = IA64_OPERAND_FREG; slot->op[4].reg = ((slot->data >> 13) & (0x7f)); break; case IA64_FORMAT_I21: slot->op[0].type = IA64_OPERAND_BREG; slot->op[0].reg = ((slot->data >> 6) & (0x7)); slot->op[2].type = IA64_OPERAND_REG; slot->op[2].reg = ((slot->data >> 13) & (0x7f)); slot->op[3].type = IA64_OPERAND_ADDRESS; slot->op[3].imm = (slot->data >> 24) & (0x1ff); slot->op[3].imm = (signExtend(slot->op[3].imm, 9)<<4)+cpu_addr.flat64.addr; break; case IA64_FORMAT_I22: slot->op[0].type = IA64_OPERAND_REG; slot->op[0].reg = ((slot->data >> 6) & (0x7f)); slot->op[2].type = IA64_OPERAND_BREG; slot->op[2].reg = ((slot->data >> 13) & (0x7)); break; case IA64_FORMAT_I23: slot->op[0].type = IA64_OPERAND_PRALL; slot->op[2].type = IA64_OPERAND_REG; slot->op[2].reg = ((slot->data >> 13) & (0x7f)); slot->op[3].type = IA64_OPERAND_IMM; slot->op[3].imm = (((slot->data >> 6) & (0x7f)) << 1) |(((slot->data >> 24) & (0xff)) << 8) |(((slot->data >> 36) & (1)) << 16); slot->op[3].imm = signExtend(slot->op[3].imm, 17); break; case IA64_FORMAT_I24: slot->op[0].type = IA64_OPERAND_PRROT; slot->op[2].type = IA64_OPERAND_IMM; slot->op[2].imm = (((slot->data >> 6) & (0x7ffffff)) << 16) |(((slot->data >> 36) & (1)) << 43); slot->op[2].imm = signExtend(slot->op[2].imm, 28); break; case IA64_FORMAT_I25: slot->op[0].type = IA64_OPERAND_REG; slot->op[0].reg = ((slot->data >> 6) & (0x7f)); if (slot->opcode->op2.type == IA64_OPTYPE_IP) { slot->op[2].type = IA64_OPERAND_IP; } else { slot->op[2].type = IA64_OPERAND_PRALL; } break; case IA64_FORMAT_I26: case IA64_FORMAT_M29: slot->op[0].type = IA64_OPERAND_AREG; slot->op[0].reg = ((slot->data >> 20) & (0x7f)); slot->op[2].type = IA64_OPERAND_REG; slot->op[2].reg = ((slot->data >> 13) & (0x7f)); break; case IA64_FORMAT_I27: case IA64_FORMAT_M31: slot->op[0].type = IA64_OPERAND_REG; slot->op[0].reg = ((slot->data >> 6) & (0x7f)); slot->op[2].type = IA64_OPERAND_AREG; slot->op[2].reg = ((slot->data >> 20) & (0x7f)); break; case IA64_FORMAT_I28: break; case IA64_FORMAT_I29: slot->op[0].type = IA64_OPERAND_REG; slot->op[0].reg = ((slot->data >> 6) & (0x7f)); slot->op[2].type = IA64_OPERAND_REG; slot->op[2].reg = ((slot->data >> 20) & (0x7f)); break; case IA64_FORMAT_M3: slot->op[3].type = IA64_OPERAND_IMM; slot->op[3].imm = ((slot->data >> 13) & (0x7f)) |(((slot->data >> 27) & (1))<<7) |(((slot->data >> 36) & (1))<<8); slot->op[3].imm = signExtend(slot->op[3].imm, 9); goto m1; case IA64_FORMAT_M2: slot->op[3].type = IA64_OPERAND_REG; slot->op[3].reg = ((slot->data >> 13) & (0x7f)); // fall-through case IA64_FORMAT_M1: m1: slot->op[0].type = IA64_OPERAND_REG; slot->op[0].reg = ((slot->data >> 6) & (0x7f)); slot->op[2].type = IA64_OPERAND_MEM_REG; slot->op[2].reg = ((slot->data >> 20) & (0x7f)); break; case IA64_FORMAT_M5: slot->op[3].type = IA64_OPERAND_IMM; slot->op[3].imm = ((slot->data >> 6) & (0x7f)) |(((slot->data >> 27) & (1))<<7) |(((slot->data >> 36) & (1))<<8); slot->op[3].imm = signExtend(slot->op[3].imm, 9); goto m4; case IA64_FORMAT_M4: m4: slot->op[0].type = IA64_OPERAND_MEM_REG;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -