diff options
| author | Roman Divacky <rdivacky@FreeBSD.org> | 2010-05-27 15:15:58 +0000 | 
|---|---|---|
| committer | Roman Divacky <rdivacky@FreeBSD.org> | 2010-05-27 15:15:58 +0000 | 
| commit | abdf259d487163e72081a8cf4991b1617206b41e (patch) | |
| tree | 9fad9a5d5dd8c4ff54af48edad9c8cc26dd5fda1 /lib/Target/X86/Disassembler/X86Disassembler.cpp | |
| parent | 59161dfae3225dd9151afbc76ca9074598c0c605 (diff) | |
Notes
Diffstat (limited to 'lib/Target/X86/Disassembler/X86Disassembler.cpp')
| -rw-r--r-- | lib/Target/X86/Disassembler/X86Disassembler.cpp | 61 | 
1 files changed, 56 insertions, 5 deletions
| diff --git a/lib/Target/X86/Disassembler/X86Disassembler.cpp b/lib/Target/X86/Disassembler/X86Disassembler.cpp index 62e7357b8f34..8a5a6308704a 100644 --- a/lib/Target/X86/Disassembler/X86Disassembler.cpp +++ b/lib/Target/X86/Disassembler/X86Disassembler.cpp @@ -155,7 +155,57 @@ static void translateRegister(MCInst &mcInst, Reg reg) {  ///  /// @param mcInst       - The MCInst to append to.  /// @param immediate    - The immediate value to append. -static void translateImmediate(MCInst &mcInst, uint64_t immediate) { +/// @param operand      - The operand, as stored in the descriptor table. +/// @param insn         - The internal instruction. +static void translateImmediate(MCInst &mcInst,  +                               uint64_t immediate,  +                               OperandSpecifier &operand, +                               InternalInstruction &insn) { +  // Sign-extend the immediate if necessary. + +  OperandType type = operand.type; + +  if (type == TYPE_RELv) { +    switch (insn.displacementSize) { +    default: +      break; +    case 8: +      type = TYPE_MOFFS8; +      break; +    case 16: +      type = TYPE_MOFFS16; +      break; +    case 32: +      type = TYPE_MOFFS32; +      break; +    case 64: +      type = TYPE_MOFFS64; +      break; +    } +  } + +  switch (type) { +  case TYPE_MOFFS8: +  case TYPE_REL8: +    if(immediate & 0x80) +      immediate |= ~(0xffull); +    break; +  case TYPE_MOFFS16: +    if(immediate & 0x8000) +      immediate |= ~(0xffffull); +    break; +  case TYPE_MOFFS32: +  case TYPE_REL32: +  case TYPE_REL64: +    if(immediate & 0x80000000) +      immediate |= ~(0xffffffffull); +    break; +  case TYPE_MOFFS64: +  default: +    // operand is 64 bits wide.  Do nothing. +    break; +  } +        mcInst.addOperand(MCOperand::CreateImm(immediate));  } @@ -370,8 +420,7 @@ static bool translateRM(MCInst &mcInst,    case TYPE_XMM64:    case TYPE_XMM128:    case TYPE_DEBUGREG: -  case TYPE_CR32: -  case TYPE_CR64: +  case TYPE_CONTROLREG:      return translateRMRegister(mcInst, insn);    case TYPE_M:    case TYPE_M8: @@ -447,8 +496,10 @@ static bool translateOperand(MCInst &mcInst,    case ENCODING_IO:    case ENCODING_Iv:    case ENCODING_Ia: -    translateImmediate(mcInst,  -                       insn.immediates[insn.numImmediatesTranslated++]); +    translateImmediate(mcInst, +                       insn.immediates[insn.numImmediatesTranslated++], +                       operand, +                       insn);      return false;    case ENCODING_RB:    case ENCODING_RW: | 
