ARM: Remove support for ABI prior to EABI
The support for the old ABI is known to be broken and has been deprecated for some time now. Removed the instructions for loading and storing co-processor registers as they where only used to support the old ABI. R=karlklose@chromium.org BUG=v8:1316 TEST= Review URL: http://codereview.chromium.org//6822025 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@7565 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
a700211937
commit
75759805a9
@ -1824,45 +1824,6 @@ void Assembler::ldc2(Coprocessor coproc,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Assembler::stc(Coprocessor coproc,
|
|
||||||
CRegister crd,
|
|
||||||
const MemOperand& dst,
|
|
||||||
LFlag l,
|
|
||||||
Condition cond) {
|
|
||||||
addrmod5(cond | B27 | B26 | l | coproc*B8, crd, dst);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Assembler::stc(Coprocessor coproc,
|
|
||||||
CRegister crd,
|
|
||||||
Register rn,
|
|
||||||
int option,
|
|
||||||
LFlag l,
|
|
||||||
Condition cond) {
|
|
||||||
// Unindexed addressing.
|
|
||||||
ASSERT(is_uint8(option));
|
|
||||||
emit(cond | B27 | B26 | U | l | rn.code()*B16 | crd.code()*B12 |
|
|
||||||
coproc*B8 | (option & 255));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Assembler::stc2(Coprocessor
|
|
||||||
coproc, CRegister crd,
|
|
||||||
const MemOperand& dst,
|
|
||||||
LFlag l) { // v5 and above
|
|
||||||
stc(coproc, crd, dst, l, kSpecialCondition);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Assembler::stc2(Coprocessor coproc,
|
|
||||||
CRegister crd,
|
|
||||||
Register rn,
|
|
||||||
int option,
|
|
||||||
LFlag l) { // v5 and above
|
|
||||||
stc(coproc, crd, rn, option, l, kSpecialCondition);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Support for VFP.
|
// Support for VFP.
|
||||||
|
|
||||||
void Assembler::vldr(const DwVfpRegister dst,
|
void Assembler::vldr(const DwVfpRegister dst,
|
||||||
|
@ -947,16 +947,6 @@ class Assembler : public AssemblerBase {
|
|||||||
void ldc2(Coprocessor coproc, CRegister crd, Register base, int option,
|
void ldc2(Coprocessor coproc, CRegister crd, Register base, int option,
|
||||||
LFlag l = Short); // v5 and above
|
LFlag l = Short); // v5 and above
|
||||||
|
|
||||||
void stc(Coprocessor coproc, CRegister crd, const MemOperand& dst,
|
|
||||||
LFlag l = Short, Condition cond = al);
|
|
||||||
void stc(Coprocessor coproc, CRegister crd, Register base, int option,
|
|
||||||
LFlag l = Short, Condition cond = al);
|
|
||||||
|
|
||||||
void stc2(Coprocessor coproc, CRegister crd, const MemOperand& dst,
|
|
||||||
LFlag l = Short); // v5 and above
|
|
||||||
void stc2(Coprocessor coproc, CRegister crd, Register base, int option,
|
|
||||||
LFlag l = Short); // v5 and above
|
|
||||||
|
|
||||||
// Support for VFP.
|
// Support for VFP.
|
||||||
// All these APIs support S0 to S31 and D0 to D15.
|
// All these APIs support S0 to S31 and D0 to D15.
|
||||||
// Currently these APIs do not support extended D registers, i.e, D16 to D31.
|
// Currently these APIs do not support extended D registers, i.e, D16 to D31.
|
||||||
|
@ -308,13 +308,9 @@ class ConvertToDoubleStub : public CodeStub {
|
|||||||
|
|
||||||
|
|
||||||
void ConvertToDoubleStub::Generate(MacroAssembler* masm) {
|
void ConvertToDoubleStub::Generate(MacroAssembler* masm) {
|
||||||
#ifndef BIG_ENDIAN_FLOATING_POINT
|
|
||||||
Register exponent = result1_;
|
|
||||||
Register mantissa = result2_;
|
|
||||||
#else
|
|
||||||
Register exponent = result2_;
|
Register exponent = result2_;
|
||||||
Register mantissa = result1_;
|
Register mantissa = result1_;
|
||||||
#endif
|
|
||||||
Label not_special;
|
Label not_special;
|
||||||
// Convert from Smi to integer.
|
// Convert from Smi to integer.
|
||||||
__ mov(source_, Operand(source_, ASR, kSmiTagSize));
|
__ mov(source_, Operand(source_, ASR, kSmiTagSize));
|
||||||
@ -951,18 +947,10 @@ void FloatingPointHelper::CallCCodeForDoubleOperation(
|
|||||||
// Call C routine that may not cause GC or other trouble.
|
// Call C routine that may not cause GC or other trouble.
|
||||||
__ CallCFunction(ExternalReference::double_fp_operation(op, masm->isolate()),
|
__ CallCFunction(ExternalReference::double_fp_operation(op, masm->isolate()),
|
||||||
4);
|
4);
|
||||||
// Store answer in the overwritable heap number.
|
// Store answer in the overwritable heap number. Double returned in
|
||||||
#if !defined(USE_ARM_EABI)
|
// registers r0 and r1.
|
||||||
// Double returned in fp coprocessor register 0 and 1, encoded as
|
|
||||||
// register cr8. Offsets must be divisible by 4 for coprocessor so we
|
|
||||||
// need to substract the tag from heap_number_result.
|
|
||||||
__ sub(scratch, heap_number_result, Operand(kHeapObjectTag));
|
|
||||||
__ stc(p1, cr8, MemOperand(scratch, HeapNumber::kValueOffset));
|
|
||||||
#else
|
|
||||||
// Double returned in registers 0 and 1.
|
|
||||||
__ Strd(r0, r1, FieldMemOperand(heap_number_result,
|
__ Strd(r0, r1, FieldMemOperand(heap_number_result,
|
||||||
HeapNumber::kValueOffset));
|
HeapNumber::kValueOffset));
|
||||||
#endif
|
|
||||||
// Place heap_number_result in r0 and return to the pushed return address.
|
// Place heap_number_result in r0 and return to the pushed return address.
|
||||||
__ mov(r0, Operand(heap_number_result));
|
__ mov(r0, Operand(heap_number_result));
|
||||||
__ pop(pc);
|
__ pop(pc);
|
||||||
@ -2047,17 +2035,9 @@ void GenericBinaryOpStub::HandleBinaryOpSlowCases(
|
|||||||
// save.
|
// save.
|
||||||
__ CallCFunction(
|
__ CallCFunction(
|
||||||
ExternalReference::double_fp_operation(op_, masm->isolate()), 4);
|
ExternalReference::double_fp_operation(op_, masm->isolate()), 4);
|
||||||
// Store answer in the overwritable heap number.
|
// Store answer in the overwritable heap number. Double
|
||||||
#if !defined(USE_ARM_EABI)
|
// returned in registers r0 and r1.
|
||||||
// Double returned in fp coprocessor register 0 and 1, encoded as
|
|
||||||
// register cr8. Offsets must be divisible by 4 for coprocessor so we
|
|
||||||
// need to substract the tag from r5.
|
|
||||||
__ sub(r4, r5, Operand(kHeapObjectTag));
|
|
||||||
__ stc(p1, cr8, MemOperand(r4, HeapNumber::kValueOffset));
|
|
||||||
#else
|
|
||||||
// Double returned in registers 0 and 1.
|
|
||||||
__ Strd(r0, r1, FieldMemOperand(r5, HeapNumber::kValueOffset));
|
__ Strd(r0, r1, FieldMemOperand(r5, HeapNumber::kValueOffset));
|
||||||
#endif
|
|
||||||
__ mov(r0, Operand(r5));
|
__ mov(r0, Operand(r5));
|
||||||
// And we are done.
|
// And we are done.
|
||||||
__ pop(pc);
|
__ pop(pc);
|
||||||
|
@ -28,12 +28,9 @@
|
|||||||
#ifndef V8_ARM_CONSTANTS_ARM_H_
|
#ifndef V8_ARM_CONSTANTS_ARM_H_
|
||||||
#define V8_ARM_CONSTANTS_ARM_H_
|
#define V8_ARM_CONSTANTS_ARM_H_
|
||||||
|
|
||||||
// The simulator emulates the EABI so we define the USE_ARM_EABI macro if we
|
// ARM EABI is required.
|
||||||
// are not running on real ARM hardware. One reason for this is that the
|
#if defined(__arm__) && !defined(__ARM_EABI__)
|
||||||
// old ABI uses fp registers in the calling convention and the simulator does
|
#error ARM EABI support is required.
|
||||||
// not simulate fp registers or coroutine instructions.
|
|
||||||
#if defined(__ARM_EABI__) || !defined(__arm__)
|
|
||||||
# define USE_ARM_EABI 1
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// This means that interwork-compatible jump instructions are generated. We
|
// This means that interwork-compatible jump instructions are generated. We
|
||||||
|
@ -75,62 +75,33 @@ void CPU::FlushICache(void* start, size_t size) {
|
|||||||
register uint32_t end asm("a2") =
|
register uint32_t end asm("a2") =
|
||||||
reinterpret_cast<uint32_t>(start) + size;
|
reinterpret_cast<uint32_t>(start) + size;
|
||||||
register uint32_t flg asm("a3") = 0;
|
register uint32_t flg asm("a3") = 0;
|
||||||
#ifdef __ARM_EABI__
|
#if defined (__arm__) && !defined(__thumb__)
|
||||||
#if defined (__arm__) && !defined(__thumb__)
|
// __arm__ may be defined in thumb mode.
|
||||||
// __arm__ may be defined in thumb mode.
|
register uint32_t scno asm("r7") = __ARM_NR_cacheflush;
|
||||||
register uint32_t scno asm("r7") = __ARM_NR_cacheflush;
|
asm volatile(
|
||||||
asm volatile(
|
"svc 0x0"
|
||||||
"svc 0x0"
|
: "=r" (beg)
|
||||||
: "=r" (beg)
|
: "0" (beg), "r" (end), "r" (flg), "r" (scno));
|
||||||
: "0" (beg), "r" (end), "r" (flg), "r" (scno));
|
|
||||||
#else
|
|
||||||
// r7 is reserved by the EABI in thumb mode.
|
|
||||||
asm volatile(
|
|
||||||
"@ Enter ARM Mode \n\t"
|
|
||||||
"adr r3, 1f \n\t"
|
|
||||||
"bx r3 \n\t"
|
|
||||||
".ALIGN 4 \n\t"
|
|
||||||
".ARM \n"
|
|
||||||
"1: push {r7} \n\t"
|
|
||||||
"mov r7, %4 \n\t"
|
|
||||||
"svc 0x0 \n\t"
|
|
||||||
"pop {r7} \n\t"
|
|
||||||
"@ Enter THUMB Mode\n\t"
|
|
||||||
"adr r3, 2f+1 \n\t"
|
|
||||||
"bx r3 \n\t"
|
|
||||||
".THUMB \n"
|
|
||||||
"2: \n\t"
|
|
||||||
: "=r" (beg)
|
|
||||||
: "0" (beg), "r" (end), "r" (flg), "r" (__ARM_NR_cacheflush)
|
|
||||||
: "r3");
|
|
||||||
#endif
|
|
||||||
#else
|
#else
|
||||||
#if defined (__arm__) && !defined(__thumb__)
|
// r7 is reserved by the EABI in thumb mode.
|
||||||
// __arm__ may be defined in thumb mode.
|
asm volatile(
|
||||||
asm volatile(
|
"@ Enter ARM Mode \n\t"
|
||||||
"svc %1"
|
"adr r3, 1f \n\t"
|
||||||
: "=r" (beg)
|
"bx r3 \n\t"
|
||||||
: "i" (__ARM_NR_cacheflush), "0" (beg), "r" (end), "r" (flg));
|
".ALIGN 4 \n\t"
|
||||||
#else
|
".ARM \n"
|
||||||
// Do not use the value of __ARM_NR_cacheflush in the inline assembly
|
"1: push {r7} \n\t"
|
||||||
// below, because the thumb mode value would be used, which would be
|
"mov r7, %4 \n\t"
|
||||||
// wrong, since we switch to ARM mode before executing the svc instruction
|
"svc 0x0 \n\t"
|
||||||
asm volatile(
|
"pop {r7} \n\t"
|
||||||
"@ Enter ARM Mode \n\t"
|
"@ Enter THUMB Mode\n\t"
|
||||||
"adr r3, 1f \n\t"
|
"adr r3, 2f+1 \n\t"
|
||||||
"bx r3 \n\t"
|
"bx r3 \n\t"
|
||||||
".ALIGN 4 \n\t"
|
".THUMB \n"
|
||||||
".ARM \n"
|
"2: \n\t"
|
||||||
"1: svc 0x9f0002 \n"
|
: "=r" (beg)
|
||||||
"@ Enter THUMB Mode\n\t"
|
: "0" (beg), "r" (end), "r" (flg), "r" (__ARM_NR_cacheflush)
|
||||||
"adr r3, 2f+1 \n\t"
|
: "r3");
|
||||||
"bx r3 \n\t"
|
|
||||||
".THUMB \n"
|
|
||||||
"2: \n\t"
|
|
||||||
: "=r" (beg)
|
|
||||||
: "0" (beg), "r" (end), "r" (flg)
|
|
||||||
: "r3");
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -839,11 +839,7 @@ void MacroAssembler::LeaveExitFrame(bool save_doubles,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MacroAssembler::GetCFunctionDoubleResult(const DoubleRegister dst) {
|
void MacroAssembler::GetCFunctionDoubleResult(const DoubleRegister dst) {
|
||||||
#if !defined(USE_ARM_EABI)
|
|
||||||
UNREACHABLE();
|
|
||||||
#else
|
|
||||||
vmov(dst, r0, r1);
|
vmov(dst, r0, r1);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -938,12 +938,7 @@ void Simulator::set_d_register_from_double(int dreg, const double& dbl) {
|
|||||||
// 2*sreg and 2*sreg+1.
|
// 2*sreg and 2*sreg+1.
|
||||||
char buffer[2 * sizeof(vfp_register[0])];
|
char buffer[2 * sizeof(vfp_register[0])];
|
||||||
memcpy(buffer, &dbl, 2 * sizeof(vfp_register[0]));
|
memcpy(buffer, &dbl, 2 * sizeof(vfp_register[0]));
|
||||||
#ifndef BIG_ENDIAN_FLOATING_POINT
|
|
||||||
memcpy(&vfp_register[dreg * 2], buffer, 2 * sizeof(vfp_register[0]));
|
memcpy(&vfp_register[dreg * 2], buffer, 2 * sizeof(vfp_register[0]));
|
||||||
#else
|
|
||||||
memcpy(&vfp_register[dreg * 2], &buffer[4], sizeof(vfp_register[0]));
|
|
||||||
memcpy(&vfp_register[dreg * 2 + 1], &buffer[0], sizeof(vfp_register[0]));
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -980,12 +975,7 @@ double Simulator::get_double_from_d_register(int dreg) {
|
|||||||
// Read the bits from the unsigned integer vfp_register[] array
|
// Read the bits from the unsigned integer vfp_register[] array
|
||||||
// into the double precision floating point value and return it.
|
// into the double precision floating point value and return it.
|
||||||
char buffer[2 * sizeof(vfp_register[0])];
|
char buffer[2 * sizeof(vfp_register[0])];
|
||||||
#ifdef BIG_ENDIAN_FLOATING_POINT
|
|
||||||
memcpy(&buffer[0], &vfp_register[2 * dreg + 1], sizeof(vfp_register[0]));
|
|
||||||
memcpy(&buffer[4], &vfp_register[2 * dreg], sizeof(vfp_register[0]));
|
|
||||||
#else
|
|
||||||
memcpy(buffer, &vfp_register[2 * dreg], 2 * sizeof(vfp_register[0]));
|
memcpy(buffer, &vfp_register[2 * dreg], 2 * sizeof(vfp_register[0]));
|
||||||
#endif
|
|
||||||
memcpy(&dm_val, buffer, 2 * sizeof(vfp_register[0]));
|
memcpy(&dm_val, buffer, 2 * sizeof(vfp_register[0]));
|
||||||
return(dm_val);
|
return(dm_val);
|
||||||
}
|
}
|
||||||
|
@ -60,11 +60,7 @@ static inline unsigned int FastD2UI(double x) {
|
|||||||
if (x < k2Pow52) {
|
if (x < k2Pow52) {
|
||||||
x += k2Pow52;
|
x += k2Pow52;
|
||||||
uint32_t result;
|
uint32_t result;
|
||||||
#ifdef BIG_ENDIAN_FLOATING_POINT
|
|
||||||
Address mantissa_ptr = reinterpret_cast<Address>(&x) + kIntSize;
|
|
||||||
#else
|
|
||||||
Address mantissa_ptr = reinterpret_cast<Address>(&x);
|
Address mantissa_ptr = reinterpret_cast<Address>(&x);
|
||||||
#endif
|
|
||||||
// Copy least significant 32 bits of mantissa.
|
// Copy least significant 32 bits of mantissa.
|
||||||
memcpy(&result, mantissa_ptr, sizeof(result));
|
memcpy(&result, mantissa_ptr, sizeof(result));
|
||||||
return negative ? ~result + 1 : result;
|
return negative ? ~result + 1 : result;
|
||||||
|
@ -1293,14 +1293,9 @@ class HeapNumber: public HeapObject {
|
|||||||
// is a mixture of sign, exponent and mantissa. Our current platforms are all
|
// is a mixture of sign, exponent and mantissa. Our current platforms are all
|
||||||
// little endian apart from non-EABI arm which is little endian with big
|
// little endian apart from non-EABI arm which is little endian with big
|
||||||
// endian floating point word ordering!
|
// endian floating point word ordering!
|
||||||
#if !defined(V8_HOST_ARCH_ARM) || defined(USE_ARM_EABI)
|
|
||||||
static const int kMantissaOffset = kValueOffset;
|
static const int kMantissaOffset = kValueOffset;
|
||||||
static const int kExponentOffset = kValueOffset + 4;
|
static const int kExponentOffset = kValueOffset + 4;
|
||||||
#else
|
|
||||||
static const int kMantissaOffset = kValueOffset + 4;
|
|
||||||
static const int kExponentOffset = kValueOffset;
|
|
||||||
# define BIG_ENDIAN_FLOATING_POINT 1
|
|
||||||
#endif
|
|
||||||
static const int kSize = kValueOffset + kDoubleSize;
|
static const int kSize = kValueOffset + kDoubleSize;
|
||||||
static const uint32_t kSignMask = 0x80000000u;
|
static const uint32_t kSignMask = 0x80000000u;
|
||||||
static const uint32_t kExponentMask = 0x7ff00000u;
|
static const uint32_t kExponentMask = 0x7ff00000u;
|
||||||
|
@ -193,11 +193,7 @@ void V8::InitializeOncePerProcess() {
|
|||||||
// Setup the platform OS support.
|
// Setup the platform OS support.
|
||||||
OS::Setup();
|
OS::Setup();
|
||||||
|
|
||||||
#if defined(V8_TARGET_ARCH_ARM) && !defined(USE_ARM_EABI)
|
|
||||||
use_crankshaft_ = false;
|
|
||||||
#else
|
|
||||||
use_crankshaft_ = FLAG_crankshaft;
|
use_crankshaft_ = FLAG_crankshaft;
|
||||||
#endif
|
|
||||||
|
|
||||||
if (Serializer::enabled()) {
|
if (Serializer::enabled()) {
|
||||||
use_crankshaft_ = false;
|
use_crankshaft_ = false;
|
||||||
|
@ -12347,28 +12347,14 @@ THREADED_TEST(GetHeapStatistics) {
|
|||||||
|
|
||||||
static double DoubleFromBits(uint64_t value) {
|
static double DoubleFromBits(uint64_t value) {
|
||||||
double target;
|
double target;
|
||||||
#ifdef BIG_ENDIAN_FLOATING_POINT
|
|
||||||
const int kIntSize = 4;
|
|
||||||
// Somebody swapped the lower and higher half of doubles.
|
|
||||||
memcpy(&target, reinterpret_cast<char*>(&value) + kIntSize, kIntSize);
|
|
||||||
memcpy(reinterpret_cast<char*>(&target) + kIntSize, &value, kIntSize);
|
|
||||||
#else
|
|
||||||
memcpy(&target, &value, sizeof(target));
|
memcpy(&target, &value, sizeof(target));
|
||||||
#endif
|
|
||||||
return target;
|
return target;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static uint64_t DoubleToBits(double value) {
|
static uint64_t DoubleToBits(double value) {
|
||||||
uint64_t target;
|
uint64_t target;
|
||||||
#ifdef BIG_ENDIAN_FLOATING_POINT
|
|
||||||
const int kIntSize = 4;
|
|
||||||
// Somebody swapped the lower and higher half of doubles.
|
|
||||||
memcpy(&target, reinterpret_cast<char*>(&value) + kIntSize, kIntSize);
|
|
||||||
memcpy(reinterpret_cast<char*>(&target) + kIntSize, &value, kIntSize);
|
|
||||||
#else
|
|
||||||
memcpy(&target, &value, sizeof(target));
|
memcpy(&target, &value, sizeof(target));
|
||||||
#endif
|
|
||||||
return target;
|
return target;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user