mirror of
https://github.com/dart-lang/sdk
synced 2024-09-19 21:01:50 +00:00
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:
parent
23d6c2e4a9
commit
48017a73cc
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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.
|
||||
}
|
||||
|
||||
|
|
|
@ -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),
|
||||
®,
|
||||
&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);
|
||||
|
|
|
@ -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");
|
||||
|
||||
|
|
Loading…
Reference in a new issue