diff --git a/js/src/ion/IonMacroAssembler.cpp b/js/src/ion/IonMacroAssembler.cpp index bc76d2175637..df94c54348cc 100644 --- a/js/src/ion/IonMacroAssembler.cpp +++ b/js/src/ion/IonMacroAssembler.cpp @@ -325,53 +325,29 @@ MacroAssembler::clampDoubleToUint8(FloatRegister input, Register output) { JS_ASSERT(input != ScratchFloatReg); #ifdef JS_CPU_ARM + Label notSplit; ma_vimm(0.5, ScratchFloatReg); - if (hasVFPv3()) { - Label notSplit; - ma_vadd(input, ScratchFloatReg, ScratchFloatReg); - // Convert the double into an unsigned fixed point value with 24 bits of - // precision. The resulting number will look like 0xII.DDDDDD - as_vcvtFixed(ScratchFloatReg, false, 24, true); - // Move the fixed point value into an integer register - as_vxfer(output, InvalidReg, ScratchFloatReg, FloatToCore); - // see if this value *might* have been an exact integer after adding 0.5 - // This tests the 1/2 through 1/16,777,216th places, but 0.5 needs to be tested out to - // the 1/140,737,488,355,328th place. - ma_tst(output, Imm32(0x00ffffff)); - // convert to a uint8 by shifting out all of the fraction bits - ma_lsr(Imm32(24), output, output); - // If any of the bottom 24 bits were non-zero, then we're good, since this number - // can't be exactly XX.0 - ma_b(¬Split, NonZero); - as_vxfer(ScratchRegister, InvalidReg, input, FloatToCore); - ma_cmp(ScratchRegister, Imm32(0)); - // If the lower 32 bits of the double were 0, then this was an exact number, - // and it should be even. - ma_bic(Imm32(1), output, NoSetCond, Zero); - bind(¬Split); - - } else { - Label outOfRange; - ma_vcmpz(input); - // do the add, in place so we can reference it later - ma_vadd(input, ScratchFloatReg, input); - // do the conversion to an integer. - as_vcvt(VFPRegister(ScratchFloatReg).uintOverlay(), VFPRegister(input)); - // copy the converted value out - as_vxfer(output, InvalidReg, ScratchFloatReg, FloatToCore); - as_vmrs(pc); - ma_b(&outOfRange, Overflow); - ma_cmp(output, Imm32(0xff)); - ma_mov(Imm32(0xff), output, NoSetCond, Above); - ma_b(&outOfRange, Above); - // convert it back to see if we got the same value back - as_vcvt(ScratchFloatReg, VFPRegister(ScratchFloatReg).uintOverlay()); - // do the check - as_vcmp(ScratchFloatReg, input); - as_vmrs(pc); - ma_bic(Imm32(1), output, NoSetCond, Zero); - bind(&outOfRange); - } + ma_vadd(input, ScratchFloatReg, ScratchFloatReg); + // Convert the double into an unsigned fixed point value with 24 bits of + // precision. The resulting number will look like 0xII.DDDDDD + as_vcvtFixed(ScratchFloatReg, false, 24, true); + // Move the fixed point value into an integer register + as_vxfer(output, InvalidReg, ScratchFloatReg, FloatToCore); + // See if this value *might* have been an exact integer after adding 0.5 + // This tests the 1/2 through 1/16,777,216th places, but 0.5 needs to be tested out to + // the 1/140,737,488,355,328th place. + ma_tst(output, Imm32(0x00ffffff)); + // convert to a uint8 by shifting out all of the fraction bits + ma_lsr(Imm32(24), output, output); + // If any of the bottom 24 bits were non-zero, then we're good, since this number + // can't be exactly XX.0 + ma_b(¬Split, NonZero); + as_vxfer(ScratchRegister, InvalidReg, input, FloatToCore); + ma_cmp(ScratchRegister, Imm32(0)); + // If the lower 32 bits of the double were 0, then this was an exact number, + // and it should be even. + ma_bic(Imm32(1), output, NoSetCond, Zero); + bind(¬Split); #else Label positive, done; diff --git a/js/src/ion/arm/Architecture-arm.cpp b/js/src/ion/arm/Architecture-arm.cpp index 41d8225e8bdb..951006f546a6 100644 --- a/js/src/ion/arm/Architecture-arm.cpp +++ b/js/src/ion/arm/Architecture-arm.cpp @@ -4,115 +4,21 @@ * 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/. */ -#define HWCAP_ARMv7 (1 << 31) -#include -#include -#include -#include -#include -#include - -// lame check for kernel version -// see bug 586550 -#ifndef WTF_OS_ANDROID -#include -#endif -#include "ion/arm/Architecture-arm.h" -#include "ion/arm/Assembler-arm.h" namespace js { namespace ion { -uint32_t getFlags() -{ - static bool isSet = false; - static uint32_t flags = 0; - if (isSet) - return flags; - -#if WTF_OS_LINUX - int fd = open("/proc/self/auxv", O_RDONLY); - if (fd > 0) { - Elf32_auxv_t aux; - while (read(fd, &aux, sizeof(Elf32_auxv_t))) { - if (aux.a_type == AT_HWCAP) { - close(fd); - flags = aux.a_un.a_val; - isSet = true; -#ifdef __ARM_ARCH_7__ - // 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. - flags |= HWCAP_ARMv7; -#endif - return flags; - } - } - close(fd); - } -#elif defined(WTF_OS_ANDROID) - FILE *fp = fopen("/proc/cpuinfo", "r"); - if (!fp) - return false; - - char buf[1024]; - fread(buf, sizeof(char), sizeof(buf), fp); - fclose(fp); - if (strstr(buf, "vfp")) - flags |= HWCAP_VFP; - - if (strstr(buf, "vfpv3")) - flags |= HWCAP_VFPv3; - - if (strstr(buf, "vfpv3d16")) - flags |= HWCAP_VFPv3; - - if (strstr(buf, "vfpv4")) - flags |= HWCAP_VFPv4; - - if (strstr(buf, "idiva")) - flags |= HWCAP_IDIVA; - - if (strstr(buf, "idivt")) - flags |= HWCAP_IDIVT; - - 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 - if (strstr(buf, "ARMv7")) - flags |= HWCAP_ARMv7; - - isSet = true; - return flags; -#endif - - return false; -} - bool hasMOVWT() { - return js::ion::getFlags() & HWCAP_ARMv7; + return true; } bool hasVFPv3() { - return js::ion::getFlags() & HWCAP_VFPv3; + return true; } -bool hasVFP() +bool has32DR() { - return js::ion::getFlags() & HWCAP_VFP; -} - -bool has16DP() -{ - return js::ion::getFlags() & HWCAP_VFPv3D16 && !(js::ion::getFlags() & HWCAP_NEON); -} -bool useConvReg() -{ - return !has16DP(); + return true; } } // namespace ion diff --git a/js/src/ion/arm/Architecture-arm.h b/js/src/ion/arm/Architecture-arm.h index 2e367923b567..46ca0191020e 100644 --- a/js/src/ion/arm/Architecture-arm.h +++ b/js/src/ion/arm/Architecture-arm.h @@ -16,7 +16,7 @@ namespace js { namespace ion { -static const uint32_t STACK_SLOT_SIZE = 4; +static const ptrdiff_t STACK_SLOT_SIZE = 4; static const uint32_t DOUBLE_STACK_ALIGNMENT = 2; // In bytes: slots needed for potential memory->memory move spills. @@ -209,7 +209,6 @@ class FloatRegisters bool hasMOVWT(); bool hasVFPv3(); -bool hasVFP(); bool has16DP(); } // namespace ion diff --git a/js/src/ion/arm/Assembler-arm.cpp b/js/src/ion/arm/Assembler-arm.cpp index 0615485ecaa2..b18bfbff6b1a 100644 --- a/js/src/ion/arm/Assembler-arm.cpp +++ b/js/src/ion/arm/Assembler-arm.cpp @@ -160,7 +160,7 @@ InstDTR::isTHIS(const Instruction &i) } InstDTR * -InstDTR::asTHIS(const Instruction &i) +InstDTR::asTHIS(Instruction &i) { if (isTHIS(i)) return (InstDTR*)&i; @@ -174,7 +174,7 @@ InstLDR::isTHIS(const Instruction &i) } InstLDR * -InstLDR::asTHIS(const Instruction &i) +InstLDR::asTHIS(Instruction &i) { if (isTHIS(i)) return (InstLDR*)&i; @@ -605,20 +605,9 @@ Assembler::getCF32Target(Iter *iter) uint32_t *dest = (uint32_t*) (targ_bot.decode() | (targ_top.decode() << 16)); return dest; } - + if (inst1->is()) { - InstLDR *load = inst1->as(); - uint32_t inst = load->encode(); - // get the address of the instruction as a raw pointer - char *dataInst = reinterpret_cast(load); - IsUp_ iu = IsUp_(inst & IsUp); - int32_t offset = inst & 0xfff; - if (iu != IsUp) { - offset = - offset; - } - uint32_t **ptr = (uint32_t **)&dataInst[offset + 8]; - return *ptr; - + JS_NOT_REACHED("ldr-based relocs NYI"); } JS_NOT_REACHED("unsupported branch relocation"); @@ -669,22 +658,7 @@ Assembler::getPtr32Target(Iter *start, Register *dest, RelocStyle *style) uint32_t *value = (uint32_t*) (targ_bot.decode() | (targ_top.decode() << 16)); return value; } - if (load1->is()) { - InstLDR *load = load1->as(); - uint32_t inst = load->encode(); - // get the address of the instruction as a raw pointer - char *dataInst = reinterpret_cast(load); - IsUp_ iu = IsUp_(inst & IsUp); - int32_t offset = inst & 0xfff; - if (iu == IsDown) - offset = - offset; - if (dest) - *dest = toRD(*load); - if (style) - *style = L_LDR; - uint32_t **ptr = (uint32_t **)&dataInst[offset + 8]; - return *ptr; - } + JS_NOT_REACHED("unsupported relocation"); return NULL; } @@ -1565,20 +1539,6 @@ Assembler::as_Imm32Pool(Register dest, uint32_t value, ARMBuffer::PoolEntry *pe, php.phd.init(0, c, PoolHintData::poolDTR, dest); return m_buffer.insertEntry(4, (uint8_t*)&php.raw, int32Pool, (uint8_t*)&value, pe); } -void -Assembler::as_WritePoolEntry(Instruction *addr, Condition c, uint32_t data) -{ - JS_ASSERT(addr->is()); - int32_t offset = addr->encode() & 0xfff; - if ((addr->encode() & IsUp) != IsUp) - offset = -offset; - char * rawAddr = reinterpret_cast(addr); - uint32_t * dest = reinterpret_cast(&rawAddr[offset + 8]); - *dest = data; - Condition orig_cond; - addr->extractCond(&orig_cond); - JS_ASSERT(orig_cond == c); -} BufferOffset Assembler::as_BranchPool(uint32_t value, RepatchLabel *label, ARMBuffer::PoolEntry *pe, Condition c) @@ -2350,11 +2310,9 @@ Assembler::patchDataWithValueCheck(CodeLocationLabel label, ImmWord newValue, Im const uint32_t *val = getPtr32Target(&iter, &dest, &rs); JS_ASSERT((uint32_t)val == expectedValue.value); reinterpret_cast(dummy)->ma_movPatchable(Imm32(newValue.value), dest, Always, rs, ptr); - // L_LDR won't cause any instructions to be updated. - if (rs != L_LDR) { - AutoFlushCache::updateTop(uintptr_t(ptr), 4); - AutoFlushCache::updateTop(uintptr_t(ptr->next()), 4); - } + + AutoFlushCache::updateTop(uintptr_t(ptr), 4); + AutoFlushCache::updateTop(uintptr_t(ptr->next()), 4); } // This just stomps over memory with 32 bits of raw data. Its purpose is to diff --git a/js/src/ion/arm/Assembler-arm.h b/js/src/ion/arm/Assembler-arm.h index 1e15745a9d8a..81292b1aa661 100644 --- a/js/src/ion/arm/Assembler-arm.h +++ b/js/src/ion/arm/Assembler-arm.h @@ -1409,8 +1409,6 @@ class Assembler BufferOffset as_dtm(LoadStore ls, Register rn, uint32_t mask, DTMMode mode, DTMWriteBack wb, Condition c = Always); - //overwrite a pool entry with new data. - void as_WritePoolEntry(Instruction *addr, Condition c, uint32_t data); // load a 32 bit immediate from a pool into a register BufferOffset as_Imm32Pool(Register dest, uint32_t value, ARMBuffer::PoolEntry *pe = NULL, Condition c = Always); // make a patchable jump that can target the entire 32 bit address space. @@ -1791,7 +1789,7 @@ class InstDTR : public Instruction { } static bool isTHIS(const Instruction &i); - static InstDTR *asTHIS(const Instruction &i); + static InstDTR *asTHIS(Instruction &i); }; JS_STATIC_ASSERT(sizeof(InstDTR) == sizeof(Instruction)); @@ -1803,7 +1801,7 @@ class InstLDR : public InstDTR : InstDTR(IsLoad, IsWord, mode, rt, addr, c) { } static bool isTHIS(const Instruction &i); - static InstLDR *asTHIS(const Instruction &i); + static InstLDR *asTHIS(Instruction &i); }; JS_STATIC_ASSERT(sizeof(InstDTR) == sizeof(InstLDR)); diff --git a/js/src/ion/arm/MacroAssembler-arm.cpp b/js/src/ion/arm/MacroAssembler-arm.cpp index e645f88adc6d..a0a6ebe77b82 100644 --- a/js/src/ion/arm/MacroAssembler-arm.cpp +++ b/js/src/ion/arm/MacroAssembler-arm.cpp @@ -260,15 +260,7 @@ MacroAssemblerARM::ma_alu(Register src1, Imm32 imm, Register dest, if ((imm.value >> 16) != 0) as_movt(ScratchRegister, (imm.value >> 16) & 0xffff, c); } else { - // Going to have to use a load. If the operation is a move, then just move it into the - // destination register - if (op == op_mov) { - as_Imm32Pool(dest, imm.value, NULL, c); - return; - } else { - // If this isn't just going into a register, then stick it in a temp, and then proceed. - as_Imm32Pool(ScratchRegister, imm.value, NULL, c); - } + JS_NOT_REACHED("non-ARMv7 loading of immediates NYI."); } as_alu(dest, src1, O2Reg(ScratchRegister), op, sc, c); } @@ -309,17 +301,11 @@ MacroAssemblerARM::ma_movPatchable(Imm32 imm_, Register dest, switch(rs) { case L_MOVWT: as_movw(dest, Imm16(imm & 0xffff), c, i); - // i can be NULL here. that just means "insert in the next in sequence." - // NextInst is special cased to not do anything when it is passed NULL, so two - // consecutive instructions will be inserted. i = NextInst(i); as_movt(dest, Imm16(imm >> 16 & 0xffff), c, i); break; case L_LDR: - if(i == NULL) - as_Imm32Pool(dest, imm, NULL, c); - else - as_WritePoolEntry(i, c, imm); + //as_Imm32Pool(dest, imm, c, i); break; } } @@ -345,13 +331,7 @@ MacroAssemblerARM::ma_mov(const ImmGCPtr &ptr, Register dest) // As opposed to x86/x64 version, the data relocation has to be executed // before to recover the pointer, and not after. writeDataRelocation(ptr); - RelocStyle rs; - if (hasMOVWT()) { - rs = L_MOVWT; - } else { - rs = L_LDR; - } - ma_movPatchable(Imm32(ptr.value), dest, Always, rs); + ma_movPatchable(Imm32(ptr.value), dest, Always, L_MOVWT); } // Shifts (just a move with a shifting op2) @@ -1252,23 +1232,22 @@ MacroAssemblerARM::ma_vimm(double value, FloatRegister dest, Condition cc) double d; } dpun; dpun.d = value; - if (hasVFPv3()) { - if (dpun.s.lo == 0) { - if (dpun.s.hi == 0) { - // To zero a register, load 1.0, then execute dN <- dN - dN - VFPImm dblEnc(0x3FF00000); - as_vimm(dest, dblEnc, cc); - as_vsub(dest, dest, dest, cc); - return; - } - - VFPImm dblEnc(dpun.s.hi); - if (dblEnc.isValid()) { - as_vimm(dest, dblEnc, cc); - return; - } + if ((dpun.s.lo) == 0) { + if (dpun.s.hi == 0) { + // To zero a register, load 1.0, then execute dN <- dN - dN + VFPImm dblEnc(0x3FF00000); + as_vimm(dest, dblEnc, cc); + as_vsub(dest, dest, dest, cc); + return; } + + VFPImm dblEnc(dpun.s.hi); + if (dblEnc.isValid()) { + as_vimm(dest, dblEnc, cc); + return; + } + } // Fall back to putting the value in a pool. as_FImm64Pool(dest, value, NULL, cc); diff --git a/js/src/ion/arm/MacroAssembler-arm.h b/js/src/ion/arm/MacroAssembler-arm.h index 48795e760958..69a35ffcdb2c 100644 --- a/js/src/ion/arm/MacroAssembler-arm.h +++ b/js/src/ion/arm/MacroAssembler-arm.h @@ -556,7 +556,7 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM CodeOffsetLabel pushWithPatch(ImmWord imm) { CodeOffsetLabel label = currentOffset(); - ma_movPatchable(Imm32(imm.value), ScratchRegister, Always, hasMOVWT() ? L_MOVWT : L_LDR); + ma_movPatchable(Imm32(imm.value), ScratchRegister, Always, L_MOVWT); ma_push(ScratchRegister); return label; } diff --git a/js/src/jsinfer.cpp b/js/src/jsinfer.cpp index 0e565f46b170..032df1326faa 100644 --- a/js/src/jsinfer.cpp +++ b/js/src/jsinfer.cpp @@ -2390,13 +2390,9 @@ TypeInferenceSupported() #endif #if WTF_ARM_ARCH_VERSION == 6 -#ifdef JS_ION - return js::ion::hasVFP(); -#else // If building for ARMv6 targets, we can't be guaranteed an FPU, // so we hardcode TI off for consistency (see bug 793740). return false; -#endif #endif return true;