// Copyright 2011 Google Inc. All Rights Reserved.

#include "assembler_arm.h"
#include "jni_internal.h"
#include "object.h"

#define __ assembler->

namespace art {
namespace arm {

typedef void (*ThrowAme)(Method*, Thread*);

ByteArray* CreateAbstractMethodErrorStub() {
  UniquePtr<ArmAssembler> assembler( static_cast<ArmAssembler*>(Assembler::Create(kArm)) );

  // Save callee saves and ready frame for exception delivery
  RegList save = (1 << R1) | (1 << R2) | (1 << R3) | (1 << R4) | (1 << R5) | (1 << R6) | (1 << R7) |
                 (1 << R8) | (1 << R9) | (1 << R10) | (1 << R11) | (1 << LR);
  __ PushList(save);
  __ Emit(0xed2d0a20);  // vpush {s0-s31}
  __ IncreaseFrameSize(16);  // 4 words of space, bottom word will hold callee save Method*

  // R0 is the Method* already
  __ mov(R1, ShifterOperand(R9));  // Pass Thread::Current() in R1
  __ mov(R2, ShifterOperand(SP));  // Pass SP in R2
  // Call to throw AbstractMethodError
  __ LoadFromOffset(kLoadWord, R12, TR, OFFSETOF_MEMBER(Thread, pThrowAbstractMethodErrorFromCode));
  // Leaf call to routine that never returns
  __ mov(PC, ShifterOperand(R12));

  __ bkpt(0);

  assembler->EmitSlowPaths();

  size_t cs = assembler->CodeSize();
  ByteArray* abstract_stub = ByteArray::Alloc(cs);
  CHECK(abstract_stub != NULL);
  CHECK(abstract_stub->GetClass()->GetDescriptor());
  MemoryRegion code(abstract_stub->GetData(), abstract_stub->GetLength());
  assembler->FinalizeInstructions(code);

  return abstract_stub;
}

ByteArray* CreateJniStub() {
  UniquePtr<ArmAssembler> assembler( static_cast<ArmAssembler*>(Assembler::Create(kArm)) );

  RegList save = (1 << R0) | (1 << R1) | (1 << R2) | (1 << R3) | (1 << LR);

  // Build frame and save registers. Save 5 registers.
  __ PushList(save);
  // Ensure 16-byte alignment
  __ AddConstant(SP, -12);

  // Pass Thread::Current() in R0
  __ mov(R0, ShifterOperand(R9));

  // Call FindNativeMethod
  __ LoadFromOffset(kLoadWord, R12, TR, OFFSETOF_MEMBER(Thread, pFindNativeMethod));
  __ blx(R12);

  // Save result of FindNativeMethod in R12
  __ mov(R12, ShifterOperand(R0));

  // Restore registers (including outgoing arguments)
  __ AddConstant(SP, 12);
  __ PopList(save);

  __ cmp(R12, ShifterOperand(0));

  // If R12 != 0 tail call into native code
  __ mov(PC, ShifterOperand(R12), NE);

  // Return to caller to handle exception
  __ mov(PC, ShifterOperand(LR));

  assembler->EmitSlowPaths();

  size_t cs = assembler->CodeSize();
  ByteArray* jni_stub = ByteArray::Alloc(cs);
  CHECK(jni_stub != NULL);
  MemoryRegion code(jni_stub->GetData(), jni_stub->GetLength());
  assembler->FinalizeInstructions(code);

  return jni_stub;
}

} // namespace arm
} // namespace art
