mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-11 20:35:50 +00:00
Bug 1028008 - IonMonkey: (ARM) Support reading a js shell 'arm-hwcap' argument in addition to the ARMHWCAP environment variable. r=jandem
This commit is contained in:
parent
7030e104d4
commit
de42e7d43f
@ -8527,7 +8527,7 @@ CodeGenerator::visitAsmJSCall(LAsmJSCall *ins)
|
||||
MAsmJSCall *mir = ins->mir();
|
||||
|
||||
#if defined(JS_CODEGEN_ARM)
|
||||
if (!useHardFpABI() && mir->callee().which() == MAsmJSCall::Callee::Builtin) {
|
||||
if (!UseHardFpABI() && mir->callee().which() == MAsmJSCall::Callee::Builtin) {
|
||||
for (unsigned i = 0, e = ins->numOperands(); i < e; i++) {
|
||||
LAllocation *a = ins->getOperand(i);
|
||||
if (a->isFloatReg()) {
|
||||
|
@ -34,6 +34,97 @@
|
||||
namespace js {
|
||||
namespace jit {
|
||||
|
||||
// The override flags parsed from the ARMHWCAP environment variable or from the
|
||||
// --arm-hwcap js shell argument.
|
||||
static uint32_t armHwCapFlags = 0;
|
||||
|
||||
bool
|
||||
ParseARMHwCapFlags(const char *armHwCap)
|
||||
{
|
||||
uint32_t flags = 0;
|
||||
|
||||
if (!armHwCap || !armHwCap[0])
|
||||
return false;
|
||||
|
||||
#ifdef JS_CODEGEN_ARM_HARDFP
|
||||
flags |= HWCAP_USE_HARDFP_ABI;
|
||||
#endif
|
||||
|
||||
if (strstr(armHwCap, "help")) {
|
||||
fflush(NULL);
|
||||
printf(
|
||||
"\n"
|
||||
"usage: ARMHWCAP=option,option,option,... where options can be:\n"
|
||||
"\n"
|
||||
" armv7 \n"
|
||||
" vfp \n"
|
||||
" neon \n"
|
||||
" vfpv3 \n"
|
||||
" vfpv3d16 \n"
|
||||
" vfpv4 \n"
|
||||
" idiva \n"
|
||||
" idivt \n"
|
||||
#if defined(JS_ARM_SIMULATOR)
|
||||
" hardfp \n"
|
||||
#endif
|
||||
"\n"
|
||||
);
|
||||
exit(0);
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
// Canonicalize each token to have a leading and trailing space.
|
||||
const char *start = armHwCap; // Token start.
|
||||
for (;;) {
|
||||
char ch = *start;
|
||||
if (!ch) {
|
||||
// End of string.
|
||||
break;
|
||||
}
|
||||
if (ch == ' ' || ch == ',') {
|
||||
// Skip separator characters.
|
||||
start++;
|
||||
continue;
|
||||
}
|
||||
// Find the end of the token.
|
||||
const char *end = start + 1;
|
||||
for (; ; end++) {
|
||||
ch = *end;
|
||||
if (!ch || ch == ' ' || ch == ',')
|
||||
break;
|
||||
}
|
||||
size_t count = end - start;
|
||||
if (count == 3 && strncmp(start, "vfp", 3) == 0)
|
||||
flags |= HWCAP_VFP;
|
||||
else if (count == 5 && strncmp(start, "vfpv3", 5) == 0)
|
||||
flags |= HWCAP_VFPv3;
|
||||
else if (count == 8 && strncmp(start, "vfpv3d16", 8) == 0)
|
||||
flags |= HWCAP_VFPv3D16;
|
||||
else if (count == 5 && strncmp(start, "vfpv4", 5) == 0)
|
||||
flags |= HWCAP_VFPv4;
|
||||
else if (count == 5 && strncmp(start, "idiva", 5) == 0)
|
||||
flags |= HWCAP_IDIVA;
|
||||
else if (count == 5 && strncmp(start, "idivt", 5) == 0)
|
||||
flags |= HWCAP_IDIVT;
|
||||
else if (count == 4 && strncmp(start, "neon", 4) == 0)
|
||||
flags |= HWCAP_NEON;
|
||||
else if (count == 5 && strncmp(start, "armv7", 5) == 0)
|
||||
flags |= HWCAP_ARMv7;
|
||||
#if defined(JS_ARM_SIMULATOR)
|
||||
else if (count == 6 && strncmp(start, "hardfp", 6) == 0)
|
||||
flags |= HWCAP_USE_HARDFP_ABI;
|
||||
#endif
|
||||
else
|
||||
fprintf(stderr, "Warning: unexpected ARMHWCAP flag at: %s\n", start);
|
||||
start = end;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
IonSpew(IonSpew_Codegen, "ARMHWCAP: '%s'\n flags: 0x%x\n", armHwCap, flags);
|
||||
#endif
|
||||
armHwCapFlags = flags;
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32_t GetARMFlags()
|
||||
{
|
||||
static bool isSet = false;
|
||||
@ -41,88 +132,17 @@ uint32_t GetARMFlags()
|
||||
if (isSet)
|
||||
return flags;
|
||||
|
||||
const char *env = getenv("ARMHWCAP");
|
||||
if (ParseARMHwCapFlags(env) || armHwCapFlags) {
|
||||
isSet = true;
|
||||
flags = armHwCapFlags;
|
||||
return flags;
|
||||
}
|
||||
|
||||
#ifdef JS_CODEGEN_ARM_HARDFP
|
||||
flags |= HWCAP_USE_HARDFP_ABI;
|
||||
#endif
|
||||
|
||||
static const char *env = getenv("ARMHWCAP");
|
||||
|
||||
if (env && env[0]) {
|
||||
if (strstr(env, "help")) {
|
||||
fflush(NULL);
|
||||
printf(
|
||||
"\n"
|
||||
"usage: ARMHWCAP=option,option,option,... where options can be:\n"
|
||||
"\n"
|
||||
" armv7 \n"
|
||||
" vfp \n"
|
||||
" neon \n"
|
||||
" vfpv3 \n"
|
||||
" vfpv3d16 \n"
|
||||
" vfpv4 \n"
|
||||
" idiva \n"
|
||||
" idivt \n"
|
||||
#if defined(JS_ARM_SIMULATOR)
|
||||
" hardfp \n"
|
||||
#endif
|
||||
"\n"
|
||||
);
|
||||
exit(0);
|
||||
/*NOTREACHED*/
|
||||
} else {
|
||||
// Canonicalize each token to have a leading and trailing space.
|
||||
const char *start = env; // Token start.
|
||||
for (;;) {
|
||||
char ch = *start;
|
||||
if (!ch) {
|
||||
// End of string.
|
||||
break;
|
||||
}
|
||||
if (ch == ' ' || ch == ',') {
|
||||
// Skip separator characters.
|
||||
start++;
|
||||
continue;
|
||||
}
|
||||
// Find the end of the token.
|
||||
const char *end = start + 1;
|
||||
for (; ; end++) {
|
||||
ch = *end;
|
||||
if (!ch || ch == ' ' || ch == ',')
|
||||
break;
|
||||
}
|
||||
size_t count = end - start;
|
||||
if (count == 3 && strncmp(start, "vfp", 3) == 0)
|
||||
flags |= HWCAP_VFP;
|
||||
else if (count == 5 && strncmp(start, "vfpv3", 5) == 0)
|
||||
flags |= HWCAP_VFPv3;
|
||||
else if (count == 8 && strncmp(start, "vfpv3d16", 8) == 0)
|
||||
flags |= HWCAP_VFPv3D16;
|
||||
else if (count == 5 && strncmp(start, "vfpv4", 5) == 0)
|
||||
flags |= HWCAP_VFPv4;
|
||||
else if (count == 5 && strncmp(start, "idiva", 5) == 0)
|
||||
flags |= HWCAP_IDIVA;
|
||||
else if (count == 5 && strncmp(start, "idivt", 5) == 0)
|
||||
flags |= HWCAP_IDIVT;
|
||||
else if (count == 4 && strncmp(start, "neon", 4) == 0)
|
||||
flags |= HWCAP_NEON;
|
||||
else if (count == 5 && strncmp(start, "armv7", 5) == 0)
|
||||
flags |= HWCAP_ARMv7;
|
||||
#if defined(JS_ARM_SIMULATOR)
|
||||
else if (count == 6 && strncmp(start, "hardfp", 6) == 0)
|
||||
flags |= HWCAP_USE_HARDFP_ABI;
|
||||
#endif
|
||||
else
|
||||
fprintf(stderr, "Warning: unexpected ARMHWCAP flag at: %s\n", start);
|
||||
start = end;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
IonSpew(IonSpew_Codegen, "ARMHWCAP: '%s'\n flags: 0x%x\n", env, flags);
|
||||
#endif
|
||||
isSet = true;
|
||||
return flags;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef JS_ARM_SIMULATOR
|
||||
isSet = true;
|
||||
flags = HWCAP_ARMv7 | HWCAP_VFP | HWCAP_VFPv3 | HWCAP_VFPv4 | HWCAP_NEON;
|
||||
@ -139,11 +159,10 @@ uint32_t GetARMFlags()
|
||||
flags = aux.a_un.a_val;
|
||||
isSet = true;
|
||||
#if defined(__ARM_ARCH_7__) || defined (__ARM_ARCH_7A__)
|
||||
// this should really be detected at runtime, but
|
||||
// /proc/*/auxv doesn't seem to carry the ISA
|
||||
// I could look in /proc/cpuinfo as well, but
|
||||
// the chances that it will be different from this
|
||||
// are low.
|
||||
// This should really be detected at runtime, but /proc/*/auxv
|
||||
// doesn't seem to carry the ISA. We could look in
|
||||
// /proc/cpuinfo as well, but the chances that it will be
|
||||
// different from this are low.
|
||||
flags |= HWCAP_ARMv7;
|
||||
#endif
|
||||
return flags;
|
||||
@ -201,8 +220,8 @@ uint32_t GetARMFlags()
|
||||
if (strstr(buf, " neon "))
|
||||
flags |= HWCAP_NEON;
|
||||
|
||||
// not part of the HWCAP flag, but I need to know this, and we're not using
|
||||
// that bit, so... I'm using it
|
||||
// Not part of the HWCAP flag, but we need to know this, and we're not using
|
||||
// that bit, so... we are using it.
|
||||
if (strstr(buf, "ARMv7"))
|
||||
flags |= HWCAP_ARMv7;
|
||||
|
||||
@ -218,29 +237,29 @@ uint32_t GetARMFlags()
|
||||
#endif // JS_ARM_SIMULATOR
|
||||
}
|
||||
|
||||
bool hasMOVWT()
|
||||
bool HasMOVWT()
|
||||
{
|
||||
return GetARMFlags() & HWCAP_ARMv7;
|
||||
}
|
||||
bool hasVFPv3()
|
||||
bool HasVFPv3()
|
||||
{
|
||||
return GetARMFlags() & HWCAP_VFPv3;
|
||||
}
|
||||
bool hasVFP()
|
||||
bool HasVFP()
|
||||
{
|
||||
return GetARMFlags() & HWCAP_VFP;
|
||||
}
|
||||
|
||||
bool has32DP()
|
||||
bool Has32DP()
|
||||
{
|
||||
return !(GetARMFlags() & HWCAP_VFPv3D16 && !(GetARMFlags() & HWCAP_NEON));
|
||||
}
|
||||
bool useConvReg()
|
||||
bool UseConvReg()
|
||||
{
|
||||
return has32DP();
|
||||
return Has32DP();
|
||||
}
|
||||
|
||||
bool hasIDIV()
|
||||
bool HasIDIV()
|
||||
{
|
||||
#if defined HWCAP_IDIVA
|
||||
return GetARMFlags() & HWCAP_IDIVA;
|
||||
@ -251,7 +270,7 @@ bool hasIDIV()
|
||||
|
||||
// This is defined in the header and inlined when not using the simulator.
|
||||
#if defined(JS_ARM_SIMULATOR)
|
||||
bool useHardFpABI()
|
||||
bool UseHardFpABI()
|
||||
{
|
||||
return GetARMFlags() & HWCAP_USE_HARDFP_ABI;
|
||||
}
|
||||
|
@ -227,18 +227,20 @@ class FloatRegisters
|
||||
};
|
||||
|
||||
uint32_t GetARMFlags();
|
||||
bool hasMOVWT();
|
||||
bool hasVFPv3();
|
||||
bool hasVFP();
|
||||
bool has16DP();
|
||||
bool hasIDIV();
|
||||
bool HasMOVWT();
|
||||
bool HasVFPv3();
|
||||
bool HasVFP();
|
||||
bool Has16DP();
|
||||
bool HasIDIV();
|
||||
|
||||
bool ParseARMHwCapFlags(const char *armHwCap);
|
||||
|
||||
// If the simulator is used then the ABI choice is dynamic. Otherwise the ABI is static
|
||||
// and useHardFpABI is inlined so that unused branches can be optimized away.
|
||||
#if defined(JS_ARM_SIMULATOR)
|
||||
bool useHardFpABI();
|
||||
bool UseHardFpABI();
|
||||
#else
|
||||
static inline bool useHardFpABI()
|
||||
static inline bool UseHardFpABI()
|
||||
{
|
||||
#if defined(JS_CODEGEN_ARM_HARDFP)
|
||||
return true;
|
||||
|
@ -1448,13 +1448,13 @@ Assembler::as_tst(Register src1, Operand2 op2, Condition c)
|
||||
BufferOffset
|
||||
Assembler::as_movw(Register dest, Imm16 imm, Condition c, Instruction *pos)
|
||||
{
|
||||
JS_ASSERT(hasMOVWT());
|
||||
JS_ASSERT(HasMOVWT());
|
||||
return writeInst(0x03000000 | c | imm.encode() | RD(dest), (uint32_t*)pos);
|
||||
}
|
||||
BufferOffset
|
||||
Assembler::as_movt(Register dest, Imm16 imm, Condition c, Instruction *pos)
|
||||
{
|
||||
JS_ASSERT(hasMOVWT());
|
||||
JS_ASSERT(HasMOVWT());
|
||||
return writeInst(0x03400000 | c | imm.encode() | RD(dest), (uint32_t*)pos);
|
||||
}
|
||||
|
||||
|
@ -2135,7 +2135,7 @@ GetTempRegForIntArg(uint32_t usedIntArgs, uint32_t usedFloatArgs, Register *out)
|
||||
static inline uint32_t
|
||||
GetArgStackDisp(uint32_t arg)
|
||||
{
|
||||
JS_ASSERT(!useHardFpABI());
|
||||
JS_ASSERT(!UseHardFpABI());
|
||||
JS_ASSERT(arg >= NumIntArgRegs);
|
||||
return (arg - NumIntArgRegs) * sizeof(intptr_t);
|
||||
}
|
||||
@ -2148,7 +2148,7 @@ GetArgStackDisp(uint32_t arg)
|
||||
static inline bool
|
||||
GetFloatArgReg(uint32_t usedIntArgs, uint32_t usedFloatArgs, FloatRegister *out)
|
||||
{
|
||||
JS_ASSERT(useHardFpABI());
|
||||
JS_ASSERT(UseHardFpABI());
|
||||
if (usedFloatArgs >= NumFloatArgRegs)
|
||||
return false;
|
||||
*out = FloatRegister::FromCode(usedFloatArgs);
|
||||
@ -2158,7 +2158,7 @@ GetFloatArgReg(uint32_t usedIntArgs, uint32_t usedFloatArgs, FloatRegister *out)
|
||||
static inline uint32_t
|
||||
GetIntArgStackDisp(uint32_t usedIntArgs, uint32_t usedFloatArgs, uint32_t *padding)
|
||||
{
|
||||
JS_ASSERT(useHardFpABI());
|
||||
JS_ASSERT(UseHardFpABI());
|
||||
JS_ASSERT(usedIntArgs >= NumIntArgRegs);
|
||||
uint32_t doubleSlots = Max(0, (int32_t)usedFloatArgs - (int32_t)NumFloatArgRegs);
|
||||
doubleSlots *= 2;
|
||||
@ -2169,7 +2169,7 @@ GetIntArgStackDisp(uint32_t usedIntArgs, uint32_t usedFloatArgs, uint32_t *paddi
|
||||
static inline uint32_t
|
||||
GetFloat32ArgStackDisp(uint32_t usedIntArgs, uint32_t usedFloatArgs, uint32_t *padding)
|
||||
{
|
||||
JS_ASSERT(useHardFpABI());
|
||||
JS_ASSERT(UseHardFpABI());
|
||||
JS_ASSERT(usedFloatArgs >= NumFloatArgRegs);
|
||||
uint32_t intSlots = 0;
|
||||
if (usedIntArgs > NumIntArgRegs)
|
||||
@ -2181,7 +2181,7 @@ GetFloat32ArgStackDisp(uint32_t usedIntArgs, uint32_t usedFloatArgs, uint32_t *p
|
||||
static inline uint32_t
|
||||
GetDoubleArgStackDisp(uint32_t usedIntArgs, uint32_t usedFloatArgs, uint32_t *padding)
|
||||
{
|
||||
JS_ASSERT(useHardFpABI());
|
||||
JS_ASSERT(UseHardFpABI());
|
||||
JS_ASSERT(usedFloatArgs >= NumFloatArgRegs);
|
||||
uint32_t intSlots = 0;
|
||||
if (usedIntArgs > NumIntArgRegs) {
|
||||
|
@ -206,7 +206,7 @@ class CodeGeneratorARM : public CodeGeneratorShared
|
||||
bool generateInvalidateEpilogue();
|
||||
protected:
|
||||
void postAsmJSCall(LAsmJSCall *lir) {
|
||||
if (!useHardFpABI() && lir->mir()->callee().which() == MAsmJSCall::Callee::Builtin) {
|
||||
if (!UseHardFpABI() && lir->mir()->callee().which() == MAsmJSCall::Callee::Builtin) {
|
||||
switch (lir->mir()->type()) {
|
||||
case MIRType_Double:
|
||||
masm.ma_vxfer(r0, r1, d0);
|
||||
|
@ -283,7 +283,7 @@ LIRGeneratorARM::lowerDivI(MDiv *div)
|
||||
}
|
||||
}
|
||||
|
||||
if (hasIDIV()) {
|
||||
if (HasIDIV()) {
|
||||
LDivI *lir = new(alloc()) LDivI(useRegister(div->lhs()), useRegister(div->rhs()), temp());
|
||||
if (div->fallible() && !assignSnapshot(lir, Bailout_DoubleOutput))
|
||||
return false;
|
||||
@ -328,7 +328,7 @@ LIRGeneratorARM::lowerModI(MMod *mod)
|
||||
}
|
||||
}
|
||||
|
||||
if (hasIDIV()) {
|
||||
if (HasIDIV()) {
|
||||
LModI *lir = new(alloc()) LModI(useRegister(mod->lhs()), useRegister(mod->rhs()), temp());
|
||||
if (mod->fallible() && !assignSnapshot(lir, Bailout_DoubleOutput))
|
||||
return false;
|
||||
@ -425,7 +425,7 @@ LIRGeneratorARM::lowerUDiv(MDiv *div)
|
||||
MDefinition *lhs = div->getOperand(0);
|
||||
MDefinition *rhs = div->getOperand(1);
|
||||
|
||||
if (hasIDIV()) {
|
||||
if (HasIDIV()) {
|
||||
LUDiv *lir = new(alloc()) LUDiv;
|
||||
lir->setOperand(0, useRegister(lhs));
|
||||
lir->setOperand(1, useRegister(rhs));
|
||||
@ -447,7 +447,7 @@ LIRGeneratorARM::lowerUMod(MMod *mod)
|
||||
MDefinition *lhs = mod->getOperand(0);
|
||||
MDefinition *rhs = mod->getOperand(1);
|
||||
|
||||
if (hasIDIV()) {
|
||||
if (HasIDIV()) {
|
||||
LUMod *lir = new(alloc()) LUMod;
|
||||
lir->setOperand(0, useRegister(lhs));
|
||||
lir->setOperand(1, useRegister(rhs));
|
||||
|
@ -295,7 +295,7 @@ MacroAssemblerARM::ma_alu(Register src1, Imm32 imm, Register dest,
|
||||
return;
|
||||
}
|
||||
|
||||
if (hasMOVWT()) {
|
||||
if (HasMOVWT()) {
|
||||
// If the operation is a move-a-like then we can try to use movw to
|
||||
// move the bits into the destination. Otherwise, we'll need to
|
||||
// fall back on a multi-instruction format :(
|
||||
@ -370,7 +370,7 @@ MacroAssemblerARM::ma_alu(Register src1, Imm32 imm, Register dest,
|
||||
|
||||
// Well, damn. We can use two 16 bit mov's, then do the op
|
||||
// or we can do a single load from a pool then op.
|
||||
if (hasMOVWT()) {
|
||||
if (HasMOVWT()) {
|
||||
// Try to load the immediate into a scratch register
|
||||
// then use that
|
||||
as_movw(ScratchRegister, imm.value & 0xffff, c);
|
||||
@ -485,7 +485,7 @@ MacroAssemblerARM::ma_mov(ImmGCPtr ptr, Register dest)
|
||||
// before to recover the pointer, and not after.
|
||||
writeDataRelocation(ptr);
|
||||
RelocStyle rs;
|
||||
if (hasMOVWT())
|
||||
if (HasMOVWT())
|
||||
rs = L_MOVWT;
|
||||
else
|
||||
rs = L_LDR;
|
||||
@ -1475,7 +1475,7 @@ DoubleLowWord(const double value)
|
||||
void
|
||||
MacroAssemblerARM::ma_vimm(double value, FloatRegister dest, Condition cc)
|
||||
{
|
||||
if (hasVFPv3()) {
|
||||
if (HasVFPv3()) {
|
||||
if (DoubleLowWord(value) == 0) {
|
||||
if (DoubleHighWord(value) == 0) {
|
||||
// To zero a register, load 1.0, then execute dN <- dN - dN
|
||||
@ -1506,7 +1506,7 @@ void
|
||||
MacroAssemblerARM::ma_vimm_f32(float value, FloatRegister dest, Condition cc)
|
||||
{
|
||||
VFPRegister vd = VFPRegister(dest).singleOverlay();
|
||||
if (hasVFPv3()) {
|
||||
if (HasVFPv3()) {
|
||||
if (Float32Word(value) == 0) {
|
||||
// To zero a register, load 1.0, then execute sN <- sN - sN
|
||||
as_vimm(vd, VFPImm::one, cc);
|
||||
@ -1753,7 +1753,7 @@ MacroAssemblerARMCompat::callWithExitFrame(JitCode *target)
|
||||
|
||||
addPendingJump(m_buffer.nextOffset(), ImmPtr(target->raw()), Relocation::JITCODE);
|
||||
RelocStyle rs;
|
||||
if (hasMOVWT())
|
||||
if (HasMOVWT())
|
||||
rs = L_MOVWT;
|
||||
else
|
||||
rs = L_LDR;
|
||||
@ -1771,7 +1771,7 @@ MacroAssemblerARMCompat::callWithExitFrame(JitCode *target, Register dynStack)
|
||||
|
||||
addPendingJump(m_buffer.nextOffset(), ImmPtr(target->raw()), Relocation::JITCODE);
|
||||
RelocStyle rs;
|
||||
if (hasMOVWT())
|
||||
if (HasMOVWT())
|
||||
rs = L_MOVWT;
|
||||
else
|
||||
rs = L_LDR;
|
||||
@ -2052,7 +2052,7 @@ void
|
||||
MacroAssemblerARMCompat::movePtr(AsmJSImmPtr imm, Register dest)
|
||||
{
|
||||
RelocStyle rs;
|
||||
if (hasMOVWT())
|
||||
if (HasMOVWT())
|
||||
rs = L_MOVWT;
|
||||
else
|
||||
rs = L_LDR;
|
||||
@ -2441,7 +2441,7 @@ MacroAssembler::clampDoubleToUint8(FloatRegister input, Register output)
|
||||
{
|
||||
JS_ASSERT(input != ScratchFloatReg);
|
||||
ma_vimm(0.5, ScratchFloatReg);
|
||||
if (hasVFPv3()) {
|
||||
if (HasVFPv3()) {
|
||||
Label notSplit;
|
||||
ma_vadd(input, ScratchFloatReg, ScratchFloatReg);
|
||||
// Convert the double into an unsigned fixed point value with 24 bits of
|
||||
@ -3619,7 +3619,7 @@ void
|
||||
MacroAssemblerARM::ma_call(ImmPtr dest)
|
||||
{
|
||||
RelocStyle rs;
|
||||
if (hasMOVWT())
|
||||
if (HasMOVWT())
|
||||
rs = L_MOVWT;
|
||||
else
|
||||
rs = L_LDR;
|
||||
@ -3837,7 +3837,7 @@ void
|
||||
MacroAssemblerARMCompat::passABIArg(const MoveOperand &from, MoveOp::Type type)
|
||||
{
|
||||
#if defined(JS_ARM_SIMULATOR)
|
||||
if (useHardFpABI())
|
||||
if (UseHardFpABI())
|
||||
MacroAssemblerARMCompat::passHardFpABIArg(from, type);
|
||||
else
|
||||
MacroAssemblerARMCompat::passSoftFpABIArg(from, type);
|
||||
@ -3875,7 +3875,7 @@ MacroAssemblerARMCompat::callWithABIPre(uint32_t *stackAdjust, bool callFromAsmJ
|
||||
|
||||
*stackAdjust = ((usedIntSlots_ > NumIntArgRegs) ? usedIntSlots_ - NumIntArgRegs : 0) * sizeof(intptr_t);
|
||||
#if defined(JS_CODEGEN_ARM_HARDFP) || defined(JS_ARM_SIMULATOR)
|
||||
if (useHardFpABI())
|
||||
if (UseHardFpABI())
|
||||
*stackAdjust += 2*((usedFloatSlots_ > NumFloatArgRegs) ? usedFloatSlots_ - NumFloatArgRegs : 0) * sizeof(intptr_t);
|
||||
#endif
|
||||
uint32_t alignmentAtPrologue = callFromAsmJS ? AsmJSFrameSize : 0;
|
||||
@ -3937,13 +3937,13 @@ MacroAssemblerARMCompat::callWithABIPost(uint32_t stackAdjust, MoveOp::Type resu
|
||||
|
||||
switch (result) {
|
||||
case MoveOp::DOUBLE:
|
||||
if (!useHardFpABI()) {
|
||||
if (!UseHardFpABI()) {
|
||||
// Move double from r0/r1 to ReturnFloatReg.
|
||||
as_vxfer(r0, r1, ReturnFloatReg, CoreToFloat);
|
||||
break;
|
||||
}
|
||||
case MoveOp::FLOAT32:
|
||||
if (!useHardFpABI()) {
|
||||
if (!UseHardFpABI()) {
|
||||
// Move float32 from r0 to ReturnFloatReg.
|
||||
as_vxfer(r0, InvalidReg, VFPRegister(d0).singleOverlay(), CoreToFloat);
|
||||
break;
|
||||
@ -4363,7 +4363,7 @@ MacroAssemblerARMCompat::toggledCall(JitCode *target, bool enabled)
|
||||
BufferOffset bo = nextOffset();
|
||||
CodeOffsetLabel offset(bo.getOffset());
|
||||
addPendingJump(bo, ImmPtr(target->raw()), Relocation::JITCODE);
|
||||
ma_movPatchable(ImmPtr(target->raw()), ScratchRegister, Always, hasMOVWT() ? L_MOVWT : L_LDR);
|
||||
ma_movPatchable(ImmPtr(target->raw()), ScratchRegister, Always, HasMOVWT() ? L_MOVWT : L_LDR);
|
||||
if (enabled)
|
||||
ma_blx(ScratchRegister);
|
||||
else
|
||||
|
@ -560,7 +560,7 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM
|
||||
BufferOffset bo = m_buffer.nextOffset();
|
||||
addPendingJump(bo, ImmPtr(c->raw()), Relocation::JITCODE);
|
||||
RelocStyle rs;
|
||||
if (hasMOVWT())
|
||||
if (HasMOVWT())
|
||||
rs = L_MOVWT;
|
||||
else
|
||||
rs = L_LDR;
|
||||
@ -606,7 +606,7 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM
|
||||
BufferOffset bo = m_buffer.nextOffset();
|
||||
addPendingJump(bo, ImmPtr(c->raw()), Relocation::JITCODE);
|
||||
RelocStyle rs;
|
||||
if (hasMOVWT())
|
||||
if (HasMOVWT())
|
||||
rs = L_MOVWT;
|
||||
else
|
||||
rs = L_LDR;
|
||||
@ -681,7 +681,7 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM
|
||||
CodeOffsetLabel toggledCall(JitCode *target, bool enabled);
|
||||
|
||||
static size_t ToggledCallSize() {
|
||||
if (hasMOVWT())
|
||||
if (HasMOVWT())
|
||||
// Size of a movw, movt, nop/blx instruction.
|
||||
return 12;
|
||||
// Size of a ldr, nop/blx instruction
|
||||
@ -696,7 +696,7 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM
|
||||
|
||||
CodeOffsetLabel movWithPatch(ImmWord imm, Register dest) {
|
||||
CodeOffsetLabel label = CodeOffsetLabel(currentOffset());
|
||||
ma_movPatchable(Imm32(imm.value), dest, Always, hasMOVWT() ? L_MOVWT : L_LDR);
|
||||
ma_movPatchable(Imm32(imm.value), dest, Always, HasMOVWT() ? L_MOVWT : L_LDR);
|
||||
return label;
|
||||
}
|
||||
CodeOffsetLabel movWithPatch(ImmPtr imm, Register dest) {
|
||||
|
@ -1437,7 +1437,7 @@ ReturnType Simulator::getFromVFPRegister(int reg_index)
|
||||
void
|
||||
Simulator::getFpArgs(double *x, double *y, int32_t *z)
|
||||
{
|
||||
if (useHardFpABI()) {
|
||||
if (UseHardFpABI()) {
|
||||
*x = get_double_from_d_register(0);
|
||||
*y = get_double_from_d_register(1);
|
||||
*z = get_register(0);
|
||||
@ -1452,7 +1452,7 @@ void
|
||||
Simulator::setCallResultDouble(double result)
|
||||
{
|
||||
// The return value is either in r0/r1 or d0.
|
||||
if (useHardFpABI()) {
|
||||
if (UseHardFpABI()) {
|
||||
char buffer[2 * sizeof(vfp_registers_[0])];
|
||||
memcpy(buffer, &result, sizeof(buffer));
|
||||
// Copy result to d0.
|
||||
@ -1468,7 +1468,7 @@ Simulator::setCallResultDouble(double result)
|
||||
void
|
||||
Simulator::setCallResultFloat(float result)
|
||||
{
|
||||
if (useHardFpABI()) {
|
||||
if (UseHardFpABI()) {
|
||||
char buffer[sizeof(registers_[0])];
|
||||
memcpy(buffer, &result, sizeof(buffer));
|
||||
// Copy result to s0.
|
||||
@ -2224,7 +2224,7 @@ Simulator::softwareInterrupt(SimInstruction *instr)
|
||||
}
|
||||
case Args_Float32_Float32: {
|
||||
float fval0;
|
||||
if (useHardFpABI())
|
||||
if (UseHardFpABI())
|
||||
fval0 = get_float_from_s_register(0);
|
||||
else
|
||||
fval0 = mozilla::BitwiseCast<float>(arg0);
|
||||
@ -2264,7 +2264,7 @@ Simulator::softwareInterrupt(SimInstruction *instr)
|
||||
case Args_Double_IntDouble: {
|
||||
int32_t ival = get_register(0);
|
||||
double dval0;
|
||||
if (useHardFpABI())
|
||||
if (UseHardFpABI())
|
||||
dval0 = get_double_from_d_register(0);
|
||||
else
|
||||
dval0 = get_double_from_register_pair(2);
|
||||
@ -2277,7 +2277,7 @@ Simulator::softwareInterrupt(SimInstruction *instr)
|
||||
case Args_Int_IntDouble: {
|
||||
int32_t ival = get_register(0);
|
||||
double dval0;
|
||||
if (useHardFpABI())
|
||||
if (UseHardFpABI())
|
||||
dval0 = get_double_from_d_register(0);
|
||||
else
|
||||
dval0 = get_double_from_register_pair(2);
|
||||
|
@ -6098,6 +6098,11 @@ SetRuntimeOptions(JSRuntime *rt, const OptionParser &op)
|
||||
|
||||
#endif // JS_ION
|
||||
|
||||
#if defined(JS_CODEGEN_ARM)
|
||||
if (const char *str = op.getStringOption("arm-hwcap"))
|
||||
jit::ParseARMHwCapFlags(str);
|
||||
#endif
|
||||
|
||||
#if defined(JS_ARM_SIMULATOR)
|
||||
if (op.getBoolOption("arm-sim-icache-checks"))
|
||||
jit::Simulator::ICacheCheckingEnabled = true;
|
||||
@ -6317,6 +6322,10 @@ main(int argc, char **argv, char **envp)
|
||||
#endif
|
||||
|| !op.addIntOption('\0', "available-memory", "SIZE",
|
||||
"Select GC settings based on available memory (MB)", 0)
|
||||
#if defined(JS_CODEGEN_ARM)
|
||||
|| !op.addStringOption('\0', "arm-hwcap", "[features]",
|
||||
"Specify ARM code generation features, or 'help' to list all features.")
|
||||
#endif
|
||||
#if defined(JS_ARM_SIMULATOR)
|
||||
|| !op.addBoolOption('\0', "arm-sim-icache-checks", "Enable icache flush checks in the ARM "
|
||||
"simulator.")
|
||||
|
@ -248,7 +248,7 @@ JitSupportsFloatingPoint()
|
||||
return false;
|
||||
|
||||
#if defined(JS_ION) && WTF_ARM_ARCH_VERSION == 6
|
||||
if (!js::jit::hasVFP())
|
||||
if (!js::jit::HasVFP())
|
||||
return false;
|
||||
#endif
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user