| Index: src/compiler/arm/code-generator-arm.cc
|
| diff --git a/src/compiler/arm/code-generator-arm.cc b/src/compiler/arm/code-generator-arm.cc
|
| index 2d0a37c9532095d79b632b53e1be8cf15ecfb4cd..fdddb684495c435e7180da45e33ae83f4f000419 100644
|
| --- a/src/compiler/arm/code-generator-arm.cc
|
| +++ b/src/compiler/arm/code-generator-arm.cc
|
| @@ -136,14 +136,25 @@ class ArmOperandConverter final : public InstructionOperandConverter {
|
| FrameOffset offset = frame_access_state()->GetFrameOffset(slot);
|
| return MemOperand(offset.from_stack_pointer() ? sp : fp, offset.offset());
|
| }
|
| -};
|
|
|
| + FloatRegister InputFloat32Register(size_t index) {
|
| + return ToFloat32Register(instr_->InputAt(index));
|
| + }
|
| +
|
| + FloatRegister OutputFloat32Register() {
|
| + return ToFloat32Register(instr_->Output());
|
| + }
|
| +
|
| + FloatRegister ToFloat32Register(InstructionOperand* op) {
|
| + return LowDwVfpRegister::from_code(ToDoubleRegister(op).code()).low();
|
| + }
|
| +};
|
|
|
| namespace {
|
|
|
| -class OutOfLineLoadFloat final : public OutOfLineCode {
|
| +class OutOfLineLoadFloat32 final : public OutOfLineCode {
|
| public:
|
| - OutOfLineLoadFloat(CodeGenerator* gen, SwVfpRegister result)
|
| + OutOfLineLoadFloat32(CodeGenerator* gen, SwVfpRegister result)
|
| : OutOfLineCode(gen), result_(result) {}
|
|
|
| void Generate() final {
|
| @@ -1074,54 +1085,54 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
|
| break;
|
| case kArmVcmpF32:
|
| if (instr->InputAt(1)->IsFPRegister()) {
|
| - __ VFPCompareAndSetFlags(i.InputFloatRegister(0),
|
| - i.InputFloatRegister(1));
|
| + __ VFPCompareAndSetFlags(i.InputFloat32Register(0),
|
| + i.InputFloat32Register(1));
|
| } else {
|
| DCHECK(instr->InputAt(1)->IsImmediate());
|
| // 0.0 is the only immediate supported by vcmp instructions.
|
| DCHECK(i.InputFloat32(1) == 0.0f);
|
| - __ VFPCompareAndSetFlags(i.InputFloatRegister(0), i.InputFloat32(1));
|
| + __ VFPCompareAndSetFlags(i.InputFloat32Register(0), i.InputFloat32(1));
|
| }
|
| DCHECK_EQ(SetCC, i.OutputSBit());
|
| break;
|
| case kArmVaddF32:
|
| - __ vadd(i.OutputFloatRegister(), i.InputFloatRegister(0),
|
| - i.InputFloatRegister(1));
|
| + __ vadd(i.OutputFloat32Register(), i.InputFloat32Register(0),
|
| + i.InputFloat32Register(1));
|
| DCHECK_EQ(LeaveCC, i.OutputSBit());
|
| break;
|
| case kArmVsubF32:
|
| - __ vsub(i.OutputFloatRegister(), i.InputFloatRegister(0),
|
| - i.InputFloatRegister(1));
|
| + __ vsub(i.OutputFloat32Register(), i.InputFloat32Register(0),
|
| + i.InputFloat32Register(1));
|
| DCHECK_EQ(LeaveCC, i.OutputSBit());
|
| break;
|
| case kArmVmulF32:
|
| - __ vmul(i.OutputFloatRegister(), i.InputFloatRegister(0),
|
| - i.InputFloatRegister(1));
|
| + __ vmul(i.OutputFloat32Register(), i.InputFloat32Register(0),
|
| + i.InputFloat32Register(1));
|
| DCHECK_EQ(LeaveCC, i.OutputSBit());
|
| break;
|
| case kArmVmlaF32:
|
| - __ vmla(i.OutputFloatRegister(), i.InputFloatRegister(1),
|
| - i.InputFloatRegister(2));
|
| + __ vmla(i.OutputFloat32Register(), i.InputFloat32Register(1),
|
| + i.InputFloat32Register(2));
|
| DCHECK_EQ(LeaveCC, i.OutputSBit());
|
| break;
|
| case kArmVmlsF32:
|
| - __ vmls(i.OutputFloatRegister(), i.InputFloatRegister(1),
|
| - i.InputFloatRegister(2));
|
| + __ vmls(i.OutputFloat32Register(), i.InputFloat32Register(1),
|
| + i.InputFloat32Register(2));
|
| DCHECK_EQ(LeaveCC, i.OutputSBit());
|
| break;
|
| case kArmVdivF32:
|
| - __ vdiv(i.OutputFloatRegister(), i.InputFloatRegister(0),
|
| - i.InputFloatRegister(1));
|
| + __ vdiv(i.OutputFloat32Register(), i.InputFloat32Register(0),
|
| + i.InputFloat32Register(1));
|
| DCHECK_EQ(LeaveCC, i.OutputSBit());
|
| break;
|
| case kArmVsqrtF32:
|
| - __ vsqrt(i.OutputFloatRegister(), i.InputFloatRegister(0));
|
| + __ vsqrt(i.OutputFloat32Register(), i.InputFloat32Register(0));
|
| break;
|
| case kArmVabsF32:
|
| - __ vabs(i.OutputFloatRegister(), i.InputFloatRegister(0));
|
| + __ vabs(i.OutputFloat32Register(), i.InputFloat32Register(0));
|
| break;
|
| case kArmVnegF32:
|
| - __ vneg(i.OutputFloatRegister(), i.InputFloatRegister(0));
|
| + __ vneg(i.OutputFloat32Register(), i.InputFloat32Register(0));
|
| break;
|
| case kArmVcmpF64:
|
| if (instr->InputAt(1)->IsFPRegister()) {
|
| @@ -1189,19 +1200,19 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
|
| __ vneg(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
|
| break;
|
| case kArmVrintmF32:
|
| - __ vrintm(i.OutputFloatRegister(), i.InputFloatRegister(0));
|
| + __ vrintm(i.OutputFloat32Register(), i.InputFloat32Register(0));
|
| break;
|
| case kArmVrintmF64:
|
| __ vrintm(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
|
| break;
|
| case kArmVrintpF32:
|
| - __ vrintp(i.OutputFloatRegister(), i.InputFloatRegister(0));
|
| + __ vrintp(i.OutputFloat32Register(), i.InputFloat32Register(0));
|
| break;
|
| case kArmVrintpF64:
|
| __ vrintp(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
|
| break;
|
| case kArmVrintzF32:
|
| - __ vrintz(i.OutputFloatRegister(), i.InputFloatRegister(0));
|
| + __ vrintz(i.OutputFloat32Register(), i.InputFloat32Register(0));
|
| break;
|
| case kArmVrintzF64:
|
| __ vrintz(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
|
| @@ -1210,32 +1221,32 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
|
| __ vrinta(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
|
| break;
|
| case kArmVrintnF32:
|
| - __ vrintn(i.OutputFloatRegister(), i.InputFloatRegister(0));
|
| + __ vrintn(i.OutputFloat32Register(), i.InputFloat32Register(0));
|
| break;
|
| case kArmVrintnF64:
|
| __ vrintn(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
|
| break;
|
| case kArmVcvtF32F64: {
|
| - __ vcvt_f32_f64(i.OutputFloatRegister(), i.InputDoubleRegister(0));
|
| + __ vcvt_f32_f64(i.OutputFloat32Register(), i.InputDoubleRegister(0));
|
| DCHECK_EQ(LeaveCC, i.OutputSBit());
|
| break;
|
| }
|
| case kArmVcvtF64F32: {
|
| - __ vcvt_f64_f32(i.OutputDoubleRegister(), i.InputFloatRegister(0));
|
| + __ vcvt_f64_f32(i.OutputDoubleRegister(), i.InputFloat32Register(0));
|
| DCHECK_EQ(LeaveCC, i.OutputSBit());
|
| break;
|
| }
|
| case kArmVcvtF32S32: {
|
| SwVfpRegister scratch = kScratchDoubleReg.low();
|
| __ vmov(scratch, i.InputRegister(0));
|
| - __ vcvt_f32_s32(i.OutputFloatRegister(), scratch);
|
| + __ vcvt_f32_s32(i.OutputFloat32Register(), scratch);
|
| DCHECK_EQ(LeaveCC, i.OutputSBit());
|
| break;
|
| }
|
| case kArmVcvtF32U32: {
|
| SwVfpRegister scratch = kScratchDoubleReg.low();
|
| __ vmov(scratch, i.InputRegister(0));
|
| - __ vcvt_f32_u32(i.OutputFloatRegister(), scratch);
|
| + __ vcvt_f32_u32(i.OutputFloat32Register(), scratch);
|
| DCHECK_EQ(LeaveCC, i.OutputSBit());
|
| break;
|
| }
|
| @@ -1255,7 +1266,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
|
| }
|
| case kArmVcvtS32F32: {
|
| SwVfpRegister scratch = kScratchDoubleReg.low();
|
| - __ vcvt_s32_f32(scratch, i.InputFloatRegister(0));
|
| + __ vcvt_s32_f32(scratch, i.InputFloat32Register(0));
|
| __ vmov(i.OutputRegister(), scratch);
|
| // Avoid INT32_MAX as an overflow indicator and use INT32_MIN instead,
|
| // because INT32_MIN allows easier out-of-bounds detection.
|
| @@ -1266,7 +1277,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
|
| }
|
| case kArmVcvtU32F32: {
|
| SwVfpRegister scratch = kScratchDoubleReg.low();
|
| - __ vcvt_u32_f32(scratch, i.InputFloatRegister(0));
|
| + __ vcvt_u32_f32(scratch, i.InputFloat32Register(0));
|
| __ vmov(i.OutputRegister(), scratch);
|
| // Avoid UINT32_MAX as an overflow indicator and use 0 instead,
|
| // because 0 allows easier out-of-bounds detection.
|
| @@ -1290,11 +1301,11 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
|
| break;
|
| }
|
| case kArmVmovU32F32:
|
| - __ vmov(i.OutputRegister(), i.InputFloatRegister(0));
|
| + __ vmov(i.OutputRegister(), i.InputFloat32Register(0));
|
| DCHECK_EQ(LeaveCC, i.OutputSBit());
|
| break;
|
| case kArmVmovF32U32:
|
| - __ vmov(i.OutputFloatRegister(), i.InputRegister(0));
|
| + __ vmov(i.OutputFloat32Register(), i.InputRegister(0));
|
| DCHECK_EQ(LeaveCC, i.OutputSBit());
|
| break;
|
| case kArmVmovLowU32F64:
|
| @@ -1352,12 +1363,12 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
|
| DCHECK_EQ(LeaveCC, i.OutputSBit());
|
| break;
|
| case kArmVldrF32: {
|
| - __ vldr(i.OutputFloatRegister(), i.InputOffset());
|
| + __ vldr(i.OutputFloat32Register(), i.InputOffset());
|
| DCHECK_EQ(LeaveCC, i.OutputSBit());
|
| break;
|
| }
|
| case kArmVstrF32:
|
| - __ vstr(i.InputFloatRegister(0), i.InputOffset(1));
|
| + __ vstr(i.InputFloat32Register(0), i.InputOffset(1));
|
| DCHECK_EQ(LeaveCC, i.OutputSBit());
|
| break;
|
| case kArmVldrF64:
|
| @@ -1453,7 +1464,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
|
| frame_access_state()->IncreaseSPDelta(kDoubleSize / kPointerSize);
|
| } else {
|
| DCHECK_EQ(MachineRepresentation::kFloat32, op->representation());
|
| - __ vpush(i.InputFloatRegister(0));
|
| + __ vpush(i.InputFloat32Register(0));
|
| frame_access_state()->IncreaseSPDelta(1);
|
| }
|
| } else {
|
| @@ -1484,7 +1495,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
|
| ASSEMBLE_CHECKED_LOAD_INTEGER(ldr);
|
| break;
|
| case kCheckedLoadFloat32:
|
| - ASSEMBLE_CHECKED_LOAD_FP(Float);
|
| + ASSEMBLE_CHECKED_LOAD_FP(Float32);
|
| break;
|
| case kCheckedLoadFloat64:
|
| ASSEMBLE_CHECKED_LOAD_FP(Double);
|
| @@ -1499,7 +1510,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
|
| ASSEMBLE_CHECKED_STORE_INTEGER(str);
|
| break;
|
| case kCheckedStoreFloat32:
|
| - ASSEMBLE_CHECKED_STORE_FP(Float);
|
| + ASSEMBLE_CHECKED_STORE_FP(Float32);
|
| break;
|
| case kCheckedStoreFloat64:
|
| ASSEMBLE_CHECKED_STORE_FP(Double);
|
| @@ -1817,7 +1828,7 @@ void CodeGenerator::AssembleMove(InstructionOperand* source,
|
| __ mov(ip, Operand(bit_cast<int32_t>(src.ToFloat32())));
|
| __ str(ip, dst);
|
| } else {
|
| - SwVfpRegister dst = g.ToFloatRegister(destination);
|
| + SwVfpRegister dst = g.ToFloat32Register(destination);
|
| __ vmov(dst, src.ToFloat32());
|
| }
|
| } else {
|
| @@ -1831,50 +1842,23 @@ void CodeGenerator::AssembleMove(InstructionOperand* source,
|
| }
|
| }
|
| } else if (source->IsFPRegister()) {
|
| - MachineRepresentation rep = LocationOperand::cast(source)->representation();
|
| - if (rep == MachineRepresentation::kFloat64) {
|
| - DwVfpRegister src = g.ToDoubleRegister(source);
|
| - if (destination->IsFPRegister()) {
|
| - DwVfpRegister dst = g.ToDoubleRegister(destination);
|
| - __ Move(dst, src);
|
| - } else {
|
| - DCHECK(destination->IsFPStackSlot());
|
| - __ vstr(src, g.ToMemOperand(destination));
|
| - }
|
| + DwVfpRegister src = g.ToDoubleRegister(source);
|
| + if (destination->IsFPRegister()) {
|
| + DwVfpRegister dst = g.ToDoubleRegister(destination);
|
| + __ Move(dst, src);
|
| } else {
|
| - DCHECK_EQ(MachineRepresentation::kFloat32, rep);
|
| - SwVfpRegister src = g.ToFloatRegister(source);
|
| - if (destination->IsFPRegister()) {
|
| - SwVfpRegister dst = g.ToFloatRegister(destination);
|
| - __ Move(dst, src);
|
| - } else {
|
| - DCHECK(destination->IsFPStackSlot());
|
| - __ vstr(src, g.ToMemOperand(destination));
|
| - }
|
| + DCHECK(destination->IsFPStackSlot());
|
| + __ vstr(src, g.ToMemOperand(destination));
|
| }
|
| } else if (source->IsFPStackSlot()) {
|
| MemOperand src = g.ToMemOperand(source);
|
| - MachineRepresentation rep =
|
| - LocationOperand::cast(destination)->representation();
|
| if (destination->IsFPRegister()) {
|
| - if (rep == MachineRepresentation::kFloat64) {
|
| __ vldr(g.ToDoubleRegister(destination), src);
|
| - } else {
|
| - DCHECK_EQ(MachineRepresentation::kFloat32, rep);
|
| - __ vldr(g.ToFloatRegister(destination), src);
|
| - }
|
| } else {
|
| DCHECK(destination->IsFPStackSlot());
|
| - if (rep == MachineRepresentation::kFloat64) {
|
| DwVfpRegister temp = kScratchDoubleReg;
|
| __ vldr(temp, src);
|
| __ vstr(temp, g.ToMemOperand(destination));
|
| - } else {
|
| - DCHECK_EQ(MachineRepresentation::kFloat32, rep);
|
| - SwVfpRegister temp = kScratchDoubleReg.low();
|
| - __ vldr(temp, src);
|
| - __ vstr(temp, g.ToMemOperand(destination));
|
| - }
|
| }
|
| } else {
|
| UNREACHABLE();
|
| @@ -1914,9 +1898,7 @@ void CodeGenerator::AssembleSwap(InstructionOperand* source,
|
| __ str(temp_0, dst);
|
| __ vstr(temp_1, src);
|
| } else if (source->IsFPRegister()) {
|
| - MachineRepresentation rep = LocationOperand::cast(source)->representation();
|
| LowDwVfpRegister temp = kScratchDoubleReg;
|
| - if (rep == MachineRepresentation::kFloat64) {
|
| DwVfpRegister src = g.ToDoubleRegister(source);
|
| if (destination->IsFPRegister()) {
|
| DwVfpRegister dst = g.ToDoubleRegister(destination);
|
| @@ -1930,30 +1912,12 @@ void CodeGenerator::AssembleSwap(InstructionOperand* source,
|
| __ vldr(src, dst);
|
| __ vstr(temp, dst);
|
| }
|
| - } else {
|
| - DCHECK_EQ(MachineRepresentation::kFloat32, rep);
|
| - SwVfpRegister src = g.ToFloatRegister(source);
|
| - if (destination->IsFPRegister()) {
|
| - SwVfpRegister dst = g.ToFloatRegister(destination);
|
| - __ Move(temp.low(), src);
|
| - __ Move(src, dst);
|
| - __ Move(dst, temp.low());
|
| - } else {
|
| - DCHECK(destination->IsFPStackSlot());
|
| - MemOperand dst = g.ToMemOperand(destination);
|
| - __ Move(temp.low(), src);
|
| - __ vldr(src, dst);
|
| - __ vstr(temp.low(), dst);
|
| - }
|
| - }
|
| } else if (source->IsFPStackSlot()) {
|
| DCHECK(destination->IsFPStackSlot());
|
| Register temp_0 = kScratchReg;
|
| LowDwVfpRegister temp_1 = kScratchDoubleReg;
|
| MemOperand src0 = g.ToMemOperand(source);
|
| MemOperand dst0 = g.ToMemOperand(destination);
|
| - MachineRepresentation rep = LocationOperand::cast(source)->representation();
|
| - if (rep == MachineRepresentation::kFloat64) {
|
| MemOperand src1(src0.rn(), src0.offset() + kPointerSize);
|
| MemOperand dst1(dst0.rn(), dst0.offset() + kPointerSize);
|
| __ vldr(temp_1, dst0); // Save destination in temp_1.
|
| @@ -1962,13 +1926,6 @@ void CodeGenerator::AssembleSwap(InstructionOperand* source,
|
| __ ldr(temp_0, src1);
|
| __ str(temp_0, dst1);
|
| __ vstr(temp_1, src0);
|
| - } else {
|
| - DCHECK_EQ(MachineRepresentation::kFloat32, rep);
|
| - __ vldr(temp_1.low(), dst0); // Save destination in temp_1.
|
| - __ ldr(temp_0, src0); // Then use temp_0 to copy source to destination.
|
| - __ str(temp_0, dst0);
|
| - __ vstr(temp_1.low(), src0);
|
| - }
|
| } else {
|
| // No other combinations are possible.
|
| UNREACHABLE();
|
|
|