// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include "vm/disassembler.h"

#include "vm/globals.h"  // Needed here to get TARGET_ARCH_MIPS.
#if defined(TARGET_ARCH_MIPS)
#include "platform/assert.h"

namespace dart {

class MIPSDecoder : public ValueObject {
 public:
  MIPSDecoder(char* buffer, size_t buffer_size)
      : buffer_(buffer),
        buffer_size_(buffer_size),
        buffer_pos_(0) {
    buffer_[buffer_pos_] = '\0';
  }

  ~MIPSDecoder() {}

  // Writes one disassembled instruction into 'buffer' (0-terminated).
  // Returns true if the instruction was successfully decoded, false otherwise.
  void InstructionDecode(Instr* instr);

 private:
  // Bottleneck functions to print into the out_buffer.
  void Print(const char* str);

  // Printing of common values.
  void PrintRegister(Register reg);

  int FormatRegister(Instr* instr, const char* format);
  int FormatOption(Instr* instr, const char* format);
  void Format(Instr* instr, const char* format);
  void Unknown(Instr* instr);

  void DecodeSpecial(Instr* instr);
  void DecodeSpecial2(Instr* instr);
  void DecodeRegImm(Instr* instr);

  // Convenience functions.
  char* get_buffer() const { return buffer_; }
  char* current_position_in_buffer() { return buffer_ + buffer_pos_; }
  size_t remaining_size_in_buffer() { return buffer_size_ - buffer_pos_; }

  char* buffer_;  // Decode instructions into this buffer.
  size_t buffer_size_;  // The size of the character buffer.
  size_t buffer_pos_;  // Current character position in buffer.

  DISALLOW_ALLOCATION();
  DISALLOW_COPY_AND_ASSIGN(MIPSDecoder);
};


// Support for assertions in the MIPSDecoder formatting functions.
#define STRING_STARTS_WITH(string, compare_string) \
  (strncmp(string, compare_string, strlen(compare_string)) == 0)


// Append the str to the output buffer.
void MIPSDecoder::Print(const char* str) {
  char cur = *str++;
  while (cur != '\0' && (buffer_pos_ < (buffer_size_ - 1))) {
    buffer_[buffer_pos_++] = cur;
    cur = *str++;
  }
  buffer_[buffer_pos_] = '\0';
}


static const char* reg_names[kNumberOfCpuRegisters] = {
  "r0" , "r1" , "r2" , "r3" , "r4" , "r5" , "r6" , "r7" ,
  "r8" , "r9" , "r10", "r11", "r12", "r13", "r14", "r15",
  "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
  "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
};


void MIPSDecoder::PrintRegister(Register reg) {
  ASSERT(0 <= reg);
  ASSERT(reg < kNumberOfCpuRegisters);
  Print(reg_names[reg]);
}


// Handle all register based formatting in these functions to reduce the
// complexity of FormatOption.
int MIPSDecoder::FormatRegister(Instr* instr, const char* format) {
  ASSERT(format[0] == 'r');
  switch (format[1]) {
    case 's': {  // 'rs: Rs register
      PrintRegister(instr->RsField());
      return 2;
    }
    case 't': {  // 'rt: Rt register
      PrintRegister(instr->RtField());
      return 2;
    }
    case 'd': {  // 'rd: Rd register
      PrintRegister(instr->RdField());
      return 2;
    }
  }
  UNREACHABLE();
  return -1;
}


// FormatOption takes a formatting string and interprets it based on
// the current instructions. The format string points to the first
// character of the option string (the option escape has already been
// consumed by the caller.)  FormatOption returns the number of
// characters that were consumed from the formatting string.
int MIPSDecoder::FormatOption(Instr* instr, const char* format) {
  switch (format[0]) {
    case 'c': {
      ASSERT(STRING_STARTS_WITH(format, "code"));
      buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
                                remaining_size_in_buffer(),
                                "%d", instr->BreakCodeField());
      return 4;
    }
    case 'h': {
      ASSERT(STRING_STARTS_WITH(format, "hint"));
      if (instr->SaField() == 0x10) {
        // The high bit of the SA field is the only one that means something for
        // JALR and JR. TODO(zra): Fill in the other cases for PREF if needed.
        buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
                                   remaining_size_in_buffer(),
                                   ".hb");
      } else if (instr->SaField() != 0) {
        buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
                           remaining_size_in_buffer(),
                           ".unknown");
      }
      return 4;
    }
    case 'd': {
      ASSERT(STRING_STARTS_WITH(format, "dest"));
      int off = instr->SImmField() << 2;
      uword destination = reinterpret_cast<uword>(instr) + off;
      buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
                                 remaining_size_in_buffer(),
                                 "%#"Px"",
                                 destination);
      return 4;
    }
    case 'i': {
      ASSERT(STRING_STARTS_WITH(format, "imm"));
      if (format[3] == 'u') {
        int32_t imm = instr->UImmField();
        buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
                                   remaining_size_in_buffer(),
                                   "0x%x",
                                   imm);
      } else {
        ASSERT(STRING_STARTS_WITH(format, "imms"));
        int32_t imm = instr->SImmField();
        buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
                                   remaining_size_in_buffer(),
                                   "%d",
                                   imm);
      }
      return 4;
    }
    case 'r': {
      return FormatRegister(instr, format);
    }
    case 's': {
      ASSERT(STRING_STARTS_WITH(format, "sa"));
      buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
                                 remaining_size_in_buffer(),
                                 "%d",
                                 instr->SaField());
      return 2;
    }
    default: {
      UNREACHABLE();
    }
  }
  UNREACHABLE();
  return -1;
}


