mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-05 07:18:39 +09:00
Merge remote-tracking branch 'origin/tracking' into custom
This commit is contained in:
commit
e9d4ea8fbf
37 changed files with 444 additions and 33 deletions
|
|
@ -84,6 +84,8 @@ const I64TruncUF32Code = 0xaf;
|
|||
const I64TruncSF64Code = 0xb0;
|
||||
const I64TruncUF64Code = 0xb1;
|
||||
|
||||
const FirstInvalidOpcode = 0xc5;
|
||||
|
||||
// DefinitionKind
|
||||
const FunctionCode = 0x00;
|
||||
const TableCode = 0x01;
|
||||
|
|
|
|||
|
|
@ -12117,16 +12117,16 @@ CodeGenerator::visitRandom(LRandom* ins)
|
|||
}
|
||||
|
||||
void
|
||||
CodeGenerator::visitSignExtend(LSignExtend* ins)
|
||||
CodeGenerator::visitSignExtendInt32(LSignExtendInt32* ins)
|
||||
{
|
||||
Register input = ToRegister(ins->input());
|
||||
Register output = ToRegister(ins->output());
|
||||
|
||||
switch (ins->mode()) {
|
||||
case MSignExtend::Byte:
|
||||
case MSignExtendInt32::Byte:
|
||||
masm.move8SignExtend(input, output);
|
||||
break;
|
||||
case MSignExtend::Half:
|
||||
case MSignExtendInt32::Half:
|
||||
masm.move16SignExtend(input, output);
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -440,7 +440,7 @@ class CodeGenerator final : public CodeGeneratorSpecific
|
|||
void visitRotate(LRotate* ins);
|
||||
|
||||
void visitRandom(LRandom* ins);
|
||||
void visitSignExtend(LSignExtend* ins);
|
||||
void visitSignExtendInt32(LSignExtendInt32* ins);
|
||||
void visitModuleMetadata(LModuleMetadata* lir);
|
||||
void visitDynamicImport(LDynamicImport* lir);
|
||||
|
||||
|
|
|
|||
|
|
@ -1328,14 +1328,14 @@ LIRGenerator::visitUrsh(MUrsh* ins)
|
|||
}
|
||||
|
||||
void
|
||||
LIRGenerator::visitSignExtend(MSignExtend* ins)
|
||||
LIRGenerator::visitSignExtendInt32(MSignExtendInt32* ins)
|
||||
{
|
||||
LInstructionHelper<1, 1, 0>* lir;
|
||||
|
||||
if (ins->mode() == MSignExtend::Byte)
|
||||
lir = new(alloc()) LSignExtend(useByteOpRegisterAtStart(ins->input()), ins->mode());
|
||||
if (ins->mode() == MSignExtendInt32::Byte)
|
||||
lir = new(alloc()) LSignExtendInt32(useByteOpRegisterAtStart(ins->input()), ins->mode());
|
||||
else
|
||||
lir = new(alloc()) LSignExtend(useRegisterAtStart(ins->input()), ins->mode());
|
||||
lir = new(alloc()) LSignExtendInt32(useRegisterAtStart(ins->input()), ins->mode());
|
||||
|
||||
define(lir, ins);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -130,7 +130,7 @@ class LIRGenerator : public LIRGeneratorSpecific
|
|||
void visitLsh(MLsh* ins);
|
||||
void visitRsh(MRsh* ins);
|
||||
void visitUrsh(MUrsh* ins);
|
||||
void visitSignExtend(MSignExtend* ins);
|
||||
void visitSignExtendInt32(MSignExtendInt32* ins);
|
||||
void visitRotate(MRotate* ins);
|
||||
void visitFloor(MFloor* ins);
|
||||
void visitCeil(MCeil* ins);
|
||||
|
|
|
|||
|
|
@ -2618,9 +2618,9 @@ MRsh::foldsTo(TempAllocator& alloc)
|
|||
|
||||
switch (shift) {
|
||||
case 16:
|
||||
return MSignExtend::New(alloc, lhs->getOperand(0), MSignExtend::Half);
|
||||
return MSignExtendInt32::New(alloc, lhs->getOperand(0), MSignExtendInt32::Half);
|
||||
case 24:
|
||||
return MSignExtend::New(alloc, lhs->getOperand(0), MSignExtend::Byte);
|
||||
return MSignExtendInt32::New(alloc, lhs->getOperand(0), MSignExtendInt32::Byte);
|
||||
}
|
||||
|
||||
return this;
|
||||
|
|
@ -3802,6 +3802,41 @@ MExtendInt32ToInt64::foldsTo(TempAllocator& alloc)
|
|||
return this;
|
||||
}
|
||||
|
||||
MDefinition*
|
||||
MSignExtendInt32::foldsTo(TempAllocator& alloc)
|
||||
{
|
||||
MDefinition* input = this->input();
|
||||
if (input->isConstant()) {
|
||||
int32_t c = input->toConstant()->toInt32();
|
||||
int32_t res;
|
||||
switch (mode_) {
|
||||
case Byte: res = int32_t(int8_t(c & 0xFF)); break;
|
||||
case Half: res = int32_t(int16_t(c & 0xFFFF)); break;
|
||||
}
|
||||
return MConstant::New(alloc, Int32Value(res));
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
MDefinition*
|
||||
MSignExtendInt64::foldsTo(TempAllocator& alloc)
|
||||
{
|
||||
MDefinition* input = this->input();
|
||||
if (input->isConstant()) {
|
||||
int64_t c = input->toConstant()->toInt64();
|
||||
int64_t res;
|
||||
switch (mode_) {
|
||||
case Byte: res = int64_t(int8_t(c & 0xFF)); break;
|
||||
case Half: res = int64_t(int16_t(c & 0xFFFF)); break;
|
||||
case Word: res = int64_t(int32_t(c & 0xFFFFFFFFU)); break;
|
||||
}
|
||||
return MConstant::NewInt64(alloc, res);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
MDefinition*
|
||||
MToDouble::foldsTo(TempAllocator& alloc)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4973,7 +4973,7 @@ class MUrsh : public MShiftInstruction
|
|||
ALLOW_CLONE(MUrsh)
|
||||
};
|
||||
|
||||
class MSignExtend
|
||||
class MSignExtendInt32
|
||||
: public MUnaryInstruction,
|
||||
public NoTypePolicy::Data
|
||||
{
|
||||
|
|
@ -4986,7 +4986,7 @@ class MSignExtend
|
|||
private:
|
||||
Mode mode_;
|
||||
|
||||
MSignExtend(MDefinition* op, Mode mode)
|
||||
MSignExtendInt32(MDefinition* op, Mode mode)
|
||||
: MUnaryInstruction(op), mode_(mode)
|
||||
{
|
||||
setResultType(MIRType::Int32);
|
||||
|
|
@ -4994,17 +4994,67 @@ class MSignExtend
|
|||
}
|
||||
|
||||
public:
|
||||
INSTRUCTION_HEADER(SignExtend)
|
||||
INSTRUCTION_HEADER(SignExtendInt32)
|
||||
TRIVIAL_NEW_WRAPPERS
|
||||
|
||||
Mode mode() { return mode_; }
|
||||
Mode mode() const { return mode_; }
|
||||
|
||||
MDefinition* foldsTo(TempAllocator& alloc) override;
|
||||
bool congruentTo(const MDefinition* ins) const override {
|
||||
if (!congruentIfOperandsEqual(ins))
|
||||
return false;
|
||||
return ins->isSignExtendInt32() && ins->toSignExtendInt32()->mode_ == mode_;
|
||||
}
|
||||
AliasSet getAliasSet() const override {
|
||||
return AliasSet::None();
|
||||
}
|
||||
|
||||
MOZ_MUST_USE bool writeRecoverData(CompactBufferWriter& writer) const override;
|
||||
bool canRecoverOnBailout() const override {
|
||||
return true;
|
||||
}
|
||||
|
||||
ALLOW_CLONE(MSignExtend)
|
||||
ALLOW_CLONE(MSignExtendInt32)
|
||||
};
|
||||
|
||||
class MSignExtendInt64
|
||||
: public MUnaryInstruction,
|
||||
public NoTypePolicy::Data
|
||||
{
|
||||
public:
|
||||
enum Mode {
|
||||
Byte,
|
||||
Half,
|
||||
Word
|
||||
};
|
||||
|
||||
private:
|
||||
Mode mode_;
|
||||
|
||||
MSignExtendInt64(MDefinition* op, Mode mode)
|
||||
: MUnaryInstruction(op), mode_(mode)
|
||||
{
|
||||
setResultType(MIRType::Int64);
|
||||
setMovable();
|
||||
}
|
||||
|
||||
public:
|
||||
INSTRUCTION_HEADER(SignExtendInt64)
|
||||
TRIVIAL_NEW_WRAPPERS
|
||||
|
||||
Mode mode() const { return mode_; }
|
||||
|
||||
MDefinition* foldsTo(TempAllocator& alloc) override;
|
||||
bool congruentTo(const MDefinition* ins) const override {
|
||||
if (!congruentIfOperandsEqual(ins))
|
||||
return false;
|
||||
return ins->isSignExtendInt64() && ins->toSignExtendInt64()->mode_ == mode_;
|
||||
}
|
||||
AliasSet getAliasSet() const override {
|
||||
return AliasSet::None();
|
||||
}
|
||||
|
||||
ALLOW_CLONE(MSignExtendInt64)
|
||||
};
|
||||
|
||||
class MBinaryArithInstruction
|
||||
|
|
|
|||
|
|
@ -66,7 +66,8 @@ namespace jit {
|
|||
_(Lsh) \
|
||||
_(Rsh) \
|
||||
_(Ursh) \
|
||||
_(SignExtend) \
|
||||
_(SignExtendInt32) \
|
||||
_(SignExtendInt64) \
|
||||
_(MinMax) \
|
||||
_(Abs) \
|
||||
_(Clz) \
|
||||
|
|
|
|||
|
|
@ -335,32 +335,32 @@ RUrsh::recover(JSContext* cx, SnapshotIterator& iter) const
|
|||
}
|
||||
|
||||
bool
|
||||
MSignExtend::writeRecoverData(CompactBufferWriter& writer) const
|
||||
MSignExtendInt32::writeRecoverData(CompactBufferWriter& writer) const
|
||||
{
|
||||
MOZ_ASSERT(canRecoverOnBailout());
|
||||
writer.writeUnsigned(uint32_t(RInstruction::Recover_SignExtend));
|
||||
writer.writeUnsigned(uint32_t(RInstruction::Recover_SignExtendInt32));
|
||||
MOZ_ASSERT(Mode(uint8_t(mode_)) == mode_);
|
||||
writer.writeByte(uint8_t(mode_));
|
||||
return true;
|
||||
}
|
||||
|
||||
RSignExtend::RSignExtend(CompactBufferReader& reader)
|
||||
RSignExtendInt32::RSignExtendInt32(CompactBufferReader& reader)
|
||||
{
|
||||
mode_ = reader.readByte();
|
||||
}
|
||||
|
||||
bool
|
||||
RSignExtend::recover(JSContext* cx, SnapshotIterator& iter) const
|
||||
RSignExtendInt32::recover(JSContext* cx, SnapshotIterator& iter) const
|
||||
{
|
||||
RootedValue operand(cx, iter.read());
|
||||
|
||||
int32_t result;
|
||||
switch (MSignExtend::Mode(mode_)) {
|
||||
case MSignExtend::Byte:
|
||||
switch (MSignExtendInt32::Mode(mode_)) {
|
||||
case MSignExtendInt32::Byte:
|
||||
if (!js::SignExtendOperation<int8_t>(cx, operand, &result))
|
||||
return false;
|
||||
break;
|
||||
case MSignExtend::Half:
|
||||
case MSignExtendInt32::Half:
|
||||
if (!js::SignExtendOperation<int16_t>(cx, operand, &result))
|
||||
return false;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ namespace jit {
|
|||
_(Lsh) \
|
||||
_(Rsh) \
|
||||
_(Ursh) \
|
||||
_(SignExtend) \
|
||||
_(SignExtendInt32) \
|
||||
_(Add) \
|
||||
_(Sub) \
|
||||
_(Mul) \
|
||||
|
|
@ -246,13 +246,13 @@ class RUrsh final : public RInstruction
|
|||
MOZ_MUST_USE bool recover(JSContext* cx, SnapshotIterator& iter) const;
|
||||
};
|
||||
|
||||
class RSignExtend final : public RInstruction
|
||||
class RSignExtendInt32 final : public RInstruction
|
||||
{
|
||||
private:
|
||||
uint8_t mode_;
|
||||
|
||||
public:
|
||||
RINSTRUCTION_HEADER_NUM_OP_(SignExtend, 1)
|
||||
RINSTRUCTION_HEADER_NUM_OP_(SignExtendInt32, 1)
|
||||
|
||||
MOZ_MUST_USE bool recover(JSContext* cx, SnapshotIterator& iter) const;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -3364,6 +3364,24 @@ CodeGeneratorARM::visitExtendInt32ToInt64(LExtendInt32ToInt64* lir)
|
|||
masm.ma_asr(Imm32(31), output.low, output.high);
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM::visitSignExtendInt64(LSignExtendInt64* lir)
|
||||
{
|
||||
Register64 input = ToRegister64(lir->getInt64Operand(0));
|
||||
Register64 output = ToOutRegister64(lir);
|
||||
switch (lir->mode()) {
|
||||
case MSignExtendInt64::Byte:
|
||||
masm.move8SignExtend(input.low, output.low);
|
||||
break;
|
||||
case MSignExtendInt64::Half:
|
||||
masm.move16SignExtend(input.low, output.low);
|
||||
break;
|
||||
case MSignExtendInt64::Word:
|
||||
break;
|
||||
}
|
||||
masm.ma_asr(Imm32(31), output.low, output.high);
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM::visitDivOrModI64(LDivOrModI64* lir)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -168,6 +168,7 @@ class CodeGeneratorARM : public CodeGeneratorShared
|
|||
|
||||
virtual void visitWrapInt64ToInt32(LWrapInt64ToInt32* lir);
|
||||
virtual void visitExtendInt32ToInt64(LExtendInt32ToInt64* lir);
|
||||
virtual void visitSignExtendInt64(LSignExtendInt64* ins);
|
||||
virtual void visitAddI64(LAddI64* lir);
|
||||
virtual void visitSubI64(LSubI64* lir);
|
||||
virtual void visitMulI64(LMulI64* lir);
|
||||
|
|
|
|||
|
|
@ -1028,3 +1028,9 @@ LIRGeneratorARM::visitExtendInt32ToInt64(MExtendInt32ToInt64* ins)
|
|||
|
||||
lir->setDef(0, def);
|
||||
}
|
||||
|
||||
void
|
||||
LIRGeneratorARM::visitSignExtendInt64(MSignExtendInt64* ins)
|
||||
{
|
||||
defineInt64(new(alloc()) LSignExtendInt64(useInt64RegisterAtStart(ins->input())), ins);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -110,6 +110,7 @@ class LIRGeneratorARM : public LIRGeneratorShared
|
|||
void visitInt64ToFloatingPoint(MInt64ToFloatingPoint* ins);
|
||||
void visitCopySign(MCopySign* ins);
|
||||
void visitExtendInt32ToInt64(MExtendInt32ToInt64* ins);
|
||||
void visitSignExtendInt64(MSignExtendInt64* ins);
|
||||
};
|
||||
|
||||
typedef LIRGeneratorARM LIRGeneratorSpecific;
|
||||
|
|
|
|||
|
|
@ -366,3 +366,9 @@ LIRGeneratorARM64::visitExtendInt32ToInt64(MExtendInt32ToInt64* ins)
|
|||
{
|
||||
MOZ_CRASH("NYI");
|
||||
}
|
||||
|
||||
void
|
||||
LIRGeneratorARM64::visitSignExtendInt64(MSignExtendInt64* ins)
|
||||
{
|
||||
MOZ_CRASH("NYI");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -109,6 +109,7 @@ class LIRGeneratorARM64 : public LIRGeneratorShared
|
|||
void visitInt64ToFloatingPoint(MInt64ToFloatingPoint* ins);
|
||||
void visitCopySign(MCopySign* ins);
|
||||
void visitExtendInt32ToInt64(MExtendInt32ToInt64* ins);
|
||||
void visitSignExtendInt64(MSignExtendInt64* ins);
|
||||
};
|
||||
|
||||
typedef LIRGeneratorARM64 LIRGeneratorSpecific;
|
||||
|
|
|
|||
|
|
@ -92,6 +92,7 @@ class LIRGeneratorNone : public LIRGeneratorShared
|
|||
void visitWasmTruncateToInt64(MWasmTruncateToInt64*) { MOZ_CRASH(); }
|
||||
void visitInt64ToFloatingPoint(MInt64ToFloatingPoint*) { MOZ_CRASH(); }
|
||||
void visitExtendInt32ToInt64(MExtendInt32ToInt64* ins) { MOZ_CRASH(); }
|
||||
void visitSignExtendInt64(MSignExtendInt64* ins) { MOZ_CRASH(); }
|
||||
};
|
||||
|
||||
typedef LIRGeneratorNone LIRGeneratorSpecific;
|
||||
|
|
|
|||
|
|
@ -2702,19 +2702,34 @@ class LShiftI64 : public LInstructionHelper<INT64_PIECES, INT64_PIECES + 1, 0>
|
|||
};
|
||||
|
||||
// Sign extension
|
||||
class LSignExtend : public LInstructionHelper<1, 1, 0>
|
||||
class LSignExtendInt32 : public LInstructionHelper<1, 1, 0>
|
||||
{
|
||||
MSignExtend::Mode mode_;
|
||||
MSignExtendInt32::Mode mode_;
|
||||
|
||||
public:
|
||||
LIR_HEADER(SignExtend);
|
||||
explicit LSignExtend(const LAllocation& num, MSignExtend::Mode mode)
|
||||
LIR_HEADER(SignExtendInt32);
|
||||
explicit LSignExtendInt32(const LAllocation& num, MSignExtendInt32::Mode mode)
|
||||
: mode_(mode)
|
||||
{
|
||||
setOperand(0, num);
|
||||
}
|
||||
|
||||
MSignExtend::Mode mode() { return mode_; }
|
||||
MSignExtendInt32::Mode mode() { return mode_; }
|
||||
};
|
||||
|
||||
class LSignExtendInt64 : public LInstructionHelper<INT64_PIECES, INT64_PIECES, 0>
|
||||
{
|
||||
public:
|
||||
LIR_HEADER(SignExtendInt64)
|
||||
explicit LSignExtendInt64(const LInt64Allocation& input) {
|
||||
setInt64Operand(0, input);
|
||||
}
|
||||
|
||||
const MSignExtendInt64* mir() const {
|
||||
return mir_->toSignExtendInt64();
|
||||
}
|
||||
|
||||
MSignExtendInt64::Mode mode() const { return mir()->mode(); }
|
||||
};
|
||||
|
||||
class LUrshD : public LBinaryMath<1>
|
||||
|
|
|
|||
|
|
@ -73,7 +73,8 @@
|
|||
_(BitOpV) \
|
||||
_(ShiftI) \
|
||||
_(ShiftI64) \
|
||||
_(SignExtend) \
|
||||
_(SignExtendInt32) \
|
||||
_(SignExtendInt64) \
|
||||
_(UrshD) \
|
||||
_(Return) \
|
||||
_(Throw) \
|
||||
|
|
|
|||
|
|
@ -472,6 +472,9 @@ class Assembler : public AssemblerX86Shared
|
|||
|
||||
void movsbq(const Operand& src, Register dest) {
|
||||
switch (src.kind()) {
|
||||
case Operand::REG:
|
||||
masm.movsbq_rr(src.reg(), dest.encoding());
|
||||
break;
|
||||
case Operand::MEM_REG_DISP:
|
||||
masm.movsbq_mr(src.disp(), src.base(), dest.encoding());
|
||||
break;
|
||||
|
|
@ -491,6 +494,9 @@ class Assembler : public AssemblerX86Shared
|
|||
|
||||
void movswq(const Operand& src, Register dest) {
|
||||
switch (src.kind()) {
|
||||
case Operand::REG:
|
||||
masm.movswq_rr(src.reg(), dest.encoding());
|
||||
break;
|
||||
case Operand::MEM_REG_DISP:
|
||||
masm.movswq_mr(src.disp(), src.base(), dest.encoding());
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -652,6 +652,11 @@ class BaseAssemblerX64 : public BaseAssembler
|
|||
m_formatter.immediate64(imm);
|
||||
}
|
||||
|
||||
void movsbq_rr(RegisterID src, RegisterID dst)
|
||||
{
|
||||
spew("movsbq %s, %s", GPReg32Name(src), GPReg64Name(dst));
|
||||
m_formatter.twoByteOp64(OP2_MOVSX_GvEb, src, dst);
|
||||
}
|
||||
void movsbq_mr(int32_t offset, RegisterID base, RegisterID dst)
|
||||
{
|
||||
spew("movsbq " MEM_ob ", %s", ADDR_ob(offset, base), GPReg64Name(dst));
|
||||
|
|
@ -663,6 +668,11 @@ class BaseAssemblerX64 : public BaseAssembler
|
|||
m_formatter.twoByteOp64(OP2_MOVSX_GvEb, offset, base, index, scale, dst);
|
||||
}
|
||||
|
||||
void movswq_rr(RegisterID src, RegisterID dst)
|
||||
{
|
||||
spew("movswq %s, %s", GPReg32Name(src), GPReg64Name(dst));
|
||||
m_formatter.twoByteOp64(OP2_MOVSX_GvEw, src, dst);
|
||||
}
|
||||
void movswq_mr(int32_t offset, RegisterID base, RegisterID dst)
|
||||
{
|
||||
spew("movswq " MEM_ob ", %s", ADDR_ob(offset, base), GPReg64Name(dst));
|
||||
|
|
|
|||
|
|
@ -794,6 +794,24 @@ CodeGeneratorX64::visitExtendInt32ToInt64(LExtendInt32ToInt64* lir)
|
|||
masm.movslq(ToOperand(input), output);
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorX64::visitSignExtendInt64(LSignExtendInt64* ins)
|
||||
{
|
||||
Register64 input = ToRegister64(ins->getInt64Operand(0));
|
||||
Register64 output = ToOutRegister64(ins);
|
||||
switch (ins->mode()) {
|
||||
case MSignExtendInt64::Byte:
|
||||
masm.movsbq(Operand(input.reg), output.reg);
|
||||
break;
|
||||
case MSignExtendInt64::Half:
|
||||
masm.movswq(Operand(input.reg), output.reg);
|
||||
break;
|
||||
case MSignExtendInt64::Word:
|
||||
masm.movslq(Operand(input.reg), output.reg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorX64::visitWasmTruncateToInt64(LWasmTruncateToInt64* lir)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@ class CodeGeneratorX64 : public CodeGeneratorX86Shared
|
|||
void visitTruncateFToInt32(LTruncateFToInt32* ins);
|
||||
void visitWrapInt64ToInt32(LWrapInt64ToInt32* lir);
|
||||
void visitExtendInt32ToInt64(LExtendInt32ToInt64* lir);
|
||||
void visitSignExtendInt64(LSignExtendInt64* ins);
|
||||
void visitWasmTruncateToInt64(LWasmTruncateToInt64* lir);
|
||||
void visitInt64ToFloatingPoint(LInt64ToFloatingPoint* lir);
|
||||
void visitLoadTypedArrayElementStatic(LLoadTypedArrayElementStatic* ins);
|
||||
|
|
|
|||
|
|
@ -486,3 +486,10 @@ LIRGeneratorX64::visitExtendInt32ToInt64(MExtendInt32ToInt64* ins)
|
|||
{
|
||||
defineInt64(new(alloc()) LExtendInt32ToInt64(useAtStart(ins->input())), ins);
|
||||
}
|
||||
|
||||
void
|
||||
LIRGeneratorX64::visitSignExtendInt64(MSignExtendInt64* ins)
|
||||
{
|
||||
defineInt64(new(alloc()) LSignExtendInt64(useInt64RegisterAtStart(ins->input())), ins);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -69,6 +69,7 @@ class LIRGeneratorX64 : public LIRGeneratorX86Shared
|
|||
void visitWasmTruncateToInt64(MWasmTruncateToInt64* ins);
|
||||
void visitInt64ToFloatingPoint(MInt64ToFloatingPoint* ins);
|
||||
void visitExtendInt32ToInt64(MExtendInt32ToInt64* ins);
|
||||
void visitSignExtendInt64(MSignExtendInt64* ins);
|
||||
};
|
||||
|
||||
typedef LIRGeneratorX64 LIRGeneratorSpecific;
|
||||
|
|
|
|||
|
|
@ -1180,6 +1180,28 @@ CodeGeneratorX86::visitExtendInt32ToInt64(LExtendInt32ToInt64* lir)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorX86::visitSignExtendInt64(LSignExtendInt64* lir)
|
||||
{
|
||||
Register64 input = ToRegister64(lir->getInt64Operand(0));
|
||||
Register64 output = ToOutRegister64(lir);
|
||||
MOZ_ASSERT(input.low == eax);
|
||||
MOZ_ASSERT(output.low == eax);
|
||||
MOZ_ASSERT(input.high == edx);
|
||||
MOZ_ASSERT(output.high == edx);
|
||||
switch (lir->mode()) {
|
||||
case MSignExtendInt64::Byte:
|
||||
masm.move8SignExtend(eax, eax);
|
||||
break;
|
||||
case MSignExtendInt64::Half:
|
||||
masm.move16SignExtend(eax, eax);
|
||||
break;
|
||||
case MSignExtendInt64::Word:
|
||||
break;
|
||||
}
|
||||
masm.cdq();
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorX86::visitWrapInt64ToInt32(LWrapInt64ToInt32* lir)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -77,6 +77,7 @@ class CodeGeneratorX86 : public CodeGeneratorX86Shared
|
|||
void visitWasmReinterpretFromI64(LWasmReinterpretFromI64* lir);
|
||||
void visitWasmReinterpretToI64(LWasmReinterpretToI64* lir);
|
||||
void visitExtendInt32ToInt64(LExtendInt32ToInt64* lir);
|
||||
void visitSignExtendInt64(LSignExtendInt64* ins);
|
||||
void visitWrapInt64ToInt32(LWrapInt64ToInt32* lir);
|
||||
void visitClzI64(LClzI64* lir);
|
||||
void visitCtzI64(LCtzI64* lir);
|
||||
|
|
|
|||
|
|
@ -649,3 +649,14 @@ LIRGeneratorX86::visitExtendInt32ToInt64(MExtendInt32ToInt64* ins)
|
|||
LAllocation(AnyRegister(eax))));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
LIRGeneratorX86::visitSignExtendInt64(MSignExtendInt64* ins)
|
||||
{
|
||||
// Here we'll end up using cdq which requires input and output in (edx,eax).
|
||||
LSignExtendInt64* lir =
|
||||
new(alloc()) LSignExtendInt64(useInt64RegisterAtStart(ins->input()));
|
||||
defineInt64Fixed(lir, ins, LInt64Allocation(LAllocation(AnyRegister(edx)),
|
||||
LAllocation(AnyRegister(eax))));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -76,6 +76,7 @@ class LIRGeneratorX86 : public LIRGeneratorX86Shared
|
|||
void visitWasmTruncateToInt64(MWasmTruncateToInt64* ins);
|
||||
void visitInt64ToFloatingPoint(MInt64ToFloatingPoint* ins);
|
||||
void visitExtendInt32ToInt64(MExtendInt32ToInt64* ins);
|
||||
void visitSignExtendInt64(MSignExtendInt64* ins);
|
||||
void lowerPhi(MPhi* phi);
|
||||
|
||||
static bool allowTypedElementHoleCheck() {
|
||||
|
|
|
|||
|
|
@ -2719,6 +2719,38 @@ class BaseCompiler
|
|||
return x0;
|
||||
}
|
||||
|
||||
RegI64 popI64ForSignExtendI64() {
|
||||
#if defined(JS_CODEGEN_X86)
|
||||
need2xI32(specific_edx, specific_eax);
|
||||
// Low on top, high underneath
|
||||
return popI64ToSpecific(RegI64(Register64(specific_edx.reg, specific_eax.reg)));
|
||||
#else
|
||||
return popI64();
|
||||
#endif
|
||||
}
|
||||
|
||||
void signExtendI64_8(RegI64 r) {
|
||||
#if defined(JS_CODEGEN_X64)
|
||||
masm.movsbq(Operand(r.reg.reg), r.reg.reg);
|
||||
#elif defined(JS_CODEGEN_X86) || defined(JS_CODEGEN_ARM)
|
||||
masm.move8SignExtend(r.reg.low, r.reg.low);
|
||||
signExtendI32ToI64(RegI32(r.reg.low), r);
|
||||
#else
|
||||
MOZ_CRASH("Basecompiler platform hook: signExtendI64_8");
|
||||
#endif
|
||||
}
|
||||
|
||||
void signExtendI64_16(RegI64 r) {
|
||||
#if defined(JS_CODEGEN_X64)
|
||||
masm.movswq(Operand(r.reg.reg), r.reg.reg);
|
||||
#elif defined(JS_CODEGEN_X86) || defined(JS_CODEGEN_ARM)
|
||||
masm.move16SignExtend(r.reg.low, r.reg.low);
|
||||
signExtendI32ToI64(RegI32(r.reg.low), r);
|
||||
#else
|
||||
MOZ_CRASH("Basecompiler platform hook: signExtendI64_16");
|
||||
#endif
|
||||
}
|
||||
|
||||
void signExtendI32ToI64(RegI32 src, RegI64 dest) {
|
||||
#if defined(JS_CODEGEN_X64)
|
||||
masm.movslq(src.reg, dest.reg.reg);
|
||||
|
|
@ -3703,6 +3735,11 @@ class BaseCompiler
|
|||
template<bool isUnsigned> MOZ_MUST_USE bool emitTruncateF64ToI64();
|
||||
#endif
|
||||
void emitWrapI64ToI32();
|
||||
void emitExtendI32_8();
|
||||
void emitExtendI32_16();
|
||||
void emitExtendI64_8();
|
||||
void emitExtendI64_16();
|
||||
void emitExtendI64_32();
|
||||
void emitExtendI32ToI64();
|
||||
void emitExtendU32ToI64();
|
||||
void emitReinterpretF32AsI32();
|
||||
|
|
@ -4593,6 +4630,48 @@ BaseCompiler::emitWrapI64ToI32()
|
|||
pushI32(i0);
|
||||
}
|
||||
|
||||
void
|
||||
BaseCompiler::emitExtendI32_8()
|
||||
{
|
||||
RegI32 r = popI32();
|
||||
masm.move8SignExtend(r.reg, r.reg);
|
||||
pushI32(r);
|
||||
}
|
||||
|
||||
void
|
||||
BaseCompiler::emitExtendI32_16()
|
||||
{
|
||||
RegI32 r = popI32();
|
||||
masm.move16SignExtend(r.reg, r.reg);
|
||||
pushI32(r);
|
||||
}
|
||||
|
||||
void
|
||||
BaseCompiler::emitExtendI64_8()
|
||||
{
|
||||
RegI64 r = popI64ForSignExtendI64();
|
||||
signExtendI64_8(r);
|
||||
pushI64(r);
|
||||
}
|
||||
|
||||
void
|
||||
BaseCompiler::emitExtendI64_16()
|
||||
{
|
||||
RegI64 r = popI64ForSignExtendI64();
|
||||
signExtendI64_16(r);
|
||||
pushI64(r);
|
||||
}
|
||||
|
||||
void
|
||||
BaseCompiler::emitExtendI64_32()
|
||||
{
|
||||
RegI64 x0 = popI64ForSignExtendI64();
|
||||
RegI32 r0 = RegI32(lowPart(x0));
|
||||
signExtendI32ToI64(r0, x0);
|
||||
pushI64(x0);
|
||||
// Note: no need to free r0, since it is part of x0
|
||||
}
|
||||
|
||||
void
|
||||
BaseCompiler::emitExtendI32ToI64()
|
||||
{
|
||||
|
|
@ -7098,6 +7177,18 @@ BaseCompiler::emitBody()
|
|||
case uint16_t(Op::I32AtomicsExchange):
|
||||
MOZ_CRASH("Unimplemented Atomics");
|
||||
|
||||
// Sign extensions
|
||||
case uint16_t(Op::I32Extend8S):
|
||||
CHECK_NEXT(emitConversion(emitExtendI32_8, ValType::I32, ValType::I32));
|
||||
case uint16_t(Op::I32Extend16S):
|
||||
CHECK_NEXT(emitConversion(emitExtendI32_16, ValType::I32, ValType::I32));
|
||||
case uint16_t(Op::I64Extend8S):
|
||||
CHECK_NEXT(emitConversion(emitExtendI64_8, ValType::I64, ValType::I64));
|
||||
case uint16_t(Op::I64Extend16S):
|
||||
CHECK_NEXT(emitConversion(emitExtendI64_16, ValType::I64, ValType::I64));
|
||||
case uint16_t(Op::I64Extend32S):
|
||||
CHECK_NEXT(emitConversion(emitExtendI64_32, ValType::I64, ValType::I64));
|
||||
|
||||
// Memory Related
|
||||
case uint16_t(Op::GrowMemory):
|
||||
CHECK_NEXT(emitGrowMemory());
|
||||
|
|
|
|||
|
|
@ -288,6 +288,13 @@ enum class Op
|
|||
F32ReinterpretI32 = 0xbe,
|
||||
F64ReinterpretI64 = 0xbf,
|
||||
|
||||
// Sign extension
|
||||
I32Extend8S = 0xc0,
|
||||
I32Extend16S = 0xc1,
|
||||
I64Extend8S = 0xc2,
|
||||
I64Extend16S = 0xc3,
|
||||
I64Extend32S = 0xc4,
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// The rest of these operators are currently only emitted internally when
|
||||
// compiling asm.js and are rejected by wasm validation.
|
||||
|
|
|
|||
|
|
@ -193,6 +193,11 @@ wasm::Classify(Op op)
|
|||
case Op::F64ConvertUI64:
|
||||
case Op::F64ReinterpretI64:
|
||||
case Op::F64PromoteF32:
|
||||
case Op::I32Extend8S:
|
||||
case Op::I32Extend16S:
|
||||
case Op::I64Extend8S:
|
||||
case Op::I64Extend16S:
|
||||
case Op::I64Extend32S:
|
||||
return OpKind::Conversion;
|
||||
case Op::I32Load8S:
|
||||
case Op::I32Load8U:
|
||||
|
|
|
|||
|
|
@ -1300,6 +1300,17 @@ AstDecodeExpr(AstDecodeContext& c)
|
|||
if (!AstDecodeConversion(c, ValType::F32, ValType::F64, Op(op)))
|
||||
return false;
|
||||
break;
|
||||
case uint16_t(Op::I32Extend8S):
|
||||
case uint16_t(Op::I32Extend16S):
|
||||
if (!AstDecodeConversion(c, ValType::I32, ValType::I32, Op(op)))
|
||||
return false;
|
||||
break;
|
||||
case uint16_t(Op::I64Extend8S):
|
||||
case uint16_t(Op::I64Extend16S):
|
||||
case uint16_t(Op::I64Extend32S):
|
||||
if (!AstDecodeConversion(c, ValType::I64, ValType::I64, Op(op)))
|
||||
return false;
|
||||
break;
|
||||
case uint16_t(Op::I32Load8S):
|
||||
case uint16_t(Op::I32Load8U):
|
||||
if (!AstDecodeLoad(c, ValType::I32, 1, Op(op)))
|
||||
|
|
|
|||
|
|
@ -713,6 +713,11 @@ RenderConversionOperator(WasmRenderContext& c, AstConversionOperator& conv)
|
|||
case Op::F64ConvertUI64: opStr = "f64.convert_u/i64"; break;
|
||||
case Op::F64ReinterpretI64: opStr = "f64.reinterpret/i64"; break;
|
||||
case Op::F64PromoteF32: opStr = "f64.promote/f32"; break;
|
||||
case Op::I32Extend8S: opStr = "i32.extend8_s"; break;
|
||||
case Op::I32Extend16S: opStr = "i32.extend16_s"; break;
|
||||
case Op::I64Extend8S: opStr = "i64.extend8_s"; break;
|
||||
case Op::I64Extend16S: opStr = "i64.extend16_s"; break;
|
||||
case Op::I64Extend32S: opStr = "i64.extend32_s"; break;
|
||||
case Op::I32Eqz: opStr = "i32.eqz"; break;
|
||||
case Op::I64Eqz: opStr = "i64.eqz"; break;
|
||||
default: return Fail(c, "unexpected conversion operator");
|
||||
|
|
|
|||
|
|
@ -347,6 +347,13 @@ DecodeFunctionBodyExprs(FunctionDecoder& f)
|
|||
CHECK(f.iter().readConversion(ValType::I64, ValType::F64, nullptr));
|
||||
case uint16_t(Op::F64PromoteF32):
|
||||
CHECK(f.iter().readConversion(ValType::F32, ValType::F64, nullptr));
|
||||
case uint16_t(Op::I32Extend8S):
|
||||
case uint16_t(Op::I32Extend16S):
|
||||
CHECK(f.iter().readConversion(ValType::I32, ValType::I32, nullptr));
|
||||
case uint16_t(Op::I64Extend8S):
|
||||
case uint16_t(Op::I64Extend16S):
|
||||
case uint16_t(Op::I64Extend32S):
|
||||
CHECK(f.iter().readConversion(ValType::I64, ValType::I64, nullptr));
|
||||
case uint16_t(Op::I32Load8S):
|
||||
case uint16_t(Op::I32Load8U):
|
||||
CHECK(f.checkHasMemory() && f.iter().readLoad(ValType::I32, 1, nullptr));
|
||||
|
|
|
|||
|
|
@ -467,6 +467,41 @@ class FunctionCompiler
|
|||
return ins;
|
||||
}
|
||||
|
||||
MDefinition* signExtend(MDefinition* op, uint32_t srcSize, uint32_t targetSize)
|
||||
{
|
||||
if (inDeadCode())
|
||||
return nullptr;
|
||||
MInstruction* ins;
|
||||
switch (targetSize) {
|
||||
case 4: {
|
||||
MSignExtendInt32::Mode mode;
|
||||
switch (srcSize) {
|
||||
case 1: mode = MSignExtendInt32::Byte; break;
|
||||
case 2: mode = MSignExtendInt32::Half; break;
|
||||
default: MOZ_CRASH("Bad sign extension");
|
||||
}
|
||||
ins = MSignExtendInt32::New(alloc(), op, mode);
|
||||
break;
|
||||
}
|
||||
case 8: {
|
||||
MSignExtendInt64::Mode mode;
|
||||
switch (srcSize) {
|
||||
case 1: mode = MSignExtendInt64::Byte; break;
|
||||
case 2: mode = MSignExtendInt64::Half; break;
|
||||
case 4: mode = MSignExtendInt64::Word; break;
|
||||
default: MOZ_CRASH("Bad sign extension");
|
||||
}
|
||||
ins = MSignExtendInt64::New(alloc(), op, mode);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
MOZ_CRASH("Bad sign extension");
|
||||
}
|
||||
}
|
||||
curBlock_->add(ins);
|
||||
return ins;
|
||||
}
|
||||
|
||||
MDefinition* convertI64ToFloatingPoint(MDefinition* op, MIRType type, bool isUnsigned)
|
||||
{
|
||||
if (inDeadCode())
|
||||
|
|
@ -1945,6 +1980,18 @@ EmitTruncate(FunctionCompiler& f, ValType operandType, ValType resultType,
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
EmitSignExtend(FunctionCompiler& f, uint32_t srcSize, uint32_t targetSize)
|
||||
{
|
||||
MDefinition* input;
|
||||
ValType type = targetSize == 4 ? ValType::I32 : ValType::I64;
|
||||
if (!f.iter().readConversion(type, type, &input))
|
||||
return false;
|
||||
|
||||
f.iter().setResult(f.signExtend(input, srcSize, targetSize));
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
EmitExtendI32(FunctionCompiler& f, bool isUnsigned)
|
||||
{
|
||||
|
|
@ -2759,6 +2806,18 @@ EmitExpr(FunctionCompiler& f)
|
|||
case Op::F64ReinterpretI64:
|
||||
return EmitReinterpret(f, ValType::F64, ValType::I64, MIRType::Double);
|
||||
|
||||
// Sign extensions
|
||||
case Op::I32Extend8S:
|
||||
return EmitSignExtend(f, 1, 4);
|
||||
case Op::I32Extend16S:
|
||||
return EmitSignExtend(f, 2, 4);
|
||||
case Op::I64Extend8S:
|
||||
return EmitSignExtend(f, 1, 8);
|
||||
case Op::I64Extend16S:
|
||||
return EmitSignExtend(f, 2, 8);
|
||||
case Op::I64Extend32S:
|
||||
return EmitSignExtend(f, 4, 8);
|
||||
|
||||
// Comparisons
|
||||
case Op::I32Eq:
|
||||
return EmitComparison(f, ValType::I32, JSOP_EQ, MCompare::Compare_Int32);
|
||||
|
|
|
|||
|
|
@ -925,6 +925,16 @@ WasmTokenStream::next()
|
|||
case 'e':
|
||||
if (consume(u"eq"))
|
||||
return WasmToken(WasmToken::ComparisonOpcode, Op::F32Eq, begin, cur_);
|
||||
if (consume(u"extend8_s"))
|
||||
return WasmToken(WasmToken::ConversionOpcode, Op::I32Extend8S, begin, cur_);
|
||||
if (consume(u"extend16_s"))
|
||||
return WasmToken(WasmToken::ConversionOpcode, Op::I32Extend16S, begin, cur_);
|
||||
if (consume(u"extend8_s"))
|
||||
return WasmToken(WasmToken::ConversionOpcode, Op::I64Extend8S, begin, cur_);
|
||||
if (consume(u"extend16_s"))
|
||||
return WasmToken(WasmToken::ConversionOpcode, Op::I64Extend16S, begin, cur_);
|
||||
if (consume(u"extend32_s"))
|
||||
return WasmToken(WasmToken::ConversionOpcode, Op::I64Extend32S, begin, cur_);
|
||||
break;
|
||||
case 'f':
|
||||
if (consume(u"floor"))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue