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:
Douglas Crosher 2014-06-24 14:43:23 +10:00
parent 7030e104d4
commit de42e7d43f
12 changed files with 169 additions and 139 deletions

View File

@ -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()) {

View File

@ -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;
}

View File

@ -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;

View File

@ -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);
}

View File

@ -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) {

View File

@ -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);

View File

@ -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));

View File

@ -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

View File

@ -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) {

View File

@ -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);

View File

@ -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.")

View File

@ -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