📄 arm-dis.c
字号:
case 'm': { int started = 0; int reg; func (stream, "{"); for (reg = 0; reg < 16; reg++) if ((given & (1 << reg)) != 0) { if (started) func (stream, ", "); started = 1; func (stream, "%s", arm_regnames[reg]); } func (stream, "}"); } break; case 'o': if ((given & 0x02000000) != 0) { int rotate = (given & 0xf00) >> 7; int immed = (given & 0xff); immed = (((immed << (32 - rotate)) | (immed >> rotate)) & 0xffffffff); func (stream, "#%d\t; 0x%x", immed, immed); } else arm_decode_shift (given, func, stream); break; case 'p': if ((given & 0x0000f000) == 0x0000f000) func (stream, "p"); break; case 't': if ((given & 0x01200000) == 0x00200000) func (stream, "t"); break; case 'A': func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]); if ((given & 0x01000000) != 0) { int offset = given & 0xff; if (offset) func (stream, ", %s#%d]%s", ((given & 0x00800000) == 0 ? "-" : ""), offset * 4, ((given & 0x00200000) != 0 ? "!" : "")); else func (stream, "]"); } else { int offset = given & 0xff; if (offset) func (stream, "], %s#%d", ((given & 0x00800000) == 0 ? "-" : ""), offset * 4); else func (stream, "]"); } break; case 'B': /* Print ARM V5 BLX(1) address: pc+25 bits. */ { bfd_vma address; bfd_vma offset = 0; if (given & 0x00800000) /* Is signed, hi bits should be ones. */ offset = (-1) ^ 0x00ffffff; /* Offset is (SignExtend(offset field)<<2). */ offset += given & 0x00ffffff; offset <<= 2; address = offset + pc + 8; if (given & 0x01000000) /* H bit allows addressing to 2-byte boundaries. */ address += 2; info->print_address_func (address, info); } break; case 'I': /* Print a Cirrus/DSP shift immediate. */ /* Immediates are 7bit signed ints with bits 0..3 in bits 0..3 of opcode and bits 4..6 in bits 5..7 of opcode. */ { int imm; imm = (given & 0xf) | ((given & 0xe0) >> 1); /* Is ``imm'' a negative number? */ if (imm & 0x40) imm |= (-1 << 7); func (stream, "%d", imm); } break; case 'C': func (stream, "_"); if (given & 0x80000) func (stream, "f"); if (given & 0x40000) func (stream, "s"); if (given & 0x20000) func (stream, "x"); if (given & 0x10000) func (stream, "c"); break; case 'F': switch (given & 0x00408000) { case 0: func (stream, "4"); break; case 0x8000: func (stream, "1"); break; case 0x00400000: func (stream, "2"); break; default: func (stream, "3"); } break; case 'P': switch (given & 0x00080080) { case 0: func (stream, "s"); break; case 0x80: func (stream, "d"); break; case 0x00080000: func (stream, "e"); break; default: func (stream, _("<illegal precision>")); break; } break; case 'Q': switch (given & 0x00408000) { case 0: func (stream, "s"); break; case 0x8000: func (stream, "d"); break; case 0x00400000: func (stream, "e"); break; default: func (stream, "p"); break; } break; case 'R': switch (given & 0x60) { case 0: break; case 0x20: func (stream, "p"); break; case 0x40: func (stream, "m"); break; default: func (stream, "z"); break; } break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': { int bitstart = *c++ - '0'; int bitend = 0; while (*c >= '0' && *c <= '9') bitstart = (bitstart * 10) + *c++ - '0'; switch (*c) { case '-': c++; while (*c >= '0' && *c <= '9') bitend = (bitend * 10) + *c++ - '0'; if (!bitend) abort (); switch (*c) { case 'r': { long reg; reg = given >> bitstart; reg &= (2 << (bitend - bitstart)) - 1; func (stream, "%s", arm_regnames[reg]); } break; case 'd': { long reg; reg = given >> bitstart; reg &= (2 << (bitend - bitstart)) - 1; func (stream, "%d", reg); } break; case 'x': { long reg; reg = given >> bitstart; reg &= (2 << (bitend - bitstart)) - 1; func (stream, "0x%08x", reg); /* Some SWI instructions have special meanings. */ if ((given & 0x0fffffff) == 0x0FF00000) func (stream, "\t; IMB"); else if ((given & 0x0fffffff) == 0x0FF00001) func (stream, "\t; IMBRange"); } break; case 'X': { long reg; reg = given >> bitstart; reg &= (2 << (bitend - bitstart)) - 1; func (stream, "%01x", reg & 0xf); } break; case 'f': { long reg; reg = given >> bitstart; reg &= (2 << (bitend - bitstart)) - 1; if (reg > 7) func (stream, "#%s", arm_fp_const[reg & 7]); else func (stream, "f%d", reg); } break; default: abort (); } break; case 'y': case 'z': { int single = *c == 'y'; int regno; switch (bitstart) { case 4: /* Sm pair */ func (stream, "{"); /* Fall through. */ case 0: /* Sm, Dm */ regno = given & 0x0000000f; if (single) { regno <<= 1; regno += (given >> 5) & 1; } break; case 1: /* Sd, Dd */ regno = (given >> 12) & 0x0000000f; if (single) { regno <<= 1; regno += (given >> 22) & 1; } break; case 2: /* Sn, Dn */ regno = (given >> 16) & 0x0000000f; if (single) { regno <<= 1; regno += (given >> 7) & 1; } break; case 3: /* List */ func (stream, "{"); regno = (given >> 12) & 0x0000000f; if (single) { regno <<= 1; regno += (given >> 22) & 1; } break; default: abort (); } func (stream, "%c%d", single ? 's' : 'd', regno); if (bitstart == 3) { int count = given & 0xff; if (single == 0) count >>= 1; if (--count) { func (stream, "-%c%d", single ? 's' : 'd', regno + count); } func (stream, "}"); } else if (bitstart == 4) func (stream, ", %c%d}", single ? 's' : 'd', regno + 1); break; } case '`': c++; if ((given & (1 << bitstart)) == 0) func (stream, "%c", *c); break; case '\'': c++; if ((given & (1 << bitstart)) != 0) func (stream, "%c", *c); break; case '?': ++c; if ((given & (1 << bitstart)) != 0) func (stream, "%c", *c++); else func (stream, "%c", *++c); break; default: abort (); } break; default: abort (); } } } else func (stream, "%c", *c); } return 4; } } abort ();}/* Print one instruction from PC on INFO->STREAM. Return the size of the instruction. */static intprint_insn_thumb (pc, info, given) bfd_vma pc; struct disassemble_info * info; long given;{ struct thumb_opcode * insn; void * stream = info->stream; fprintf_ftype func = info->fprintf_func; for (insn = thumb_opcodes; insn->assembler; insn++) { if ((given & insn->mask) == insn->value) { char * c = insn->assembler; /* Special processing for Thumb 2 instruction BL sequence: */ if (!*c) /* Check for empty (not NULL) assembler string. */ { long offset; info->bytes_per_chunk = 4; info->bytes_per_line = 4; offset = BDISP23 (given); offset = offset * 2 + pc + 4; if ((given & 0x10000000) == 0) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -