Allow mixing of thread offsets between 32 and 64bit architectures.
Begin a more full implementation x86-64 REX prefixes.
Doesn't implement 64bit thread offset support for the JNI compiler.
Change-Id: If9af2f08a1833c21ddb4b4077f9b03add1a05147
diff --git a/compiler/utils/mips/assembler_mips.cc b/compiler/utils/mips/assembler_mips.cc
index dfd3306..99c29f1 100644
--- a/compiler/utils/mips/assembler_mips.cc
+++ b/compiler/utils/mips/assembler_mips.cc
@@ -633,7 +633,7 @@
StoreToOffset(kStoreWord, scratch.AsCoreRegister(), SP, dest.Int32Value());
}
-void MipsAssembler::StoreImmediateToThread(ThreadOffset dest, uint32_t imm,
+void MipsAssembler::StoreImmediateToThread32(ThreadOffset<4> dest, uint32_t imm,
ManagedRegister mscratch) {
MipsManagedRegister scratch = mscratch.AsMips();
CHECK(scratch.IsCoreRegister()) << scratch;
@@ -641,7 +641,7 @@
StoreToOffset(kStoreWord, scratch.AsCoreRegister(), S1, dest.Int32Value());
}
-void MipsAssembler::StoreStackOffsetToThread(ThreadOffset thr_offs,
+void MipsAssembler::StoreStackOffsetToThread32(ThreadOffset<4> thr_offs,
FrameOffset fr_offs,
ManagedRegister mscratch) {
MipsManagedRegister scratch = mscratch.AsMips();
@@ -651,7 +651,7 @@
S1, thr_offs.Int32Value());
}
-void MipsAssembler::StoreStackPointerToThread(ThreadOffset thr_offs) {
+void MipsAssembler::StoreStackPointerToThread32(ThreadOffset<4> thr_offs) {
StoreToOffset(kStoreWord, SP, S1, thr_offs.Int32Value());
}
@@ -668,7 +668,7 @@
return EmitLoad(mdest, SP, src.Int32Value(), size);
}
-void MipsAssembler::Load(ManagedRegister mdest, ThreadOffset src, size_t size) {
+void MipsAssembler::LoadFromThread32(ManagedRegister mdest, ThreadOffset<4> src, size_t size) {
return EmitLoad(mdest, S1, src.Int32Value(), size);
}
@@ -697,8 +697,8 @@
base.AsMips().AsCoreRegister(), offs.Int32Value());
}
-void MipsAssembler::LoadRawPtrFromThread(ManagedRegister mdest,
- ThreadOffset offs) {
+void MipsAssembler::LoadRawPtrFromThread32(ManagedRegister mdest,
+ ThreadOffset<4> offs) {
MipsManagedRegister dest = mdest.AsMips();
CHECK(dest.IsCoreRegister());
LoadFromOffset(kLoadWord, dest.AsCoreRegister(), S1, offs.Int32Value());
@@ -748,8 +748,8 @@
StoreToOffset(kStoreWord, scratch.AsCoreRegister(), SP, dest.Int32Value());
}
-void MipsAssembler::CopyRawPtrFromThread(FrameOffset fr_offs,
- ThreadOffset thr_offs,
+void MipsAssembler::CopyRawPtrFromThread32(FrameOffset fr_offs,
+ ThreadOffset<4> thr_offs,
ManagedRegister mscratch) {
MipsManagedRegister scratch = mscratch.AsMips();
CHECK(scratch.IsCoreRegister()) << scratch;
@@ -759,7 +759,7 @@
SP, fr_offs.Int32Value());
}
-void MipsAssembler::CopyRawPtrToThread(ThreadOffset thr_offs,
+void MipsAssembler::CopyRawPtrToThread32(ThreadOffset<4> thr_offs,
FrameOffset fr_offs,
ManagedRegister mscratch) {
MipsManagedRegister scratch = mscratch.AsMips();
@@ -923,7 +923,7 @@
// TODO: place reference map on call
}
-void MipsAssembler::Call(ThreadOffset /*offset*/, ManagedRegister /*mscratch*/) {
+void MipsAssembler::CallFromThread32(ThreadOffset<4> /*offset*/, ManagedRegister /*mscratch*/) {
UNIMPLEMENTED(FATAL) << "no mips implementation";
}
@@ -941,7 +941,7 @@
MipsExceptionSlowPath* slow = new MipsExceptionSlowPath(scratch, stack_adjust);
buffer_.EnqueueSlowPath(slow);
LoadFromOffset(kLoadWord, scratch.AsCoreRegister(),
- S1, Thread::ExceptionOffset().Int32Value());
+ S1, Thread::ExceptionOffset<4>().Int32Value());
EmitBranch(scratch.AsCoreRegister(), ZERO, slow->Entry(), false);
}
@@ -956,7 +956,7 @@
// Don't care about preserving A0 as this call won't return
__ Move(A0, scratch_.AsCoreRegister());
// Set up call to Thread::Current()->pDeliverException
- __ LoadFromOffset(kLoadWord, T9, S1, QUICK_ENTRYPOINT_OFFSET(pDeliverException).Int32Value());
+ __ LoadFromOffset(kLoadWord, T9, S1, QUICK_ENTRYPOINT_OFFSET(4, pDeliverException).Int32Value());
__ Jr(T9);
// Call never returns
__ Break();
diff --git a/compiler/utils/mips/assembler_mips.h b/compiler/utils/mips/assembler_mips.h
index 0d1a94c..75ee8b9 100644
--- a/compiler/utils/mips/assembler_mips.h
+++ b/compiler/utils/mips/assembler_mips.h
@@ -29,171 +29,6 @@
namespace art {
namespace mips {
-#if 0
-class Operand {
- public:
- uint8_t mod() const {
- return (encoding_at(0) >> 6) & 3;
- }
-
- Register rm() const {
- return static_cast<Register>(encoding_at(0) & 7);
- }
-
- ScaleFactor scale() const {
- return static_cast<ScaleFactor>((encoding_at(1) >> 6) & 3);
- }
-
- Register index() const {
- return static_cast<Register>((encoding_at(1) >> 3) & 7);
- }
-
- Register base() const {
- return static_cast<Register>(encoding_at(1) & 7);
- }
-
- int8_t disp8() const {
- CHECK_GE(length_, 2);
- return static_cast<int8_t>(encoding_[length_ - 1]);
- }
-
- int32_t disp32() const {
- CHECK_GE(length_, 5);
- int32_t value;
- memcpy(&value, &encoding_[length_ - 4], sizeof(value));
- return value;
- }
-
- bool IsRegister(Register reg) const {
- return ((encoding_[0] & 0xF8) == 0xC0) // Addressing mode is register only.
- && ((encoding_[0] & 0x07) == reg); // Register codes match.
- }
-
- protected:
- // Operand can be sub classed (e.g: Address).
- Operand() : length_(0) { }
-
- void SetModRM(int mod, Register rm) {
- CHECK_EQ(mod & ~3, 0);
- encoding_[0] = (mod << 6) | rm;
- length_ = 1;
- }
-
- void SetSIB(ScaleFactor scale, Register index, Register base) {
- CHECK_EQ(length_, 1);
- CHECK_EQ(scale & ~3, 0);
- encoding_[1] = (scale << 6) | (index << 3) | base;
- length_ = 2;
- }
-
- void SetDisp8(int8_t disp) {
- CHECK(length_ == 1 || length_ == 2);
- encoding_[length_++] = static_cast<uint8_t>(disp);
- }
-
- void SetDisp32(int32_t disp) {
- CHECK(length_ == 1 || length_ == 2);
- int disp_size = sizeof(disp);
- memmove(&encoding_[length_], &disp, disp_size);
- length_ += disp_size;
- }
-
- private:
- byte length_;
- byte encoding_[6];
- byte padding_;
-
- explicit Operand(Register reg) { SetModRM(3, reg); }
-
- // Get the operand encoding byte at the given index.
- uint8_t encoding_at(int index) const {
- CHECK_GE(index, 0);
- CHECK_LT(index, length_);
- return encoding_[index];
- }
-
- friend class MipsAssembler;
-
- DISALLOW_COPY_AND_ASSIGN(Operand);
-};
-
-
-class Address : public Operand {
- public:
- Address(Register base, int32_t disp) {
- Init(base, disp);
- }
-
- Address(Register base, Offset disp) {
- Init(base, disp.Int32Value());
- }
-
- Address(Register base, FrameOffset disp) {
- CHECK_EQ(base, ESP);
- Init(ESP, disp.Int32Value());
- }
-
- Address(Register base, MemberOffset disp) {
- Init(base, disp.Int32Value());
- }
-
- void Init(Register base, int32_t disp) {
- if (disp == 0 && base != EBP) {
- SetModRM(0, base);
- if (base == ESP) SetSIB(TIMES_1, ESP, base);
- } else if (disp >= -128 && disp <= 127) {
- SetModRM(1, base);
- if (base == ESP) SetSIB(TIMES_1, ESP, base);
- SetDisp8(disp);
- } else {
- SetModRM(2, base);
- if (base == ESP) SetSIB(TIMES_1, ESP, base);
- SetDisp32(disp);
- }
- }
-
-
- Address(Register index, ScaleFactor scale, int32_t disp) {
- CHECK_NE(index, ESP); // Illegal addressing mode.
- SetModRM(0, ESP);
- SetSIB(scale, index, EBP);
- SetDisp32(disp);
- }
-
- Address(Register base, Register index, ScaleFactor scale, int32_t disp) {
- CHECK_NE(index, ESP); // Illegal addressing mode.
- if (disp == 0 && base != EBP) {
- SetModRM(0, ESP);
- SetSIB(scale, index, base);
- } else if (disp >= -128 && disp <= 127) {
- SetModRM(1, ESP);
- SetSIB(scale, index, base);
- SetDisp8(disp);
- } else {
- SetModRM(2, ESP);
- SetSIB(scale, index, base);
- SetDisp32(disp);
- }
- }
-
- static Address Absolute(uword addr) {
- Address result;
- result.SetModRM(0, EBP);
- result.SetDisp32(addr);
- return result;
- }
-
- static Address Absolute(ThreadOffset addr) {
- return Absolute(addr.Int32Value());
- }
-
- private:
- Address() {}
-
- DISALLOW_COPY_AND_ASSIGN(Address);
-};
-
-#endif
enum LoadOperandType {
kLoadSignedByte,
@@ -215,7 +50,7 @@
kStoreDWord
};
-class MipsAssembler : public Assembler {
+class MipsAssembler FINAL : public Assembler {
public:
MipsAssembler() {}
virtual ~MipsAssembler() {}
@@ -310,40 +145,6 @@
void StoreFToOffset(FRegister reg, Register base, int32_t offset);
void StoreDToOffset(DRegister reg, Register base, int32_t offset);
-#if 0
- MipsAssembler* lock();
-
- void mfence();
-
- MipsAssembler* fs();
-
- //
- // Macros for High-level operations.
- //
-
- void AddImmediate(Register reg, const Immediate& imm);
-
- void LoadDoubleConstant(XmmRegister dst, double value);
-
- void DoubleNegate(XmmRegister d);
- void FloatNegate(XmmRegister f);
-
- void DoubleAbs(XmmRegister reg);
-
- void LockCmpxchgl(const Address& address, Register reg) {
- lock()->cmpxchgl(address, reg);
- }
-
- //
- // Misc. functionality
- //
- int PreferredLoopAlignment() { return 16; }
- void Align(int alignment, int offset);
-
- // Debugging and bringup support.
- void Stop(const char* message);
-#endif
-
// Emit data (e.g. encoded instruction or immediate) to the instruction stream.
void Emit(int32_t value);
void EmitBranch(Register rt, Register rs, Label* label, bool equal);
@@ -355,127 +156,116 @@
//
// Emit code that will create an activation on the stack
- virtual void BuildFrame(size_t frame_size, ManagedRegister method_reg,
- const std::vector<ManagedRegister>& callee_save_regs,
- const ManagedRegisterEntrySpills& entry_spills);
+ void BuildFrame(size_t frame_size, ManagedRegister method_reg,
+ const std::vector<ManagedRegister>& callee_save_regs,
+ const ManagedRegisterEntrySpills& entry_spills) OVERRIDE;
// Emit code that will remove an activation from the stack
- virtual void RemoveFrame(size_t frame_size,
- const std::vector<ManagedRegister>& callee_save_regs);
+ void RemoveFrame(size_t frame_size, const std::vector<ManagedRegister>& callee_save_regs)
+ OVERRIDE;
- virtual void IncreaseFrameSize(size_t adjust);
- virtual void DecreaseFrameSize(size_t adjust);
+ void IncreaseFrameSize(size_t adjust) OVERRIDE;
+ void DecreaseFrameSize(size_t adjust) OVERRIDE;
// Store routines
- virtual void Store(FrameOffset offs, ManagedRegister msrc, size_t size);
- virtual void StoreRef(FrameOffset dest, ManagedRegister msrc);
- virtual void StoreRawPtr(FrameOffset dest, ManagedRegister msrc);
+ void Store(FrameOffset offs, ManagedRegister msrc, size_t size) OVERRIDE;
+ void StoreRef(FrameOffset dest, ManagedRegister msrc) OVERRIDE;
+ void StoreRawPtr(FrameOffset dest, ManagedRegister msrc) OVERRIDE;
- virtual void StoreImmediateToFrame(FrameOffset dest, uint32_t imm,
- ManagedRegister mscratch);
+ void StoreImmediateToFrame(FrameOffset dest, uint32_t imm, ManagedRegister mscratch) OVERRIDE;
- virtual void StoreImmediateToThread(ThreadOffset dest, uint32_t imm,
- ManagedRegister mscratch);
+ void StoreImmediateToThread32(ThreadOffset<4> dest, uint32_t imm, ManagedRegister mscratch)
+ OVERRIDE;
- virtual void StoreStackOffsetToThread(ThreadOffset thr_offs,
- FrameOffset fr_offs,
- ManagedRegister mscratch);
+ void StoreStackOffsetToThread32(ThreadOffset<4> thr_offs, FrameOffset fr_offs,
+ ManagedRegister mscratch) OVERRIDE;
- virtual void StoreStackPointerToThread(ThreadOffset thr_offs);
+ void StoreStackPointerToThread32(ThreadOffset<4> thr_offs) OVERRIDE;
- virtual void StoreSpanning(FrameOffset dest, ManagedRegister msrc,
- FrameOffset in_off, ManagedRegister mscratch);
+ void StoreSpanning(FrameOffset dest, ManagedRegister msrc, FrameOffset in_off,
+ ManagedRegister mscratch) OVERRIDE;
// Load routines
- virtual void Load(ManagedRegister mdest, FrameOffset src, size_t size);
+ void Load(ManagedRegister mdest, FrameOffset src, size_t size) OVERRIDE;
- virtual void Load(ManagedRegister mdest, ThreadOffset src, size_t size);
+ void LoadFromThread32(ManagedRegister mdest, ThreadOffset<4> src, size_t size) OVERRIDE;
- virtual void LoadRef(ManagedRegister dest, FrameOffset src);
+ void LoadRef(ManagedRegister dest, FrameOffset src) OVERRIDE;
- virtual void LoadRef(ManagedRegister mdest, ManagedRegister base,
- MemberOffset offs);
+ void LoadRef(ManagedRegister mdest, ManagedRegister base, MemberOffset offs) OVERRIDE;
- virtual void LoadRawPtr(ManagedRegister mdest, ManagedRegister base,
- Offset offs);
+ void LoadRawPtr(ManagedRegister mdest, ManagedRegister base, Offset offs) OVERRIDE;
- virtual void LoadRawPtrFromThread(ManagedRegister mdest,
- ThreadOffset offs);
+ void LoadRawPtrFromThread32(ManagedRegister mdest, ThreadOffset<4> offs) OVERRIDE;
// Copying routines
- virtual void Move(ManagedRegister mdest, ManagedRegister msrc, size_t size);
+ void Move(ManagedRegister mdest, ManagedRegister msrc, size_t size) OVERRIDE;
- virtual void CopyRawPtrFromThread(FrameOffset fr_offs, ThreadOffset thr_offs,
- ManagedRegister mscratch);
+ void CopyRawPtrFromThread32(FrameOffset fr_offs, ThreadOffset<4> thr_offs,
+ ManagedRegister mscratch) OVERRIDE;
- virtual void CopyRawPtrToThread(ThreadOffset thr_offs, FrameOffset fr_offs,
- ManagedRegister mscratch);
+ void CopyRawPtrToThread32(ThreadOffset<4> thr_offs, FrameOffset fr_offs,
+ ManagedRegister mscratch) OVERRIDE;
- virtual void CopyRef(FrameOffset dest, FrameOffset src,
- ManagedRegister mscratch);
+ void CopyRef(FrameOffset dest, FrameOffset src, ManagedRegister mscratch) OVERRIDE;
- virtual void Copy(FrameOffset dest, FrameOffset src, ManagedRegister mscratch, size_t size);
+ void Copy(FrameOffset dest, FrameOffset src, ManagedRegister mscratch, size_t size) OVERRIDE;
- virtual void Copy(FrameOffset dest, ManagedRegister src_base, Offset src_offset,
- ManagedRegister mscratch, size_t size);
+ void Copy(FrameOffset dest, ManagedRegister src_base, Offset src_offset, ManagedRegister mscratch,
+ size_t size) OVERRIDE;
- virtual void Copy(ManagedRegister dest_base, Offset dest_offset, FrameOffset src,
- ManagedRegister mscratch, size_t size);
+ void Copy(ManagedRegister dest_base, Offset dest_offset, FrameOffset src,
+ ManagedRegister mscratch, size_t size) OVERRIDE;
- virtual void Copy(FrameOffset dest, FrameOffset src_base, Offset src_offset,
- ManagedRegister mscratch, size_t size);
+ void Copy(FrameOffset dest, FrameOffset src_base, Offset src_offset, ManagedRegister mscratch,
+ size_t size) OVERRIDE;
- virtual void Copy(ManagedRegister dest, Offset dest_offset,
- ManagedRegister src, Offset src_offset,
- ManagedRegister mscratch, size_t size);
+ void Copy(ManagedRegister dest, Offset dest_offset, ManagedRegister src, Offset src_offset,
+ ManagedRegister mscratch, size_t size) OVERRIDE;
- virtual void Copy(FrameOffset dest, Offset dest_offset, FrameOffset src, Offset src_offset,
- ManagedRegister mscratch, size_t size);
+ void Copy(FrameOffset dest, Offset dest_offset, FrameOffset src, Offset src_offset,
+ ManagedRegister mscratch, size_t size) OVERRIDE;
- virtual void MemoryBarrier(ManagedRegister);
+ void MemoryBarrier(ManagedRegister) OVERRIDE;
// Sign extension
- virtual void SignExtend(ManagedRegister mreg, size_t size);
+ void SignExtend(ManagedRegister mreg, size_t size) OVERRIDE;
// Zero extension
- virtual void ZeroExtend(ManagedRegister mreg, size_t size);
+ void ZeroExtend(ManagedRegister mreg, size_t size) OVERRIDE;
// Exploit fast access in managed code to Thread::Current()
- virtual void GetCurrentThread(ManagedRegister tr);
- virtual void GetCurrentThread(FrameOffset dest_offset,
- ManagedRegister mscratch);
+ void GetCurrentThread(ManagedRegister tr) OVERRIDE;
+ void GetCurrentThread(FrameOffset dest_offset, ManagedRegister mscratch) OVERRIDE;
// Set up out_reg to hold a Object** into the SIRT, or to be NULL if the
// value is null and null_allowed. in_reg holds a possibly stale reference
// that can be used to avoid loading the SIRT entry to see if the value is
// NULL.
- virtual void CreateSirtEntry(ManagedRegister out_reg, FrameOffset sirt_offset,
- ManagedRegister in_reg, bool null_allowed);
+ void CreateSirtEntry(ManagedRegister out_reg, FrameOffset sirt_offset, ManagedRegister in_reg,
+ bool null_allowed) OVERRIDE;
// Set up out_off to hold a Object** into the SIRT, or to be NULL if the
// value is null and null_allowed.
- virtual void CreateSirtEntry(FrameOffset out_off, FrameOffset sirt_offset,
- ManagedRegister mscratch, bool null_allowed);
+ void CreateSirtEntry(FrameOffset out_off, FrameOffset sirt_offset, ManagedRegister mscratch,
+ bool null_allowed) OVERRIDE;
// src holds a SIRT entry (Object**) load this into dst
- virtual void LoadReferenceFromSirt(ManagedRegister dst,
- ManagedRegister src);
+ void LoadReferenceFromSirt(ManagedRegister dst, ManagedRegister src) OVERRIDE;
// Heap::VerifyObject on src. In some cases (such as a reference to this) we
// know that src may not be null.
- virtual void VerifyObject(ManagedRegister src, bool could_be_null);
- virtual void VerifyObject(FrameOffset src, bool could_be_null);
+ void VerifyObject(ManagedRegister src, bool could_be_null) OVERRIDE;
+ void VerifyObject(FrameOffset src, bool could_be_null) OVERRIDE;
// Call to address held at [base+offset]
- virtual void Call(ManagedRegister base, Offset offset,
- ManagedRegister mscratch);
- virtual void Call(FrameOffset base, Offset offset,
- ManagedRegister mscratch);
- virtual void Call(ThreadOffset offset, ManagedRegister mscratch);
+ void Call(ManagedRegister base, Offset offset, ManagedRegister mscratch) OVERRIDE;
+ void Call(FrameOffset base, Offset offset, ManagedRegister mscratch) OVERRIDE;
+ void CallFromThread32(ThreadOffset<4> offset, ManagedRegister mscratch) OVERRIDE;
// Generate code to check if Thread::Current()->exception_ is non-null
// and branch to a ExceptionSlowPath if it is.
- virtual void ExceptionPoll(ManagedRegister mscratch, size_t stack_adjust);
+ void ExceptionPoll(ManagedRegister mscratch, size_t stack_adjust) OVERRIDE;
private:
void EmitR(int opcode, Register rs, Register rt, Register rd, int shamt, int funct);
@@ -491,11 +281,11 @@
};
// Slowpath entered when Thread::Current()->_exception is non-null
-class MipsExceptionSlowPath : public SlowPath {
+class MipsExceptionSlowPath FINAL : public SlowPath {
public:
explicit MipsExceptionSlowPath(MipsManagedRegister scratch, size_t stack_adjust)
: scratch_(scratch), stack_adjust_(stack_adjust) {}
- virtual void Emit(Assembler *sp_asm);
+ virtual void Emit(Assembler *sp_asm) OVERRIDE;
private:
const MipsManagedRegister scratch_;
const size_t stack_adjust_;