mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-26 19:55:39 +00:00
Bug 1279248 - Part 25: Extra tests, r=lth
This commit is contained in:
parent
ec0937ad53
commit
69caf976c6
@ -96,6 +96,9 @@ if (hasI64()) {
|
||||
testConversion('f32', 'convert_s', 'i64', "0x7fffffffffffffff", 9223372036854775807.0);
|
||||
testConversion('f32', 'convert_s', 'i64', "0x8000000000000000", -9223372036854775808.0);
|
||||
testConversion('f32', 'convert_s', 'i64', "0x11db9e76a2483", 314159275180032.0);
|
||||
testConversion('f32', 'convert_s', 'i64', "0x7fffffff", 2147483648.0); // closesth approx.
|
||||
testConversion('f32', 'convert_s', 'i64', "0x80000000", 2147483648.0);
|
||||
testConversion('f32', 'convert_s', 'i64', "0x80000001", 2147483648.0); // closesth approx.
|
||||
|
||||
testConversion('f64', 'convert_s', 'i64', 1, 1.0);
|
||||
testConversion('f64', 'convert_s', 'i64', -1, -1.0);
|
||||
@ -103,6 +106,9 @@ if (hasI64()) {
|
||||
testConversion('f64', 'convert_s', 'i64', "0x7fffffffffffffff", 9223372036854775807.0);
|
||||
testConversion('f64', 'convert_s', 'i64', "0x8000000000000000", -9223372036854775808.0);
|
||||
testConversion('f64', 'convert_s', 'i64', "0x10969d374b968e", 4669201609102990);
|
||||
testConversion('f64', 'convert_s', 'i64', "0x7fffffff", 2147483647.0);
|
||||
testConversion('f64', 'convert_s', 'i64', "0x80000000", 2147483648.0);
|
||||
testConversion('f64', 'convert_s', 'i64', "0x80000001", 2147483649.0);
|
||||
|
||||
testConversion('f32', 'convert_u', 'i64', 1, 1.0);
|
||||
testConversion('f32', 'convert_u', 'i64', 0, 0.0);
|
||||
|
@ -158,6 +158,13 @@ if (hasI64()) {
|
||||
testBinary64('mul', 40, 2, 80);
|
||||
testBinary64('mul', -1, 2, -2);
|
||||
testBinary64('mul', 0x123456, "0x9876543210", "0xad77d2c5f941160");
|
||||
testBinary64('mul', 2, -1, -2);
|
||||
testBinary64('mul', "0x80000000", -1, -2147483648);
|
||||
testBinary64('mul', "0x7fffffff", -1, -2147483647);
|
||||
testBinary64('mul', "0x7fffffffffffffff", -1, "0x8000000000000001");
|
||||
testBinary64('mul', 2, 2, 4);
|
||||
testBinary64('mul', "0x80000000", 2, "0x100000000");
|
||||
testBinary64('mul', "0x7fffffff", 2, "0xfffffffe");
|
||||
testBinary64('div_s', -40, 2, -20);
|
||||
testBinary64('div_s', "0x1234567887654321", 2, "0x91a2b3c43b2a190");
|
||||
testBinary64('div_s', "0x1234567887654321", "0x1000000000", "0x1234567");
|
||||
|
@ -954,7 +954,8 @@ class MacroAssembler : public MacroAssemblerSpecific
|
||||
DEFINED_ON(x86, x64);
|
||||
inline void branch64(Condition cond, Register64 lhs, Register64 rhs, Label* label)
|
||||
DEFINED_ON(x86, x64);
|
||||
// Only NotEqual conditions are allowed for the branch64 variants with Address as lhs.
|
||||
// On x86 and x64 NotEqual and Equal conditions are allowed for the branch64 variants
|
||||
// with Address as lhs. On others only the NotEqual condition.
|
||||
inline void branch64(Condition cond, const Address& lhs, Imm64 val, Label* label) PER_ARCH;
|
||||
|
||||
// Compare the value at |lhs| with the value at |rhs|. The scratch
|
||||
|
@ -514,12 +514,14 @@ MacroAssembler::maxDouble(FloatRegister other, FloatRegister srcDest, bool handl
|
||||
void
|
||||
MacroAssembler::lshiftPtr(Imm32 imm, Register dest)
|
||||
{
|
||||
MOZ_ASSERT(0 <= imm.value && imm.value < 32);
|
||||
ma_lsl(imm, dest, dest);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::lshift64(Imm32 imm, Register64 dest)
|
||||
{
|
||||
MOZ_ASSERT(0 <= imm.value && imm.value < 64);
|
||||
as_mov(dest.high, lsl(dest.high, imm.value));
|
||||
as_orr(dest.high, dest.high, lsr(dest.low, 32 - imm.value));
|
||||
as_mov(dest.low, lsl(dest.low, imm.value));
|
||||
@ -534,12 +536,14 @@ MacroAssembler::lshift32(Register src, Register dest)
|
||||
void
|
||||
MacroAssembler::lshift32(Imm32 imm, Register dest)
|
||||
{
|
||||
MOZ_ASSERT(0 <= imm.value && imm.value < 32);
|
||||
lshiftPtr(imm, dest);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::rshiftPtr(Imm32 imm, Register dest)
|
||||
{
|
||||
MOZ_ASSERT(0 <= imm.value && imm.value < 32);
|
||||
ma_lsr(imm, dest, dest);
|
||||
}
|
||||
|
||||
@ -552,12 +556,14 @@ MacroAssembler::rshift32(Register src, Register dest)
|
||||
void
|
||||
MacroAssembler::rshift32(Imm32 imm, Register dest)
|
||||
{
|
||||
MOZ_ASSERT(0 <= imm.value && imm.value < 32);
|
||||
rshiftPtr(imm, dest);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::rshiftPtrArithmetic(Imm32 imm, Register dest)
|
||||
{
|
||||
MOZ_ASSERT(0 <= imm.value && imm.value < 32);
|
||||
ma_asr(imm, dest, dest);
|
||||
}
|
||||
|
||||
@ -570,12 +576,14 @@ MacroAssembler::rshift32Arithmetic(Register src, Register dest)
|
||||
void
|
||||
MacroAssembler::rshift32Arithmetic(Imm32 imm, Register dest)
|
||||
{
|
||||
MOZ_ASSERT(0 <= imm.value && imm.value < 32);
|
||||
rshiftPtrArithmetic(imm, dest);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::rshift64(Imm32 imm, Register64 dest)
|
||||
{
|
||||
MOZ_ASSERT(0 <= imm.value && imm.value < 64);
|
||||
as_mov(dest.low, lsr(dest.low, imm.value));
|
||||
as_orr(dest.low, dest.low, lsl(dest.high, 32 - imm.value));
|
||||
as_mov(dest.high, lsr(dest.high, imm.value));
|
||||
|
@ -541,12 +541,14 @@ MacroAssembler::maxDouble(FloatRegister other, FloatRegister srcDest, bool handl
|
||||
void
|
||||
MacroAssembler::lshiftPtr(Imm32 imm, Register dest)
|
||||
{
|
||||
MOZ_ASSERT(0 <= imm.value && imm.value < 64);
|
||||
Lsl(ARMRegister(dest, 64), ARMRegister(dest, 64), imm.value);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::lshift64(Imm32 imm, Register64 dest)
|
||||
{
|
||||
MOZ_ASSERT(0 <= imm.value && imm.value < 64);
|
||||
lshiftPtr(imm, dest.reg);
|
||||
}
|
||||
|
||||
@ -559,18 +561,21 @@ MacroAssembler::lshift32(Register shift, Register dest)
|
||||
void
|
||||
MacroAssembler::lshift32(Imm32 imm, Register dest)
|
||||
{
|
||||
MOZ_ASSERT(0 <= imm.value && imm.value < 32);
|
||||
Lsl(ARMRegister(dest, 32), ARMRegister(dest, 32), imm.value);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::rshiftPtr(Imm32 imm, Register dest)
|
||||
{
|
||||
MOZ_ASSERT(0 <= imm.value && imm.value < 64);
|
||||
Lsr(ARMRegister(dest, 64), ARMRegister(dest, 64), imm.value);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::rshiftPtr(Imm32 imm, Register src, Register dest)
|
||||
{
|
||||
MOZ_ASSERT(0 <= imm.value && imm.value < 64);
|
||||
Lsr(ARMRegister(dest, 64), ARMRegister(src, 64), imm.value);
|
||||
}
|
||||
|
||||
@ -583,12 +588,14 @@ MacroAssembler::rshift32(Register shift, Register dest)
|
||||
void
|
||||
MacroAssembler::rshift32(Imm32 imm, Register dest)
|
||||
{
|
||||
MOZ_ASSERT(0 <= imm.value && imm.value < 32);
|
||||
Lsr(ARMRegister(dest, 32), ARMRegister(dest, 32), imm.value);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::rshiftPtrArithmetic(Imm32 imm, Register dest)
|
||||
{
|
||||
MOZ_ASSERT(0 <= imm.value && imm.value < 64);
|
||||
Asr(ARMRegister(dest, 64), ARMRegister(dest, 64), imm.value);
|
||||
}
|
||||
|
||||
@ -601,12 +608,14 @@ MacroAssembler::rshift32Arithmetic(Register shift, Register dest)
|
||||
void
|
||||
MacroAssembler::rshift32Arithmetic(Imm32 imm, Register dest)
|
||||
{
|
||||
MOZ_ASSERT(0 <= imm.value && imm.value < 32);
|
||||
Asr(ARMRegister(dest, 32), ARMRegister(dest, 32), imm.value);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::rshift64(Imm32 imm, Register64 dest)
|
||||
{
|
||||
MOZ_ASSERT(0 <= imm.value && imm.value < 64);
|
||||
rshiftPtr(imm, dest.reg);
|
||||
}
|
||||
|
||||
|
@ -230,12 +230,14 @@ MacroAssembler::inc64(AbsoluteAddress dest)
|
||||
void
|
||||
MacroAssembler::lshiftPtr(Imm32 imm, Register dest)
|
||||
{
|
||||
MOZ_ASSERT(0 <= imm.value && imm.value < 32);
|
||||
ma_sll(dest, dest, imm);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::lshift64(Imm32 imm, Register64 dest)
|
||||
{
|
||||
MOZ_ASSERT(0 <= imm.value && imm.value < 64);
|
||||
ScratchRegisterScope scratch(*this);
|
||||
as_sll(dest.high, dest.high, imm.value);
|
||||
as_srl(scratch, dest.low, 32 - imm.value);
|
||||
@ -246,18 +248,21 @@ MacroAssembler::lshift64(Imm32 imm, Register64 dest)
|
||||
void
|
||||
MacroAssembler::rshiftPtr(Imm32 imm, Register dest)
|
||||
{
|
||||
MOZ_ASSERT(0 <= imm.value && imm.value < 32);
|
||||
ma_srl(dest, dest, imm);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::rshiftPtrArithmetic(Imm32 imm, Register dest)
|
||||
{
|
||||
MOZ_ASSERT(0 <= imm.value && imm.value < 32);
|
||||
ma_sra(dest, dest, imm);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::rshift64(Imm32 imm, Register64 dest)
|
||||
{
|
||||
MOZ_ASSERT(0 <= imm.value && imm.value < 64);
|
||||
ScratchRegisterScope scratch(*this);
|
||||
as_srl(dest.low, dest.low, imm.value);
|
||||
as_sll(scratch, dest.high, 32 - imm.value);
|
||||
|
@ -177,30 +177,35 @@ MacroAssembler::inc64(AbsoluteAddress dest)
|
||||
void
|
||||
MacroAssembler::lshiftPtr(Imm32 imm, Register dest)
|
||||
{
|
||||
MOZ_ASSERT(0 <= imm.value && imm.value < 64);
|
||||
ma_dsll(dest, dest, imm);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::lshift64(Imm32 imm, Register64 dest)
|
||||
{
|
||||
MOZ_ASSERT(0 <= imm.value && imm.value < 64);
|
||||
ma_dsll(dest.reg, dest.reg, imm);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::rshiftPtr(Imm32 imm, Register dest)
|
||||
{
|
||||
MOZ_ASSERT(0 <= imm.value && imm.value < 64);
|
||||
ma_dsrl(dest, dest, imm);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::rshiftPtrArithmetic(Imm32 imm, Register dest)
|
||||
{
|
||||
MOZ_ASSERT(0 <= imm.value && imm.value < 64);
|
||||
ma_dsra(dest, dest, imm);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::rshift64(Imm32 imm, Register64 dest)
|
||||
{
|
||||
MOZ_ASSERT(0 <= imm.value && imm.value < 64);
|
||||
ma_dsrl(dest.reg, dest.reg, imm);
|
||||
}
|
||||
|
||||
|
@ -327,12 +327,14 @@ MacroAssembler::neg64(Register64 reg)
|
||||
void
|
||||
MacroAssembler::lshiftPtr(Imm32 imm, Register dest)
|
||||
{
|
||||
MOZ_ASSERT(0 <= imm.value && imm.value < 64);
|
||||
shlq(imm, dest);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::lshift64(Imm32 imm, Register64 dest)
|
||||
{
|
||||
MOZ_ASSERT(0 <= imm.value && imm.value < 64);
|
||||
lshiftPtr(imm, dest.reg);
|
||||
}
|
||||
|
||||
@ -346,6 +348,7 @@ MacroAssembler::lshift64(Register shift, Register64 srcDest)
|
||||
void
|
||||
MacroAssembler::rshiftPtr(Imm32 imm, Register dest)
|
||||
{
|
||||
MOZ_ASSERT(0 <= imm.value && imm.value < 64);
|
||||
shrq(imm, dest);
|
||||
}
|
||||
|
||||
@ -365,12 +368,14 @@ MacroAssembler::rshift64(Register shift, Register64 srcDest)
|
||||
void
|
||||
MacroAssembler::rshiftPtrArithmetic(Imm32 imm, Register dest)
|
||||
{
|
||||
MOZ_ASSERT(0 <= imm.value && imm.value < 64);
|
||||
sarq(imm, dest);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::rshift64Arithmetic(Imm32 imm, Register64 dest)
|
||||
{
|
||||
MOZ_ASSERT(0 <= imm.value && imm.value < 64);
|
||||
rshiftPtrArithmetic(imm, dest.reg);
|
||||
}
|
||||
|
||||
@ -582,7 +587,7 @@ MacroAssembler::branch64(Condition cond, Register64 lhs, Register64 rhs, Label*
|
||||
void
|
||||
MacroAssembler::branch64(Condition cond, const Address& lhs, Imm64 val, Label* label)
|
||||
{
|
||||
MOZ_ASSERT(cond == Assembler::NotEqual,
|
||||
MOZ_ASSERT(cond == Assembler::NotEqual || cond == Assembler::Equal,
|
||||
"other condition codes not supported");
|
||||
|
||||
branchPtr(cond, lhs, ImmWord(val.value), label);
|
||||
@ -592,7 +597,7 @@ void
|
||||
MacroAssembler::branch64(Condition cond, const Address& lhs, const Address& rhs, Register scratch,
|
||||
Label* label)
|
||||
{
|
||||
MOZ_ASSERT(cond == Assembler::NotEqual,
|
||||
MOZ_ASSERT(cond == Assembler::NotEqual || cond == Assembler::Equal,
|
||||
"other condition codes not supported");
|
||||
MOZ_ASSERT(lhs.base != scratch);
|
||||
MOZ_ASSERT(rhs.base != scratch);
|
||||
@ -746,7 +751,7 @@ MacroAssembler::truncateFloat32ToUInt64(Address src, Address dest, Register temp
|
||||
|
||||
// For unsigned conversion the case of [INT64, UINT64] needs to get handle seperately.
|
||||
loadPtr(dest, temp);
|
||||
branch32(Assembler::Condition::NotSigned, temp, Imm32(0), &done);
|
||||
branchPtr(Assembler::Condition::NotSigned, temp, Imm32(0), &done);
|
||||
|
||||
// Move the value inside INT64 range.
|
||||
storeFloat32(floatTemp, dest);
|
||||
@ -774,7 +779,7 @@ MacroAssembler::truncateDoubleToUInt64(Address src, Address dest, Register temp,
|
||||
|
||||
// For unsigned conversion the case of [INT64, UINT64] needs to get handle seperately.
|
||||
loadPtr(dest, temp);
|
||||
branch32(Assembler::Condition::NotSigned, temp, Imm32(0), &done);
|
||||
branchPtr(Assembler::Condition::NotSigned, temp, Imm32(0), &done);
|
||||
|
||||
// Move the value inside INT64 range.
|
||||
storeDouble(floatTemp, dest);
|
||||
|
@ -351,13 +351,15 @@ MacroAssembler::neg64(Register64 reg)
|
||||
void
|
||||
MacroAssembler::lshiftPtr(Imm32 imm, Register dest)
|
||||
{
|
||||
MOZ_ASSERT(0 <= imm.value && imm.value < 32);
|
||||
shll(imm, dest);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::lshift64(Imm32 imm, Register64 dest)
|
||||
{
|
||||
if ((imm.value & INT32_MAX) < 32) {
|
||||
MOZ_ASSERT(0 <= imm.value && imm.value < 64);
|
||||
if (imm.value < 32) {
|
||||
shldl(imm, dest.low, dest.high);
|
||||
shll(imm, dest.low);
|
||||
return;
|
||||
@ -392,13 +394,15 @@ MacroAssembler::lshift64(Register shift, Register64 srcDest)
|
||||
void
|
||||
MacroAssembler::rshiftPtr(Imm32 imm, Register dest)
|
||||
{
|
||||
MOZ_ASSERT(0 <= imm.value && imm.value < 32);
|
||||
shrl(imm, dest);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::rshift64(Imm32 imm, Register64 dest)
|
||||
{
|
||||
if ((imm.value & INT32_MAX) < 32) {
|
||||
MOZ_ASSERT(0 <= imm.value && imm.value < 64);
|
||||
if (imm.value < 32) {
|
||||
shrdl(imm, dest.high, dest.low);
|
||||
shrl(imm, dest.high);
|
||||
return;
|
||||
@ -433,13 +437,15 @@ MacroAssembler::rshift64(Register shift, Register64 srcDest)
|
||||
void
|
||||
MacroAssembler::rshiftPtrArithmetic(Imm32 imm, Register dest)
|
||||
{
|
||||
MOZ_ASSERT(0 <= imm.value && imm.value < 32);
|
||||
sarl(imm, dest);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::rshift64Arithmetic(Imm32 imm, Register64 dest)
|
||||
{
|
||||
if ((imm.value & INT32_MAX) < 32) {
|
||||
MOZ_ASSERT(0 <= imm.value && imm.value < 64);
|
||||
if (imm.value < 32) {
|
||||
shrdl(imm, dest.high, dest.low);
|
||||
sarl(imm, dest.high);
|
||||
return;
|
||||
@ -715,27 +721,41 @@ MacroAssembler::branch64(Condition cond, Register64 lhs, Register64 rhs, Label*
|
||||
void
|
||||
MacroAssembler::branch64(Condition cond, const Address& lhs, Imm64 val, Label* label)
|
||||
{
|
||||
MOZ_ASSERT(cond == Assembler::NotEqual,
|
||||
MOZ_ASSERT(cond == Assembler::NotEqual || cond == Assembler::Equal,
|
||||
"other condition codes not supported");
|
||||
|
||||
branch32(cond, lhs, val.firstHalf(), label);
|
||||
Label done;
|
||||
|
||||
if (cond == Assembler::Equal)
|
||||
branch32(Assembler::NotEqual, lhs, val.firstHalf(), &done);
|
||||
else
|
||||
branch32(Assembler::NotEqual, lhs, val.firstHalf(), label);
|
||||
branch32(cond, Address(lhs.base, lhs.offset + sizeof(uint32_t)), val.secondHalf(), label);
|
||||
|
||||
bind(&done);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::branch64(Condition cond, const Address& lhs, const Address& rhs, Register scratch,
|
||||
Label* label)
|
||||
{
|
||||
MOZ_ASSERT(cond == Assembler::NotEqual,
|
||||
MOZ_ASSERT(cond == Assembler::NotEqual || cond == Assembler::Equal,
|
||||
"other condition codes not supported");
|
||||
MOZ_ASSERT(lhs.base != scratch);
|
||||
MOZ_ASSERT(rhs.base != scratch);
|
||||
|
||||
Label done;
|
||||
|
||||
load32(rhs, scratch);
|
||||
branch32(cond, lhs, scratch, label);
|
||||
if (cond == Assembler::Equal)
|
||||
branch32(Assembler::NotEqual, lhs, scratch, &done);
|
||||
else
|
||||
branch32(Assembler::NotEqual, lhs, scratch, label);
|
||||
|
||||
load32(Address(rhs.base, rhs.offset + sizeof(uint32_t)), scratch);
|
||||
branch32(cond, Address(lhs.base, lhs.offset + sizeof(uint32_t)), scratch, label);
|
||||
|
||||
bind(&done);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -114,6 +114,7 @@ if CONFIG['ENABLE_ION']:
|
||||
'testJitDCEinGVN.cpp',
|
||||
'testJitFoldsTo.cpp',
|
||||
'testJitGVN.cpp',
|
||||
'testJitMacroAssembler.cpp',
|
||||
'testJitMoveEmitterCycles-mips32.cpp',
|
||||
'testJitMoveEmitterCycles.cpp',
|
||||
'testJitRangeAnalysis.cpp',
|
||||
|
476
js/src/jsapi-tests/testJitMacroAssembler.cpp
Normal file
476
js/src/jsapi-tests/testJitMacroAssembler.cpp
Normal file
@ -0,0 +1,476 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* vim: set ts=8 sts=4 et sw=4 tw=99:
|
||||
*/
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "jit/IonAnalysis.h"
|
||||
#include "jit/Linker.h"
|
||||
#include "jit/MacroAssembler.h"
|
||||
#include "jit/MIRGenerator.h"
|
||||
#include "jit/MIRGraph.h"
|
||||
#include "jit/ValueNumbering.h"
|
||||
#include "js/Value.h"
|
||||
|
||||
#include "jsapi-tests/tests.h"
|
||||
|
||||
#include "jit/MacroAssembler-inl.h"
|
||||
|
||||
using namespace js;
|
||||
using namespace js::jit;
|
||||
|
||||
using mozilla::PositiveInfinity;
|
||||
using mozilla::NegativeInfinity;
|
||||
|
||||
#if defined(JS_CODEGEN_X86) || defined(JS_CODEGEN_X64)
|
||||
|
||||
typedef void (*EnterTest)();
|
||||
|
||||
static bool Prepare(MacroAssembler& masm)
|
||||
{
|
||||
AllocatableRegisterSet regs(RegisterSet::Volatile());
|
||||
LiveRegisterSet save(regs.asLiveSet());
|
||||
masm.PushRegsInMask(save);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool Execute(JSContext* cx, MacroAssembler& masm)
|
||||
{
|
||||
AllocatableRegisterSet regs(RegisterSet::Volatile());
|
||||
LiveRegisterSet save(regs.asLiveSet());
|
||||
masm.PopRegsInMask(save);
|
||||
masm.ret(); // Add return statement to be sure.
|
||||
|
||||
if (masm.oom())
|
||||
return false;
|
||||
|
||||
Linker linker(masm);
|
||||
JitCode* code = linker.newCode<CanGC>(cx, OTHER_CODE);
|
||||
if (!code)
|
||||
return false;
|
||||
if (!ExecutableAllocator::makeExecutable(code->raw(), code->bufferSize()))
|
||||
return false;
|
||||
|
||||
EnterTest test = code->as<EnterTest>();
|
||||
test();
|
||||
return true;
|
||||
}
|
||||
|
||||
BEGIN_TEST(testJitMacroAssembler_truncateDoubleToInt64)
|
||||
{
|
||||
MacroAssembler masm(cx);
|
||||
|
||||
if (!Prepare(masm))
|
||||
return false;
|
||||
|
||||
AllocatableGeneralRegisterSet allRegs(GeneralRegisterSet::All());
|
||||
AllocatableFloatRegisterSet allFloatRegs(FloatRegisterSet::All());
|
||||
FloatRegister input = allFloatRegs.takeAny();
|
||||
#ifdef JS_NUNBOX32
|
||||
Register64 output(allRegs.takeAny(), allRegs.takeAny());
|
||||
#else
|
||||
Register64 output(allRegs.takeAny());
|
||||
#endif
|
||||
Register temp = allRegs.takeAny();
|
||||
|
||||
masm.reserveStack(sizeof(int32_t));
|
||||
|
||||
#define TEST(INPUT, OUTPUT) \
|
||||
{ \
|
||||
Label next; \
|
||||
masm.loadConstantDouble(double(INPUT), input); \
|
||||
masm.storeDouble(input, Operand(esp, 0)); \
|
||||
masm.truncateDoubleToInt64(Address(esp, 0), Address(esp, 0), temp); \
|
||||
masm.branch64(Assembler::Equal, Address(esp, 0), Imm64(OUTPUT), &next); \
|
||||
masm.printf("truncateDoubleToInt64("#INPUT") failed\n"); \
|
||||
masm.breakpoint(); \
|
||||
masm.bind(&next); \
|
||||
}
|
||||
|
||||
TEST(0, 0);
|
||||
TEST(-0, 0);
|
||||
TEST(1, 1);
|
||||
TEST(9223372036854774784.0, 9223372036854774784);
|
||||
TEST(-9223372036854775808.0, 0x8000000000000000);
|
||||
TEST(9223372036854775808.0, 0x8000000000000000);
|
||||
TEST(JS::GenericNaN(), 0x8000000000000000);
|
||||
TEST(PositiveInfinity<double>(), 0x8000000000000000);
|
||||
TEST(NegativeInfinity<double>(), 0x8000000000000000);
|
||||
#undef TEST
|
||||
|
||||
masm.freeStack(sizeof(int32_t));
|
||||
|
||||
return Execute(cx, masm);
|
||||
}
|
||||
END_TEST(testJitMacroAssembler_truncateDoubleToInt64)
|
||||
|
||||
BEGIN_TEST(testJitMacroAssembler_truncateDoubleToUInt64)
|
||||
{
|
||||
MacroAssembler masm(cx);
|
||||
|
||||
if (!Prepare(masm))
|
||||
return false;
|
||||
|
||||
AllocatableGeneralRegisterSet allRegs(GeneralRegisterSet::All());
|
||||
AllocatableFloatRegisterSet allFloatRegs(FloatRegisterSet::All());
|
||||
FloatRegister input = allFloatRegs.takeAny();
|
||||
FloatRegister floatTemp = allFloatRegs.takeAny();
|
||||
#ifdef JS_NUNBOX32
|
||||
Register64 output(allRegs.takeAny(), allRegs.takeAny());
|
||||
#else
|
||||
Register64 output(allRegs.takeAny());
|
||||
#endif
|
||||
Register temp = allRegs.takeAny();
|
||||
|
||||
masm.reserveStack(sizeof(int32_t));
|
||||
|
||||
#define TEST(INPUT, OUTPUT) \
|
||||
{ \
|
||||
Label next; \
|
||||
masm.loadConstantDouble(double(INPUT), input); \
|
||||
masm.storeDouble(input, Operand(esp, 0)); \
|
||||
masm.truncateDoubleToUInt64(Address(esp, 0), Address(esp, 0), temp, floatTemp); \
|
||||
masm.branch64(Assembler::Equal, Address(esp, 0), Imm64(OUTPUT), &next); \
|
||||
masm.printf("truncateDoubleToUInt64("#INPUT") failed\n"); \
|
||||
masm.breakpoint(); \
|
||||
masm.bind(&next); \
|
||||
}
|
||||
|
||||
TEST(0, 0);
|
||||
TEST(1, 1);
|
||||
TEST(9223372036854774784.0, 9223372036854774784);
|
||||
TEST((uint64_t)0x8000000000000000, 0x8000000000000000);
|
||||
TEST((uint64_t)0x8000000000000001, 0x8000000000000000);
|
||||
TEST((uint64_t)0x8006004000000001, 0x8006004000000000);
|
||||
TEST(-0.0, 0);
|
||||
TEST(-0.5, 0);
|
||||
TEST(-0.99, 0);
|
||||
TEST(JS::GenericNaN(), 0x8000000000000000);
|
||||
TEST(PositiveInfinity<double>(), 0x8000000000000000);
|
||||
TEST(NegativeInfinity<double>(), 0x8000000000000000);
|
||||
#undef TEST
|
||||
|
||||
masm.freeStack(sizeof(int32_t));
|
||||
|
||||
return Execute(cx, masm);
|
||||
}
|
||||
END_TEST(testJitMacroAssembler_truncateDoubleToUInt64)
|
||||
|
||||
BEGIN_TEST(testJitMacroAssembler_branchDoubleNotInInt64Range)
|
||||
{
|
||||
MacroAssembler masm(cx);
|
||||
|
||||
if (!Prepare(masm))
|
||||
return false;
|
||||
|
||||
AllocatableGeneralRegisterSet allRegs(GeneralRegisterSet::All());
|
||||
AllocatableFloatRegisterSet allFloatRegs(FloatRegisterSet::All());
|
||||
FloatRegister input = allFloatRegs.takeAny();
|
||||
#ifdef JS_NUNBOX32
|
||||
Register64 output(allRegs.takeAny(), allRegs.takeAny());
|
||||
#else
|
||||
Register64 output(allRegs.takeAny());
|
||||
#endif
|
||||
Register temp = allRegs.takeAny();
|
||||
|
||||
masm.reserveStack(sizeof(int32_t));
|
||||
|
||||
#define TEST(INPUT, OUTPUT) \
|
||||
{ \
|
||||
Label next; \
|
||||
masm.loadConstantDouble(double(INPUT), input); \
|
||||
masm.storeDouble(input, Operand(esp, 0)); \
|
||||
if (OUTPUT) { \
|
||||
masm.branchDoubleNotInInt64Range(Address(esp, 0), temp, &next); \
|
||||
} else { \
|
||||
Label fail; \
|
||||
masm.branchDoubleNotInInt64Range(Address(esp, 0), temp, &fail); \
|
||||
masm.jump(&next); \
|
||||
masm.bind(&fail); \
|
||||
} \
|
||||
masm.printf("branchDoubleNotInInt64Range("#INPUT") failed\n"); \
|
||||
masm.breakpoint(); \
|
||||
masm.bind(&next); \
|
||||
}
|
||||
|
||||
TEST(0, false);
|
||||
TEST(-0, false);
|
||||
TEST(1, false);
|
||||
TEST(9223372036854774784.0, false);
|
||||
TEST(-9223372036854775808.0, true);
|
||||
TEST(9223372036854775808.0, true);
|
||||
TEST(JS::GenericNaN(), true);
|
||||
TEST(PositiveInfinity<double>(), true);
|
||||
TEST(NegativeInfinity<double>(), true);
|
||||
#undef TEST
|
||||
|
||||
masm.freeStack(sizeof(int32_t));
|
||||
|
||||
return Execute(cx, masm);
|
||||
}
|
||||
END_TEST(testJitMacroAssembler_branchDoubleNotInInt64Range)
|
||||
|
||||
BEGIN_TEST(testJitMacroAssembler_branchDoubleNotInUInt64Range)
|
||||
{
|
||||
MacroAssembler masm(cx);
|
||||
|
||||
if (!Prepare(masm))
|
||||
return false;
|
||||
|
||||
AllocatableGeneralRegisterSet allRegs(GeneralRegisterSet::All());
|
||||
AllocatableFloatRegisterSet allFloatRegs(FloatRegisterSet::All());
|
||||
FloatRegister input = allFloatRegs.takeAny();
|
||||
#ifdef JS_NUNBOX32
|
||||
Register64 output(allRegs.takeAny(), allRegs.takeAny());
|
||||
#else
|
||||
Register64 output(allRegs.takeAny());
|
||||
#endif
|
||||
Register temp = allRegs.takeAny();
|
||||
|
||||
masm.reserveStack(sizeof(int32_t));
|
||||
|
||||
#define TEST(INPUT, OUTPUT) \
|
||||
{ \
|
||||
Label next; \
|
||||
masm.loadConstantDouble(double(INPUT), input); \
|
||||
masm.storeDouble(input, Operand(esp, 0)); \
|
||||
if (OUTPUT) { \
|
||||
masm.branchDoubleNotInUInt64Range(Address(esp, 0), temp, &next); \
|
||||
} else { \
|
||||
Label fail; \
|
||||
masm.branchDoubleNotInUInt64Range(Address(esp, 0), temp, &fail); \
|
||||
masm.jump(&next); \
|
||||
masm.bind(&fail); \
|
||||
} \
|
||||
masm.printf("branchDoubleNotInUInt64Range("#INPUT") failed\n"); \
|
||||
masm.breakpoint(); \
|
||||
masm.bind(&next); \
|
||||
}
|
||||
|
||||
TEST(0, false);
|
||||
TEST(1, false);
|
||||
TEST(9223372036854774784.0, false);
|
||||
TEST((uint64_t)0x8000000000000000, false);
|
||||
TEST((uint64_t)0x8000000000000001, false);
|
||||
TEST((uint64_t)0x8006004000000001, false);
|
||||
TEST(-0.0, true);
|
||||
TEST(-0.5, true);
|
||||
TEST(-0.99, true);
|
||||
TEST(JS::GenericNaN(), true);
|
||||
TEST(PositiveInfinity<double>(), true);
|
||||
TEST(NegativeInfinity<double>(), true);
|
||||
#undef TEST
|
||||
|
||||
masm.freeStack(sizeof(int32_t));
|
||||
|
||||
return Execute(cx, masm);
|
||||
}
|
||||
END_TEST(testJitMacroAssembler_branchDoubleNotInUInt64Range)
|
||||
|
||||
BEGIN_TEST(testJitMacroAssembler_lshift64)
|
||||
{
|
||||
MacroAssembler masm(cx);
|
||||
|
||||
if (!Prepare(masm))
|
||||
return false;
|
||||
|
||||
AllocatableGeneralRegisterSet allRegs(GeneralRegisterSet::All());
|
||||
AllocatableFloatRegisterSet allFloatRegs(FloatRegisterSet::All());
|
||||
#if defined(JS_CODEGEN_X86)
|
||||
Register shift = ecx;
|
||||
allRegs.take(shift);
|
||||
#elif defined(JS_CODEGEN_X64)
|
||||
Register shift = rcx;
|
||||
allRegs.take(shift);
|
||||
#else
|
||||
Register shift = allRegs.takeAny();
|
||||
#endif
|
||||
|
||||
#ifdef JS_NUNBOX32
|
||||
Register64 input(allRegs.takeAny(), allRegs.takeAny());
|
||||
#else
|
||||
Register64 input(allRegs.takeAny());
|
||||
#endif
|
||||
|
||||
masm.reserveStack(sizeof(int32_t));
|
||||
|
||||
#define TEST(SHIFT, INPUT, OUTPUT) \
|
||||
{ \
|
||||
Label next; \
|
||||
masm.move64(Imm64(INPUT), input); \
|
||||
masm.move32(Imm32(SHIFT), shift); \
|
||||
masm.lshift64(shift, input); \
|
||||
masm.branch64(Assembler::Equal, input, Imm64(OUTPUT), &next); \
|
||||
masm.printf("lshift64("#SHIFT", "#INPUT") failed\n"); \
|
||||
masm.breakpoint(); \
|
||||
masm.bind(&next); \
|
||||
} \
|
||||
{ \
|
||||
Label next; \
|
||||
masm.move64(Imm64(INPUT), input); \
|
||||
masm.lshift64(Imm32(SHIFT & 0x3f), input); \
|
||||
masm.branch64(Assembler::Equal, input, Imm64(OUTPUT), &next); \
|
||||
masm.printf("lshift64(Imm32("#SHIFT"&0x3f), "#INPUT") failed\n"); \
|
||||
masm.breakpoint(); \
|
||||
masm.bind(&next); \
|
||||
}
|
||||
|
||||
TEST(0, 1, 1);
|
||||
TEST(1, 1, 2);
|
||||
TEST(2, 1, 4);
|
||||
TEST(32, 1, 0x0000000100000000);
|
||||
TEST(33, 1, 0x0000000200000000);
|
||||
TEST(0, -1, 0xffffffffffffffff);
|
||||
TEST(1, -1, 0xfffffffffffffffe);
|
||||
TEST(2, -1, 0xfffffffffffffffc);
|
||||
TEST(32, -1, 0xffffffff00000000);
|
||||
TEST(0xffffffff, 1, 0x8000000000000000);
|
||||
TEST(0xfffffffe, 1, 0x4000000000000000);
|
||||
TEST(0xfffffffd, 1, 0x2000000000000000);
|
||||
TEST(0x80000001, 1, 2);
|
||||
#undef TEST
|
||||
|
||||
masm.freeStack(sizeof(int32_t));
|
||||
|
||||
return Execute(cx, masm);
|
||||
}
|
||||
END_TEST(testJitMacroAssembler_lshift64)
|
||||
|
||||
BEGIN_TEST(testJitMacroAssembler_rshift64Arithmetic)
|
||||
{
|
||||
MacroAssembler masm(cx);
|
||||
|
||||
if (!Prepare(masm))
|
||||
return false;
|
||||
|
||||
AllocatableGeneralRegisterSet allRegs(GeneralRegisterSet::All());
|
||||
AllocatableFloatRegisterSet allFloatRegs(FloatRegisterSet::All());
|
||||
#if defined(JS_CODEGEN_X86)
|
||||
Register shift = ecx;
|
||||
allRegs.take(shift);
|
||||
#elif defined(JS_CODEGEN_X64)
|
||||
Register shift = rcx;
|
||||
allRegs.take(shift);
|
||||
#else
|
||||
Register shift = allRegs.takeAny();
|
||||
#endif
|
||||
|
||||
#ifdef JS_NUNBOX32
|
||||
Register64 input(allRegs.takeAny(), allRegs.takeAny());
|
||||
#else
|
||||
Register64 input(allRegs.takeAny());
|
||||
#endif
|
||||
|
||||
masm.reserveStack(sizeof(int32_t));
|
||||
|
||||
#define TEST(SHIFT, INPUT, OUTPUT) \
|
||||
{ \
|
||||
Label next; \
|
||||
masm.move64(Imm64(INPUT), input); \
|
||||
masm.move32(Imm32(SHIFT), shift); \
|
||||
masm.rshift64Arithmetic(shift, input); \
|
||||
masm.branch64(Assembler::Equal, input, Imm64(OUTPUT), &next); \
|
||||
masm.printf("rshift64Arithmetic("#SHIFT", "#INPUT") failed\n"); \
|
||||
masm.breakpoint(); \
|
||||
masm.bind(&next); \
|
||||
} \
|
||||
{ \
|
||||
Label next; \
|
||||
masm.move64(Imm64(INPUT), input); \
|
||||
masm.rshift64Arithmetic(Imm32(SHIFT & 0x3f), input); \
|
||||
masm.branch64(Assembler::Equal, input, Imm64(OUTPUT), &next); \
|
||||
masm.printf("rshift64Arithmetic(Imm32("#SHIFT"&0x3f), "#INPUT") failed\n"); \
|
||||
masm.breakpoint(); \
|
||||
masm.bind(&next); \
|
||||
}
|
||||
|
||||
TEST(0, 0x4000000000000000, 0x4000000000000000);
|
||||
TEST(1, 0x4000000000000000, 0x2000000000000000);
|
||||
TEST(2, 0x4000000000000000, 0x1000000000000000);
|
||||
TEST(32, 0x4000000000000000, 0x0000000040000000);
|
||||
TEST(0, 0x8000000000000000, 0x8000000000000000);
|
||||
TEST(1, 0x8000000000000000, 0xc000000000000000);
|
||||
TEST(2, 0x8000000000000000, 0xe000000000000000);
|
||||
TEST(32, 0x8000000000000000, 0xffffffff80000000);
|
||||
TEST(0xffffffff, 0x8000000000000000, 0xffffffffffffffff);
|
||||
TEST(0xfffffffe, 0x8000000000000000, 0xfffffffffffffffe);
|
||||
TEST(0xfffffffd, 0x8000000000000000, 0xfffffffffffffffc);
|
||||
TEST(0x80000001, 0x8000000000000000, 0xc000000000000000);
|
||||
#undef TEST
|
||||
|
||||
masm.freeStack(sizeof(int32_t));
|
||||
|
||||
return Execute(cx, masm);
|
||||
}
|
||||
END_TEST(testJitMacroAssembler_rshift64Arithmetic)
|
||||
|
||||
BEGIN_TEST(testJitMacroAssembler_rshift64)
|
||||
{
|
||||
MacroAssembler masm(cx);
|
||||
|
||||
if (!Prepare(masm))
|
||||
return false;
|
||||
|
||||
AllocatableGeneralRegisterSet allRegs(GeneralRegisterSet::All());
|
||||
AllocatableFloatRegisterSet allFloatRegs(FloatRegisterSet::All());
|
||||
#if defined(JS_CODEGEN_X86)
|
||||
Register shift = ecx;
|
||||
allRegs.take(shift);
|
||||
#elif defined(JS_CODEGEN_X64)
|
||||
Register shift = rcx;
|
||||
allRegs.take(shift);
|
||||
#else
|
||||
Register shift = allRegs.takeAny();
|
||||
#endif
|
||||
|
||||
#ifdef JS_NUNBOX32
|
||||
Register64 input(allRegs.takeAny(), allRegs.takeAny());
|
||||
#else
|
||||
Register64 input(allRegs.takeAny());
|
||||
#endif
|
||||
|
||||
masm.reserveStack(sizeof(int32_t));
|
||||
|
||||
#define TEST(SHIFT, INPUT, OUTPUT) \
|
||||
{ \
|
||||
Label next; \
|
||||
masm.move64(Imm64(INPUT), input); \
|
||||
masm.move32(Imm32(SHIFT), shift); \
|
||||
masm.rshift64(shift, input); \
|
||||
masm.branch64(Assembler::Equal, input, Imm64(OUTPUT), &next); \
|
||||
masm.printf("rshift64("#SHIFT", "#INPUT") failed\n"); \
|
||||
masm.breakpoint(); \
|
||||
masm.bind(&next); \
|
||||
} \
|
||||
{ \
|
||||
Label next; \
|
||||
masm.move64(Imm64(INPUT), input); \
|
||||
masm.rshift64(Imm32(SHIFT & 0x3f), input); \
|
||||
masm.branch64(Assembler::Equal, input, Imm64(OUTPUT), &next); \
|
||||
masm.printf("rshift64(Imm32("#SHIFT"&0x3f), "#INPUT") failed\n"); \
|
||||
masm.breakpoint(); \
|
||||
masm.bind(&next); \
|
||||
}
|
||||
|
||||
TEST(0, 0x4000000000000000, 0x4000000000000000);
|
||||
TEST(1, 0x4000000000000000, 0x2000000000000000);
|
||||
TEST(2, 0x4000000000000000, 0x1000000000000000);
|
||||
TEST(32, 0x4000000000000000, 0x0000000040000000);
|
||||
TEST(0, 0x8000000000000000, 0x8000000000000000);
|
||||
TEST(1, 0x8000000000000000, 0x4000000000000000);
|
||||
TEST(2, 0x8000000000000000, 0x2000000000000000);
|
||||
TEST(32, 0x8000000000000000, 0x0000000080000000);
|
||||
TEST(0xffffffff, 0x8000000000000000, 0x0000000000000001);
|
||||
TEST(0xfffffffe, 0x8000000000000000, 0x0000000000000002);
|
||||
TEST(0xfffffffd, 0x8000000000000000, 0x0000000000000004);
|
||||
TEST(0x80000001, 0x8000000000000000, 0x4000000000000000);
|
||||
#undef TEST
|
||||
|
||||
masm.freeStack(sizeof(int32_t));
|
||||
|
||||
return Execute(cx, masm);
|
||||
}
|
||||
END_TEST(testJitMacroAssembler_rshift64)
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user