// File: /workspace/github_cpp_makefile_star2_O2/daniel5151[P]mips241/src/disasm.cc
// Function: MIPS::disasm[abi:cxx11](unsigned int)
std::string MIPS::disasm(uint32_t word) {
  std::stringstream instr_ss;

  uint8_t  $s, $t, $d;

  int32_t imm;
  uint16_t imm_u;

  $s = (word >> 21) & 0x1F;
  $t = (word >> 16) & 0x1F;
  $d = (word >> 11) & 0x1F;

  imm_u = (word & 0xFFFF);

  bool isNeg = imm_u & 0x8000;
  if (isNeg) {
    imm_u -= 1;
    imm_u = ~imm_u;
    imm = - ((int32_t)imm_u);
  } else {
    imm = imm_u;
  }

  bool hasImmediateValue = (word >> 26) != 0;
  uint32_t opcode = (hasImmediateValue)
    ? word & 0xFC000000   // Mask off all register identifiers + immediate bits
    : word & 0x0000003F;  // Mask off all register identifiers

  switch (opcode) {
      case OP_MULT:
      case OP_MULTU:
      case OP_DIV:
      case OP_DIVU:
        // 2 src
        instr_ss
          << opcode2str(opcode) << " "
          << "$" << (int)$s
          << ", "
          << "$" << (int)$t;
        break;
      case OP_BEQ:
      case OP_BNE:
        // 2 src + immediate
        instr_ss
          << opcode2str(opcode) << " "
          << "$" << (int)$s
          << ", "
          << "$" << (int)$t
          << ", "
          << imm;
        break;

      case OP_LW:
        // 1 source + immediate + 1 dst
        instr_ss
          << opcode2str(opcode) << " "
          << "$" << (int)$t
          << ", "
          << imm
          << "("
          << "$" << (int)$s
          << ")";
        break;
      case OP_SW:
        // 2 source + immediate
        instr_ss
          << opcode2str(opcode) << " "
          << "$" << (int)$t
          << ", "
          << imm
          << "("
          << "$" << (int)$s
          << ")";
        break;

      case OP_ADD:
      case OP_SUB:
      case OP_SLT:
      case OP_SLTU:
        // 2 sources, 1 dst
        instr_ss
          << opcode2str(opcode) << " "
          << "$" << (int)$d
          << ", "
          << "$" << (int)$s
          << ", "
          << "$" << (int)$t;
        break;

      case OP_MFHI:
      case OP_MFLO:
      case OP_LIS:
        // 1 dst
        instr_ss
          << opcode2str(opcode) << " "
          << "$" << (int)$d;
        break;
      case OP_JALR:
      case OP_JR:
        // 1 src
        instr_ss
          << opcode2str(opcode) << " "
          << "$" << (int)$s;
        break;
      default:
        instr_ss
          << ".word "
          << COUTHEX( word );
  }

  return instr_ss.str();
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x1a8, %rsp            # imm = 0x1A8
movl %esi, %r13d
movq %rdi, %rbx
leaq 0x20(%rsp), %rdi
callq 0x2170
movl %r13d, %ebp
shrl $0x15, %ebp
andl $0x1f, %ebp
movl %r13d, %r14d
shrl $0x10, %r14d
andl $0x1f, %r14d
movl %r13d, %r12d
shrl $0xb, %r12d
andl $0x1f, %r12d
movl %r13d, %eax
negl %eax
movzwl %ax, %eax
negl %eax
movl %r13d, %r15d
andl $0x7fff, %r15d          # imm = 0x7FFF
testw %r13w, %r13w
cmovsl %eax, %r15d
cmpl $0x4000000, %r13d       # imm = 0x4000000
pushq $0x3f
popq %rax
movl $0xfc000000, %esi       # imm = 0xFC000000
cmovbl %eax, %esi
andl %r13d, %esi
leal -0x8(%rsi), %eax
cmpl $0x1a, %eax
ja 0x535d
leaq 0x2207(%rip), %rcx      # 0x74f0
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq %rsp, %rdi
callq 0x514c
leaq 0x30(%rsp), %rdi
movq %rsp, %rsi
callq 0x21d0
leaq 0x1e2c(%rip), %rsi      # 0x713a
movq %rax, %rdi
callq 0x21e0
leaq 0x1e50(%rip), %rsi      # 0x716d
movq %rax, %rdi
callq 0x21e0
movq %rax, %rdi
movl %ebp, %esi
callq 0x2370
leaq 0x2294(%rip), %rsi      # 0x75ca
movq %rax, %rdi
callq 0x21e0
leaq 0x1e28(%rip), %rsi      # 0x716d
movq %rax, %rdi
callq 0x21e0
movq %rax, %rdi
movl %r14d, %esi
callq 0x2370
jmp 0x56e9
leal -0x2a(%rsi), %eax
cmpl $0x2, %eax
jb 0x541a
cmpl $0x8c000000, %esi       # imm = 0x8C000000
je 0x55bc
cmpl $0xac000000, %esi       # imm = 0xAC000000
je 0x5655
cmpl $0x10000000, %esi       # imm = 0x10000000
je 0x5395
cmpl $0x14000000, %esi       # imm = 0x14000000
jne 0x5533
movq %rsp, %rdi
callq 0x514c
leaq 0x30(%rsp), %rdi
movq %rsp, %rsi
callq 0x21d0
leaq 0x1d89(%rip), %rsi      # 0x713a
movq %rax, %rdi
callq 0x21e0
leaq 0x1dad(%rip), %rsi      # 0x716d
movq %rax, %rdi
callq 0x21e0
movq %rax, %rdi
movl %ebp, %esi
callq 0x2370
leaq 0x21f1(%rip), %rsi      # 0x75ca
movq %rax, %rdi
callq 0x21e0
leaq 0x1d85(%rip), %rsi      # 0x716d
movq %rax, %rdi
callq 0x21e0
movq %rax, %rdi
movl %r14d, %esi
callq 0x2370
leaq 0x21c8(%rip), %rsi      # 0x75ca
movq %rax, %rdi
callq 0x21e0
movq %rax, %rdi
movl %r15d, %esi
callq 0x2370
jmp 0x56e9
movq %rsp, %rdi
callq 0x514c
leaq 0x30(%rsp), %rdi
movq %rsp, %rsi
callq 0x21d0
leaq 0x1d04(%rip), %rsi      # 0x713a
movq %rax, %rdi
callq 0x21e0
leaq 0x1d28(%rip), %rsi      # 0x716d
movq %rax, %rdi
callq 0x21e0
movq %rax, %rdi
movl %r12d, %esi
callq 0x2370
leaq 0x216b(%rip), %rsi      # 0x75ca
movq %rax, %rdi
callq 0x21e0
leaq 0x1cff(%rip), %rsi      # 0x716d
movq %rax, %rdi
callq 0x21e0
movq %rax, %rdi
movl %ebp, %esi
callq 0x2370
leaq 0x2143(%rip), %rsi      # 0x75ca
movq %rax, %rdi
callq 0x21e0
leaq 0x1cd7(%rip), %rsi      # 0x716d
movq %rax, %rdi
callq 0x21e0
movq %rax, %rdi
movl %r14d, %esi
callq 0x2370
jmp 0x56e9
movq %rsp, %rdi
callq 0x514c
leaq 0x30(%rsp), %rdi
movq %rsp, %rsi
callq 0x21d0
leaq 0x1c70(%rip), %rsi      # 0x713a
movq %rax, %rdi
callq 0x21e0
leaq 0x1c94(%rip), %rsi      # 0x716d
movq %rax, %rdi
callq 0x21e0
movq %rax, %rdi
movl %r12d, %esi
callq 0x2370
jmp 0x56e9
movq %rsp, %rdi
callq 0x514c
leaq 0x30(%rsp), %rdi
movq %rsp, %rsi
callq 0x21d0
leaq 0x1c2d(%rip), %rsi      # 0x713a
movq %rax, %rdi
callq 0x21e0
leaq 0x1c51(%rip), %rsi      # 0x716d
movq %rax, %rdi
callq 0x21e0
movq %rax, %rdi
movl %ebp, %esi
callq 0x2370
jmp 0x56e9
leaq 0x30(%rsp), %rdi
leaq 0x2090(%rip), %rsi      # 0x75cf
callq 0x21e0
leaq 0x23e4(%rip), %rsi      # 0x792f
movq %rax, %rdi
callq 0x21e0
pushq $0x30
popq %rsi
movq %rax, %rdi
callq 0x2300
movq (%rax), %rcx
movq -0x18(%rcx), %rdx
movq $0x8, 0x10(%rax,%rdx)
movq -0x18(%rcx), %rdx
movl $0xffffff4f, %esi       # imm = 0xFFFFFF4F
andl 0x18(%rax,%rdx), %esi
orl $0x80, %esi
movl %esi, 0x18(%rax,%rdx)
movq -0x18(%rcx), %rcx
movl 0x18(%rax,%rcx), %edx
andl $-0x4b, %edx
orl $0x8, %edx
movl %edx, 0x18(%rax,%rcx)
movl %r13d, %esi
movq %rax, %rdi
callq 0x2150
movq (%rax), %rcx
movq -0x18(%rcx), %rcx
movl 0x18(%rax,%rcx), %edx
andl $-0x4b, %edx
orl $0x2, %edx
movl %edx, 0x18(%rax,%rcx)
jmp 0x56f1
movq %rsp, %rdi
movl $0x8c000000, %esi       # imm = 0x8C000000
callq 0x514c
leaq 0x30(%rsp), %rdi
movq %rsp, %rsi
callq 0x21d0
leaq 0x1b5d(%rip), %rsi      # 0x713a
movq %rax, %rdi
callq 0x21e0
leaq 0x1b81(%rip), %rsi      # 0x716d
movq %rax, %rdi
callq 0x21e0
movq %rax, %rdi
movl %r14d, %esi
callq 0x2370
leaq 0x1fc4(%rip), %rsi      # 0x75ca
movq %rax, %rdi
callq 0x21e0
movq %rax, %rdi
movl %r15d, %esi
callq 0x2370
leaq 0x1fad(%rip), %rsi      # 0x75cd
movq %rax, %rdi
callq 0x21e0
leaq 0x1b3e(%rip), %rsi      # 0x716d
movq %rax, %rdi
callq 0x21e0
movq %rax, %rdi
movl %ebp, %esi
callq 0x2370
leaq 0x1a16(%rip), %rsi      # 0x705e
movq %rax, %rdi
callq 0x21e0
jmp 0x56e9
movq %rsp, %rdi
movl $0xac000000, %esi       # imm = 0xAC000000
callq 0x514c
leaq 0x30(%rsp), %rdi
movq %rsp, %rsi
callq 0x21d0
leaq 0x1ac4(%rip), %rsi      # 0x713a
movq %rax, %rdi
callq 0x21e0
leaq 0x1ae8(%rip), %rsi      # 0x716d
movq %rax, %rdi
callq 0x21e0
movq %rax, %rdi
movl %r14d, %esi
callq 0x2370
leaq 0x1f2b(%rip), %rsi      # 0x75ca
movq %rax, %rdi
callq 0x21e0
movq %rax, %rdi
movl %r15d, %esi
callq 0x2370
leaq 0x1f14(%rip), %rsi      # 0x75cd
movq %rax, %rdi
callq 0x21e0
leaq 0x1aa5(%rip), %rsi      # 0x716d
movq %rax, %rdi
callq 0x21e0
movq %rax, %rdi
movl %ebp, %esi
callq 0x2370
leaq 0x197d(%rip), %rsi      # 0x705e
movq %rax, %rdi
callq 0x21e0
movq %rsp, %rdi
callq 0x23e8
leaq 0x38(%rsp), %rsi
movq %rbx, %rdi
callq 0x2310
leaq 0x20(%rsp), %rdi
callq 0x2190
movq %rbx, %rax
addq $0x1a8, %rsp            # imm = 0x1A8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x5735
jmp 0x5735
jmp 0x5735
jmp 0x5735
jmp 0x5735
jmp 0x5735
jmp 0x5735
jmp 0x573c
jmp 0x573c
jmp 0x573c
jmp 0x573c
jmp 0x573c
movq %rax, %rbx
jmp 0x5747
jmp 0x573c
movq %rax, %rbx
movq %rsp, %rdi
callq 0x23e8
leaq 0x20(%rsp), %rdi
callq 0x2190
movq %rbx, %rdi
callq 0x23a0
nopl (%rax)