// Format takes a formatting string for a whole instruction and prints it into
// the output buffer. All escaped options are handed to FormatOption to be
// parsed further.
void MIPSDecoder::Format(Instr* instr, const char* format) {
  char cur = *format++;
  while ((cur != 0) && (buffer_pos_ < (buffer_size_ - 1))) {
    if (cur == '\'') {  // Single quote is used as the formatting escape.
      format += FormatOption(instr, format);
    } else {
      buffer_[buffer_pos_++] = cur;
    }
    cur = *format++;
  }
  buffer_[buffer_pos_]  = '\0';
}


// For currently unimplemented decodings the disassembler calls Unknown(instr)
// which will just print "unknown" of the instruction bits.
void MIPSDecoder::Unknown(Instr* instr) {
  Format(instr, "unknown");
}


void MIPSDecoder::DecodeSpecial(Instr* instr) {
  ASSERT(instr->OpcodeField() == SPECIAL);
  switch (instr->FunctionField()) {
    case ADDU: {
      Format(instr, "addu 'rd, 'rs, 'rt");
      break;
    }
    case AND: {
      Format(instr, "and 'rd, 'rs, 'rt");
      break;
    }
    case BREAK: {
      Format(instr, "break 'code");
      break;
    }
    case DIV: {
      Format(instr, "div 'rs, 'rt");
      break;
    }
    case DIVU: {
      Format(instr, "divu 'rs, 'rt");
      break;
    }
    case JALR: {
      Format(instr, "jalr'hint 'rd, 'rs");
      break;
    }
    case JR: {
      Format(instr, "jr'hint 'rs");
      break;
    }
    case MFHI: {
      Format(instr, "mfhi 'rd");
      break;
    }
    case MFLO: {
      Format(instr, "mflo 'rd");
      break;
    }
    case MOVN: {
      Format(instr, "movn 'rd, 'rs, 'rt");
      break;
    }
    case MOVZ: {
      Format(instr, "movz 'rd, 'rs, 'rt");
      break;
    }
    case MULT: {
      Format(instr, "mult 'rs, 'rt");
      break;
    }
    case MULTU: {
      Format(instr, "multu 'rs, 'rt");
      break;
    }
    case NOR: {
      Format(instr, "nor 'rd, 'rs, 'rt");
      break;
    }
    case OR: {
      if (instr->RsField() == 0 && instr->RtField() == 0) {
        Format(instr, "mov 'rd, 0");
      } else if (instr->RsField() == R0) {
        Format(instr, "mov 'rd, 'rt");
      } else if (instr->RtField() == R0) {
        Format(instr, "mov 'rd, 'rs");
      } else {
        Format(instr, "or 'rd, 'rs, 'rt");
      }
      break;
    }
    case SLL: {
      if ((instr->RdField() == R0) &&
          (instr->RtField() == R0) &&
          (instr->SaField() == 0)) {
        Format(instr, "nop");
      } else {
        Format(instr, "sll 'rd, 'rt, 'sa");
      }
      break;
    }
    case SLLV: {
      Format(instr, "sllv 'rd, 'rt, 'rs");
      break;
    }
    case SLT: {
      Format(instr, "slt 'rd, 'rs, 'rt");
      break;
    }
    case SLTU: {
      Format(instr, "sltu 'rd, 'rs, 'rt");
      break;
    }
    case SRA: {
      if (instr->RsField() == 0) {
        Format(instr, "sra 'rd, 'rt, 'sa");
      } else {
        Unknown(instr);
      }
      break;
    }
    case SRAV: {
      Format(instr, "srav 'rd, 'rt, 'rs");
      break;
    }
    case SRL: {
      if (instr->RsField() == 0) {
        Format(instr, "srl 'rd, 'rt, 'sa");
      } else {
        Unknown(instr);
      }
      break;
    }
    case SRLV: {
      if (instr->SaField() == 0) {
        Format(instr, "srlv 'rd, 'rt, 'rs");
      } else {
        Unknown(instr);
      }
      break;
    }
    case SUB: {
      Format(instr, "sub 'rd, 'rs, 'rt");
      break;
    }
    case SUBU: {
      Format(instr, "subu 'rd, 'rs, 'rt");
      break;
    }
    case XOR: {
      Format(instr, "xor 'rd, 'rs, 'rt");
      break;
    }
    default: {
      Unknown(instr);
      break;
    }
  }
}


void MIPSDecoder::DecodeSpecial2(Instr* instr) {
  ASSERT(instr->OpcodeField() == SPECIAL2);
  switch (instr->FunctionField()) {
    case CLO: {
      Format(instr, "clo 'rd, 'rs");
      break;
    }
    case CLZ: {
      Format(instr, "clz 'rd, 'rs");
      break;
    }
    default: {
      Unknown(instr);
      break;
    }
  }
}


void MIPSDecoder::DecodeRegImm(Instr* instr) {
  ASSERT(instr->OpcodeField() == REGIMM);
  switch (instr->RegImmFnField()) {
    case BGEZ: {
      Format(instr, "bgez 'rs, 'dest");
      break;
    }
    case BGEZL: {
      Format(instr, "bgezl 'rs, 'dest");
      break;
    }
    case BLTZ: {
      Format(instr, "bltz 'rs, 'dest");
      break;
    }
    case BLTZL: {
      Format(instr, "bltzl 'rs, 'dest");
      break;
    }
    default: {
      Unknown(instr);
      break;
    }
  }
}


void MIPSDecoder::InstructionDecode(Instr* instr) {
  switch (instr->OpcodeField()) {
    case SPECIAL: {
      DecodeSpecial(instr);
      break;
    }
    case SPECIAL2: {
      DecodeSpecial2(instr);
      break;
    }
    case REGIMM: {
      DecodeRegImm(instr);
      break;
    }
    case ADDIU: {
      Format(instr, "addiu 'rt, 'rs, 'imms");
      break;
    }
    case ANDI: {
      Format(instr, "andi 'rt, 'rs, 'immu");
      break;
    }
    case BEQ: {
      Format(instr, "beq 'rs, 'rt, 'dest");
      break;
    }
    case BEQL: {
      Format(instr, "beql 'rs, 'rt, 'dest");
      break;
    }
    case BGTZ: {
      Format(instr, "bgtz 'rs, 'dest");
      break;
    }
    case BGTZL: {
      Format(instr, "bgtzl 'rs, 'dest");
      break;
    }
    case BLEZ: {
      Format(instr, "blez 'rs, 'dest");
      break;
    }
    case BLEZL: {
      Format(instr, "blezl 'rs, 'dest");
      break;
    }
    case BNE: {
      Format(instr, "bne 'rs, 'rt, 'dest");
      break;
    }
    case BNEL: {
      Format(instr, "bnel 'rs, 'rt, 'dest");
      break;
    }
    case LB: {
      Format(instr, "lb 'rt, 'imms('rs)");
      break;
    }
    case LBU: {
      Format(instr, "lbu 'rt, 'imms('rs)");
      break;
    }
    case LH: {
      Format(instr, "lh 'rt, 'imms('rs)");
      break;
    }
    case LUI: {
      Format(instr, "lui 'rt, 'immu");
      break;
    }
    case LW: {
      Format(instr, "lw 'rt, 'imms('rs)");
      break;
    }
    case ORI: {
      Format(instr, "ori 'rt, 'rs, 'immu");
      break;
    }
    case SB: {
      Format(instr, "sb 'rt, 'imms('rs)");
      break;
    }
    case SH: {
      Format(instr, "sh 'rt, 'imms('rs)");
      break;
    }
    case SW: {
      Format(instr, "sw 'rt, 'imms('rs)");
      break;
    }
    default: {
      Unknown(instr);
      break;
    }
  }
}


void Disassembler::DecodeInstruction(char* hex_buffer, intptr_t hex_size,
                                     char* human_buffer, intptr_t human_size,
                                     int* out_instr_len, uword pc) {
  MIPSDecoder decoder(human_buffer, human_size);
  Instr* instr = Instr::At(pc);
  decoder.InstructionDecode(instr);
  OS::SNPrint(hex_buffer, hex_size, "%08x", instr->InstructionBits());
  if (out_instr_len) {
    *out_instr_len = Instr::kInstrSize;
  }
}


void Disassembler::Disassemble(uword start,
                               uword end,
                               DisassemblyFormatter* formatter,
                               const Code::Comments& comments) {
  ASSERT(formatter != NULL);
  char hex_buffer[kHexadecimalBufferSize];  // Instruction in hexadecimal form.
  char human_buffer[kUserReadableBufferSize];  // Human-readable instruction.
  uword pc = start;
  intptr_t comment_finger = 0;
  while (pc < end) {
    const intptr_t offset = pc - start;
    while (comment_finger < comments.Length() &&
           comments.PCOffsetAt(comment_finger) <= offset) {
      formatter->Print(
          "        ;; %s\n",
          String::Handle(comments.CommentAt(comment_finger)).ToCString());
      comment_finger++;
    }
    int instruction_length;
    DecodeInstruction(hex_buffer, sizeof(hex_buffer),
                      human_buffer, sizeof(human_buffer),
                      &instruction_length, pc);

    formatter->ConsumeInstruction(hex_buffer,
                                  sizeof(hex_buffer),
                                  human_buffer,
                                  sizeof(human_buffer),
                                  pc);
    pc += instruction_length;
  }

  return;
}

}  // namespace dart

#endif  // defined TARGET_ARCH_MIPS
