Fixes ABI bug in MIPS.

Adds test for native extensions with autoscoping set to false.

R=asiva@google.com

Review URL: https://codereview.chromium.org//131103025

git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@32147 260f80e4-7a28-3924-810f-c04153c831b5
This commit is contained in:
zra@google.com 2014-01-29 23:07:50 +00:00
parent 23d6c2e4a9
commit 48017a73cc
4 changed files with 38 additions and 22 deletions

View file

@ -114,12 +114,12 @@ void Assembler::EmitFarJump(int32_t offset, bool link) {
const uint16_t low = Utils::Low16Bits(offset);
const uint16_t high = Utils::High16Bits(offset);
buffer_.EmitFixup(new PatchFarJump());
lui(TMP, Immediate(high));
ori(TMP, TMP, Immediate(low));
lui(T9, Immediate(high));
ori(T9, T9, Immediate(low));
if (link) {
EmitRType(SPECIAL, TMP, R0, RA, 0, JALR);
EmitRType(SPECIAL, T9, R0, RA, 0, JALR);
} else {
EmitRType(SPECIAL, TMP, R0, R0, 0, JR);
EmitRType(SPECIAL, T9, R0, R0, 0, JR);
}
}

View file

@ -796,22 +796,22 @@ class Assembler : public ValueObject {
void BranchPatchable(const ExternalLabel* label) {
const uint16_t low = Utils::Low16Bits(label->address());
const uint16_t high = Utils::High16Bits(label->address());
lui(TMP, Immediate(high));
ori(TMP, TMP, Immediate(low));
jr(TMP);
lui(T9, Immediate(high));
ori(T9, T9, Immediate(low));
jr(T9);
delay_slot_available_ = false; // CodePatcher expects a nop.
}
void BranchLink(const ExternalLabel* label) {
LoadImmediate(TMP, label->address());
jalr(TMP);
LoadImmediate(T9, label->address());
jalr(T9);
}
void BranchLinkPatchable(const ExternalLabel* label) {
const int32_t offset =
Array::data_offset() + 4*AddExternalLabel(label) - kHeapObjectTag;
LoadWordFromPoolOffset(TMP, offset);
jalr(TMP);
LoadWordFromPoolOffset(T9, offset);
jalr(T9);
delay_slot_available_ = false; // CodePatcher expects a nop.
}

View file

@ -21,15 +21,15 @@ CallPattern::CallPattern(uword pc, const Code& code)
args_desc_(Array::Handle()),
ic_data_(ICData::Handle()) {
ASSERT(code.ContainsInstructionAt(pc));
// Last instruction: jalr RA, TMP(=R1).
ASSERT(*(reinterpret_cast<uword*>(end_) - 2) == 0x0020f809);
// Last instruction: jalr RA, T9(=R25).
ASSERT(*(reinterpret_cast<uword*>(end_) - 2) == 0x0320f809);
Register reg;
// The end of the pattern is the instruction after the delay slot of the jalr.
ic_data_load_end_ =
InstructionPattern::DecodeLoadWordFromPool(end_ - (2 * Instr::kInstrSize),
&reg,
&target_address_pool_index_);
ASSERT(reg == TMP);
ASSERT(reg == T9);
}
@ -180,9 +180,9 @@ void CallPattern::InsertAt(uword pc, uword target_address) {
uint16_t target_lo = target_address & 0xffff;
uint16_t target_hi = target_address >> 16;
lui->SetImmInstrBits(LUI, ZR, TMP, target_hi);
ori->SetImmInstrBits(ORI, TMP, TMP, target_lo);
jr->SetSpecialInstrBits(JALR, TMP, ZR, RA);
lui->SetImmInstrBits(LUI, ZR, T9, target_hi);
ori->SetImmInstrBits(ORI, T9, T9, target_lo);
jr->SetSpecialInstrBits(JALR, T9, ZR, RA);
nop->SetInstructionBits(Instr::kNopInstruction);
ASSERT(kFixedLengthInBytes == 4 * Instr::kInstrSize);

View file

@ -84,8 +84,13 @@ void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) {
// Set argv in NativeArguments.
__ addiu(A2, A2, Immediate(exitframe_last_param_slot_from_fp * kWordSize));
// Call runtime or redirection via simulator.
__ jalr(S5);
// We defensively always jalr through T9 because it is sometimes required by
// the MIPS ABI.
__ mov(T9, S5);
__ jalr(T9);
ASSERT(retval_offset == 3 * kWordSize);
// Retval is next to 1st argument.
__ delay_slot()->addiu(A3, A2, Immediate(kWordSize));
@ -206,8 +211,8 @@ void StubCode::GenerateCallNativeCFunctionStub(Assembler* assembler) {
uword entry = reinterpret_cast<uword>(NativeEntry::NativeCallWrapper);
entry = Simulator::RedirectExternalReference(
entry, Simulator::kNativeCall, NativeEntry::kNumCallWrapperArguments);
__ LoadImmediate(T5, entry);
__ jalr(T5);
__ LoadImmediate(T9, entry);
__ jalr(T9);
#else
__ BranchLink(&NativeEntry::NativeCallWrapperLabel());
#endif
@ -217,7 +222,12 @@ void StubCode::GenerateCallNativeCFunctionStub(Assembler* assembler) {
__ Bind(&leaf_call);
// Call native function or redirection via simulator.
__ ReserveAlignedFrameSpace(kWordSize); // Just passing A0.
__ jalr(T5);
// We defensively always jalr through T9 because it is sometimes required by
// the MIPS ABI.
__ mov(T9, T5);
__ jalr(T9);
__ Bind(&done);
@ -307,7 +317,11 @@ void StubCode::GenerateCallBootstrapCFunctionStub(Assembler* assembler) {
__ ReserveAlignedFrameSpace(kWordSize); // Just passing A0.
// Call native function or redirection via simulator.
__ jalr(T5);
// We defensively always jalr through T9 because it is sometimes required by
// the MIPS ABI.
__ mov(T9, T5);
__ jalr(T9);
__ TraceSimMsg("CallNativeCFunctionStub return");
// Reset exit frame information in Isolate structure.
@ -1023,6 +1037,8 @@ void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) {
__ Bind(&done_push_arguments);
// Call the Dart code entrypoint.
// We are calling into Dart code, here, so there is no need to call through
// T9 to match the ABI.
__ jalr(A0); // S4 is the arguments descriptor array.
__ TraceSimMsg("InvokeDartCodeStub return");