OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/compiler/code-generator.h" | 5 #include "src/compiler/code-generator.h" |
6 | 6 |
7 #include "src/arm/macro-assembler-arm.h" | 7 #include "src/arm/macro-assembler-arm.h" |
8 #include "src/ast/scopes.h" | 8 #include "src/ast/scopes.h" |
9 #include "src/compiler/code-generator-impl.h" | 9 #include "src/compiler/code-generator-impl.h" |
10 #include "src/compiler/gap-resolver.h" | 10 #include "src/compiler/gap-resolver.h" |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
142 UNREACHABLE(); | 142 UNREACHABLE(); |
143 return MemOperand(r0); | 143 return MemOperand(r0); |
144 } | 144 } |
145 | 145 |
146 MemOperand InputOffset(size_t first_index = 0) { | 146 MemOperand InputOffset(size_t first_index = 0) { |
147 return InputOffset(&first_index); | 147 return InputOffset(&first_index); |
148 } | 148 } |
149 | 149 |
150 MemOperand ToMemOperand(InstructionOperand* op) const { | 150 MemOperand ToMemOperand(InstructionOperand* op) const { |
151 DCHECK_NOT_NULL(op); | 151 DCHECK_NOT_NULL(op); |
152 DCHECK(op->IsStackSlot() || op->IsDoubleStackSlot()); | 152 DCHECK(op->IsStackSlot() || op->IsFPStackSlot()); |
153 return SlotToMemOperand(AllocatedOperand::cast(op)->index()); | 153 return SlotToMemOperand(AllocatedOperand::cast(op)->index()); |
154 } | 154 } |
155 | 155 |
156 MemOperand SlotToMemOperand(int slot) const { | 156 MemOperand SlotToMemOperand(int slot) const { |
157 FrameOffset offset = frame_access_state()->GetFrameOffset(slot); | 157 FrameOffset offset = frame_access_state()->GetFrameOffset(slot); |
158 return MemOperand(offset.from_stack_pointer() ? sp : fp, offset.offset()); | 158 return MemOperand(offset.from_stack_pointer() ? sp : fp, offset.offset()); |
159 } | 159 } |
160 }; | 160 }; |
161 | 161 |
162 | 162 |
(...skipping 710 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
873 case kArmAsrPair: | 873 case kArmAsrPair: |
874 if (instr->InputAt(2)->IsImmediate()) { | 874 if (instr->InputAt(2)->IsImmediate()) { |
875 __ AsrPair(i.OutputRegister(0), i.OutputRegister(1), i.InputRegister(0), | 875 __ AsrPair(i.OutputRegister(0), i.OutputRegister(1), i.InputRegister(0), |
876 i.InputRegister(1), i.InputInt32(2)); | 876 i.InputRegister(1), i.InputInt32(2)); |
877 } else { | 877 } else { |
878 __ AsrPair(i.OutputRegister(0), i.OutputRegister(1), i.InputRegister(0), | 878 __ AsrPair(i.OutputRegister(0), i.OutputRegister(1), i.InputRegister(0), |
879 i.InputRegister(1), kScratchReg, i.InputRegister(2)); | 879 i.InputRegister(1), kScratchReg, i.InputRegister(2)); |
880 } | 880 } |
881 break; | 881 break; |
882 case kArmVcmpF32: | 882 case kArmVcmpF32: |
883 if (instr->InputAt(1)->IsDoubleRegister()) { | 883 if (instr->InputAt(1)->IsFPRegister()) { |
884 __ VFPCompareAndSetFlags(i.InputFloat32Register(0), | 884 __ VFPCompareAndSetFlags(i.InputFloat32Register(0), |
885 i.InputFloat32Register(1)); | 885 i.InputFloat32Register(1)); |
886 } else { | 886 } else { |
887 DCHECK(instr->InputAt(1)->IsImmediate()); | 887 DCHECK(instr->InputAt(1)->IsImmediate()); |
888 // 0.0 is the only immediate supported by vcmp instructions. | 888 // 0.0 is the only immediate supported by vcmp instructions. |
889 DCHECK(i.InputFloat32(1) == 0.0f); | 889 DCHECK(i.InputFloat32(1) == 0.0f); |
890 __ VFPCompareAndSetFlags(i.InputFloat32Register(0), i.InputFloat32(1)); | 890 __ VFPCompareAndSetFlags(i.InputFloat32Register(0), i.InputFloat32(1)); |
891 } | 891 } |
892 DCHECK_EQ(SetCC, i.OutputSBit()); | 892 DCHECK_EQ(SetCC, i.OutputSBit()); |
893 break; | 893 break; |
(...skipping 30 matching lines...) Expand all Loading... |
924 case kArmVsqrtF32: | 924 case kArmVsqrtF32: |
925 __ vsqrt(i.OutputFloat32Register(), i.InputFloat32Register(0)); | 925 __ vsqrt(i.OutputFloat32Register(), i.InputFloat32Register(0)); |
926 break; | 926 break; |
927 case kArmVabsF32: | 927 case kArmVabsF32: |
928 __ vabs(i.OutputFloat32Register(), i.InputFloat32Register(0)); | 928 __ vabs(i.OutputFloat32Register(), i.InputFloat32Register(0)); |
929 break; | 929 break; |
930 case kArmVnegF32: | 930 case kArmVnegF32: |
931 __ vneg(i.OutputFloat32Register(), i.InputFloat32Register(0)); | 931 __ vneg(i.OutputFloat32Register(), i.InputFloat32Register(0)); |
932 break; | 932 break; |
933 case kArmVcmpF64: | 933 case kArmVcmpF64: |
934 if (instr->InputAt(1)->IsDoubleRegister()) { | 934 if (instr->InputAt(1)->IsFPRegister()) { |
935 __ VFPCompareAndSetFlags(i.InputFloat64Register(0), | 935 __ VFPCompareAndSetFlags(i.InputFloat64Register(0), |
936 i.InputFloat64Register(1)); | 936 i.InputFloat64Register(1)); |
937 } else { | 937 } else { |
938 DCHECK(instr->InputAt(1)->IsImmediate()); | 938 DCHECK(instr->InputAt(1)->IsImmediate()); |
939 // 0.0 is the only immediate supported by vcmp instructions. | 939 // 0.0 is the only immediate supported by vcmp instructions. |
940 DCHECK(i.InputDouble(1) == 0.0); | 940 DCHECK(i.InputDouble(1) == 0.0); |
941 __ VFPCompareAndSetFlags(i.InputFloat64Register(0), i.InputDouble(1)); | 941 __ VFPCompareAndSetFlags(i.InputFloat64Register(0), i.InputDouble(1)); |
942 } | 942 } |
943 DCHECK_EQ(SetCC, i.OutputSBit()); | 943 DCHECK_EQ(SetCC, i.OutputSBit()); |
944 break; | 944 break; |
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1204 CpuFeatureScope scope(masm(), ARMv8); | 1204 CpuFeatureScope scope(masm(), ARMv8); |
1205 // (a < b) ? a : b | 1205 // (a < b) ? a : b |
1206 DwVfpRegister a = i.InputFloat64Register(0); | 1206 DwVfpRegister a = i.InputFloat64Register(0); |
1207 DwVfpRegister b = i.InputFloat64Register(1); | 1207 DwVfpRegister b = i.InputFloat64Register(1); |
1208 DwVfpRegister result = i.OutputFloat64Register(0); | 1208 DwVfpRegister result = i.OutputFloat64Register(0); |
1209 __ VFPCompareAndSetFlags(b, a); | 1209 __ VFPCompareAndSetFlags(b, a); |
1210 __ vsel(gt, result, a, b); | 1210 __ vsel(gt, result, a, b); |
1211 break; | 1211 break; |
1212 } | 1212 } |
1213 case kArmPush: | 1213 case kArmPush: |
1214 if (instr->InputAt(0)->IsDoubleRegister()) { | 1214 if (instr->InputAt(0)->IsFPRegister()) { |
1215 __ vpush(i.InputDoubleRegister(0)); | 1215 __ vpush(i.InputDoubleRegister(0)); |
1216 frame_access_state()->IncreaseSPDelta(kDoubleSize / kPointerSize); | 1216 frame_access_state()->IncreaseSPDelta(kDoubleSize / kPointerSize); |
1217 } else { | 1217 } else { |
1218 __ push(i.InputRegister(0)); | 1218 __ push(i.InputRegister(0)); |
1219 frame_access_state()->IncreaseSPDelta(1); | 1219 frame_access_state()->IncreaseSPDelta(1); |
1220 } | 1220 } |
1221 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 1221 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
1222 break; | 1222 break; |
1223 case kArmPoke: { | 1223 case kArmPoke: { |
1224 int const slot = MiscField::decode(instr->opcode()); | 1224 int const slot = MiscField::decode(instr->opcode()); |
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1553 __ Move(dst, src_object); | 1553 __ Move(dst, src_object); |
1554 } | 1554 } |
1555 break; | 1555 break; |
1556 } | 1556 } |
1557 case Constant::kRpoNumber: | 1557 case Constant::kRpoNumber: |
1558 UNREACHABLE(); // TODO(dcarney): loading RPO constants on arm. | 1558 UNREACHABLE(); // TODO(dcarney): loading RPO constants on arm. |
1559 break; | 1559 break; |
1560 } | 1560 } |
1561 if (destination->IsStackSlot()) __ str(dst, g.ToMemOperand(destination)); | 1561 if (destination->IsStackSlot()) __ str(dst, g.ToMemOperand(destination)); |
1562 } else if (src.type() == Constant::kFloat32) { | 1562 } else if (src.type() == Constant::kFloat32) { |
1563 if (destination->IsDoubleStackSlot()) { | 1563 if (destination->IsFPStackSlot()) { |
1564 MemOperand dst = g.ToMemOperand(destination); | 1564 MemOperand dst = g.ToMemOperand(destination); |
1565 __ mov(ip, Operand(bit_cast<int32_t>(src.ToFloat32()))); | 1565 __ mov(ip, Operand(bit_cast<int32_t>(src.ToFloat32()))); |
1566 __ str(ip, dst); | 1566 __ str(ip, dst); |
1567 } else { | 1567 } else { |
1568 SwVfpRegister dst = g.ToFloat32Register(destination); | 1568 SwVfpRegister dst = g.ToFloat32Register(destination); |
1569 __ vmov(dst, src.ToFloat32()); | 1569 __ vmov(dst, src.ToFloat32()); |
1570 } | 1570 } |
1571 } else { | 1571 } else { |
1572 DCHECK_EQ(Constant::kFloat64, src.type()); | 1572 DCHECK_EQ(Constant::kFloat64, src.type()); |
1573 DwVfpRegister dst = destination->IsDoubleRegister() | 1573 DwVfpRegister dst = destination->IsFPRegister() |
1574 ? g.ToFloat64Register(destination) | 1574 ? g.ToFloat64Register(destination) |
1575 : kScratchDoubleReg; | 1575 : kScratchDoubleReg; |
1576 __ vmov(dst, src.ToFloat64(), kScratchReg); | 1576 __ vmov(dst, src.ToFloat64(), kScratchReg); |
1577 if (destination->IsDoubleStackSlot()) { | 1577 if (destination->IsFPStackSlot()) { |
1578 __ vstr(dst, g.ToMemOperand(destination)); | 1578 __ vstr(dst, g.ToMemOperand(destination)); |
1579 } | 1579 } |
1580 } | 1580 } |
1581 } else if (source->IsDoubleRegister()) { | 1581 } else if (source->IsFPRegister()) { |
1582 DwVfpRegister src = g.ToDoubleRegister(source); | 1582 DwVfpRegister src = g.ToDoubleRegister(source); |
1583 if (destination->IsDoubleRegister()) { | 1583 if (destination->IsFPRegister()) { |
1584 DwVfpRegister dst = g.ToDoubleRegister(destination); | 1584 DwVfpRegister dst = g.ToDoubleRegister(destination); |
1585 __ Move(dst, src); | 1585 __ Move(dst, src); |
1586 } else { | 1586 } else { |
1587 DCHECK(destination->IsDoubleStackSlot()); | 1587 DCHECK(destination->IsFPStackSlot()); |
1588 __ vstr(src, g.ToMemOperand(destination)); | 1588 __ vstr(src, g.ToMemOperand(destination)); |
1589 } | 1589 } |
1590 } else if (source->IsDoubleStackSlot()) { | 1590 } else if (source->IsFPStackSlot()) { |
1591 DCHECK(destination->IsDoubleRegister() || destination->IsDoubleStackSlot()); | 1591 DCHECK(destination->IsFPRegister() || destination->IsFPStackSlot()); |
1592 MemOperand src = g.ToMemOperand(source); | 1592 MemOperand src = g.ToMemOperand(source); |
1593 if (destination->IsDoubleRegister()) { | 1593 if (destination->IsFPRegister()) { |
1594 __ vldr(g.ToDoubleRegister(destination), src); | 1594 __ vldr(g.ToDoubleRegister(destination), src); |
1595 } else { | 1595 } else { |
1596 DwVfpRegister temp = kScratchDoubleReg; | 1596 DwVfpRegister temp = kScratchDoubleReg; |
1597 __ vldr(temp, src); | 1597 __ vldr(temp, src); |
1598 __ vstr(temp, g.ToMemOperand(destination)); | 1598 __ vstr(temp, g.ToMemOperand(destination)); |
1599 } | 1599 } |
1600 } else { | 1600 } else { |
1601 UNREACHABLE(); | 1601 UNREACHABLE(); |
1602 } | 1602 } |
1603 } | 1603 } |
(...skipping 23 matching lines...) Expand all Loading... |
1627 } else if (source->IsStackSlot()) { | 1627 } else if (source->IsStackSlot()) { |
1628 DCHECK(destination->IsStackSlot()); | 1628 DCHECK(destination->IsStackSlot()); |
1629 Register temp_0 = kScratchReg; | 1629 Register temp_0 = kScratchReg; |
1630 SwVfpRegister temp_1 = kScratchDoubleReg.low(); | 1630 SwVfpRegister temp_1 = kScratchDoubleReg.low(); |
1631 MemOperand src = g.ToMemOperand(source); | 1631 MemOperand src = g.ToMemOperand(source); |
1632 MemOperand dst = g.ToMemOperand(destination); | 1632 MemOperand dst = g.ToMemOperand(destination); |
1633 __ ldr(temp_0, src); | 1633 __ ldr(temp_0, src); |
1634 __ vldr(temp_1, dst); | 1634 __ vldr(temp_1, dst); |
1635 __ str(temp_0, dst); | 1635 __ str(temp_0, dst); |
1636 __ vstr(temp_1, src); | 1636 __ vstr(temp_1, src); |
1637 } else if (source->IsDoubleRegister()) { | 1637 } else if (source->IsFPRegister()) { |
1638 DwVfpRegister temp = kScratchDoubleReg; | 1638 DwVfpRegister temp = kScratchDoubleReg; |
1639 DwVfpRegister src = g.ToDoubleRegister(source); | 1639 DwVfpRegister src = g.ToDoubleRegister(source); |
1640 if (destination->IsDoubleRegister()) { | 1640 if (destination->IsFPRegister()) { |
1641 DwVfpRegister dst = g.ToDoubleRegister(destination); | 1641 DwVfpRegister dst = g.ToDoubleRegister(destination); |
1642 __ Move(temp, src); | 1642 __ Move(temp, src); |
1643 __ Move(src, dst); | 1643 __ Move(src, dst); |
1644 __ Move(dst, temp); | 1644 __ Move(dst, temp); |
1645 } else { | 1645 } else { |
1646 DCHECK(destination->IsDoubleStackSlot()); | 1646 DCHECK(destination->IsFPStackSlot()); |
1647 MemOperand dst = g.ToMemOperand(destination); | 1647 MemOperand dst = g.ToMemOperand(destination); |
1648 __ Move(temp, src); | 1648 __ Move(temp, src); |
1649 __ vldr(src, dst); | 1649 __ vldr(src, dst); |
1650 __ vstr(temp, dst); | 1650 __ vstr(temp, dst); |
1651 } | 1651 } |
1652 } else if (source->IsDoubleStackSlot()) { | 1652 } else if (source->IsFPStackSlot()) { |
1653 DCHECK(destination->IsDoubleStackSlot()); | 1653 DCHECK(destination->IsFPStackSlot()); |
1654 Register temp_0 = kScratchReg; | 1654 Register temp_0 = kScratchReg; |
1655 DwVfpRegister temp_1 = kScratchDoubleReg; | 1655 DwVfpRegister temp_1 = kScratchDoubleReg; |
1656 MemOperand src0 = g.ToMemOperand(source); | 1656 MemOperand src0 = g.ToMemOperand(source); |
1657 MemOperand src1(src0.rn(), src0.offset() + kPointerSize); | 1657 MemOperand src1(src0.rn(), src0.offset() + kPointerSize); |
1658 MemOperand dst0 = g.ToMemOperand(destination); | 1658 MemOperand dst0 = g.ToMemOperand(destination); |
1659 MemOperand dst1(dst0.rn(), dst0.offset() + kPointerSize); | 1659 MemOperand dst1(dst0.rn(), dst0.offset() + kPointerSize); |
1660 __ vldr(temp_1, dst0); // Save destination in temp_1. | 1660 __ vldr(temp_1, dst0); // Save destination in temp_1. |
1661 __ ldr(temp_0, src0); // Then use temp_0 to copy source to destination. | 1661 __ ldr(temp_0, src0); // Then use temp_0 to copy source to destination. |
1662 __ str(temp_0, dst0); | 1662 __ str(temp_0, dst0); |
1663 __ ldr(temp_0, src1); | 1663 __ ldr(temp_0, src1); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1695 padding_size -= v8::internal::Assembler::kInstrSize; | 1695 padding_size -= v8::internal::Assembler::kInstrSize; |
1696 } | 1696 } |
1697 } | 1697 } |
1698 } | 1698 } |
1699 | 1699 |
1700 #undef __ | 1700 #undef __ |
1701 | 1701 |
1702 } // namespace compiler | 1702 } // namespace compiler |
1703 } // namespace internal | 1703 } // namespace internal |
1704 } // namespace v8 | 1704 } // namespace v8 |
OLD | NEW |