summaryrefslogtreecommitdiffstats
path: root/js/src/jit/mips-shared/Assembler-mips-shared.h
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/jit/mips-shared/Assembler-mips-shared.h')
-rw-r--r--js/src/jit/mips-shared/Assembler-mips-shared.h83
1 files changed, 64 insertions, 19 deletions
diff --git a/js/src/jit/mips-shared/Assembler-mips-shared.h b/js/src/jit/mips-shared/Assembler-mips-shared.h
index a619fa0e0..1640fdafc 100644
--- a/js/src/jit/mips-shared/Assembler-mips-shared.h
+++ b/js/src/jit/mips-shared/Assembler-mips-shared.h
@@ -525,21 +525,13 @@ class JOffImm26
}
int32_t decode() {
MOZ_ASSERT(!isInvalid());
- return (int32_t(data << 8) >> 6) + 4;
+ return int32_t(data << 8) >> 6;
}
explicit JOffImm26(int offset)
- : data ((offset - 4) >> 2 & Imm26Mask)
+ : data (offset >> 2 & Imm26Mask)
{
MOZ_ASSERT((offset & 0x3) == 0);
- MOZ_ASSERT(IsInRange(offset));
- }
- static bool IsInRange(int offset) {
- if ((offset - 4) < -536870912)
- return false;
- if ((offset - 4) > 536870908)
- return false;
- return true;
}
static const uint32_t INVALID = 0x20000000;
JOffImm26()
@@ -840,6 +832,27 @@ class AssemblerMIPSShared : public AssemblerShared
TestForFalse
};
+ struct MixedJumpPatch
+ {
+ enum Kind {
+ NONE,
+ PATCHABLE,
+ CONDITIONAL,
+ };
+
+ BufferOffset src;
+ BufferOffset mid;
+ uintptr_t target;
+ Kind kind;
+
+ MixedJumpPatch(BufferOffset src, uintptr_t target, Kind kind)
+ : src(src),
+ mid(BufferOffset()),
+ target(target),
+ kind(kind)
+ { }
+ };
+
// :( this should be protected, but since CodeGenerator
// wants to use it, It needs to go out here :(
@@ -873,7 +886,7 @@ class AssemblerMIPSShared : public AssemblerShared
};
js::Vector<RelativePatch, 8, SystemAllocPolicy> jumps_;
- js::Vector<uint32_t, 8, SystemAllocPolicy> longJumps_;
+ js::Vector<MixedJumpPatch, 8, SystemAllocPolicy> mixedJumps_;
CompactBufferWriter jumpRelocations_;
CompactBufferWriter dataRelocations_;
@@ -922,7 +935,9 @@ class AssemblerMIPSShared : public AssemblerShared
public:
void finish();
bool asmMergeWith(const AssemblerMIPSShared& other);
- void executableCopy(void* buffer);
+ // Copy the assembly code to the given buffer, and perform any pending
+ // relocations relying on the target address.
+ void executableCopy(uint8_t* buffer);
void copyJumpRelocationTable(uint8_t* dest);
void copyDataRelocationTable(uint8_t* dest);
void copyPreBarrierTable(uint8_t* dest);
@@ -1197,8 +1212,9 @@ class AssemblerMIPSShared : public AssemblerShared
// label operations
void bind(Label* label, BufferOffset boff = BufferOffset());
void bindLater(Label* label, wasm::TrapDesc target);
- virtual void bind(InstImm* inst, uintptr_t branch, uintptr_t target) = 0;
+ void bind(InstImm* inst, uintptr_t branch, uintptr_t target);
virtual void Bind(uint8_t* rawCode, CodeOffset* label, const void* address) = 0;
+ void bind(RepatchLabel* label);
void bind(CodeOffset* label) {
label->bind(currentOffset());
}
@@ -1240,16 +1256,21 @@ class AssemblerMIPSShared : public AssemblerShared
writeRelocation(src);
}
- void addLongJump(BufferOffset src) {
- enoughMemory_ &= longJumps_.append(src.getOffset());
+ void addMixedJump(BufferOffset src, uintptr_t target,
+ MixedJumpPatch::Kind kind = MixedJumpPatch::NONE)
+ {
+ enoughMemory_ &= mixedJumps_.append(MixedJumpPatch(src, target, kind));
}
+ virtual void GenerateMixedJumps() = 0;
+ void PatchMixedJumps(uint8_t* buffer);
+
public:
- size_t numLongJumps() const {
- return longJumps_.length();
+ size_t numMixedJumps() const {
+ return mixedJumps_.length();
}
- uint32_t longJump(size_t i) {
- return longJumps_[i];
+ MixedJumpPatch& mixedJump(size_t i) {
+ return mixedJumps_[i];
}
void flushBuffer() {
@@ -1261,18 +1282,24 @@ class AssemblerMIPSShared : public AssemblerShared
}
static uint32_t NopSize() { return 4; }
+ static uint32_t PatchWrite_NearCallSize();
static void PatchWrite_Imm32(CodeLocationLabel label, Imm32 imm);
+ static void PatchWrite_NearCall(CodeLocationLabel start, CodeLocationLabel toCall);
static uint32_t AlignDoubleArg(uint32_t offset) {
return (offset + 1U) &~ 1U;
}
static uint8_t* NextInstruction(uint8_t* instruction, uint32_t* count = nullptr);
+ static Instruction* GetInstructionImmediateFromJump(Instruction* jump);
+ static void PatchMixedJump(uint8_t* src, uint8_t* mid, uint8_t* target);
static void ToggleToJmp(CodeLocationLabel inst_);
static void ToggleToCmp(CodeLocationLabel inst_);
+ static void UpdateLuiOriValue(Instruction* inst0, Instruction* inst1, uint32_t value);
+
void processCodeLabels(uint8_t* rawCode);
bool bailed() {
@@ -1487,6 +1514,10 @@ class InstJump : public Instruction
uint32_t extractImm26Value() {
return extractBitField(Imm26Shift + Imm26Bits - 1, Imm26Shift);
}
+ void setJOffImm26(JOffImm26 off) {
+ // Reset immediate field and replace it
+ data = (data & ~Imm26Mask) | off.encode();
+ }
};
// Class for Loongson-specific instructions
@@ -1516,6 +1547,20 @@ class InstGS : public Instruction
{ }
};
+inline bool
+IsUnaligned(const wasm::MemoryAccessDesc& access)
+{
+ if (!access.align())
+ return false;
+
+#ifdef JS_CODEGEN_MIPS32
+ if (access.type() == Scalar::Int64 && access.align() >= 4)
+ return false;
+#endif
+
+ return access.align() < access.byteSize();
+}
+
} // namespace jit
} // namespace js