| 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/arm64/frames-arm64.h" | 7 #include "src/arm64/frames-arm64.h" |
| 8 #include "src/arm64/macro-assembler-arm64.h" | 8 #include "src/arm64/macro-assembler-arm64.h" |
| 9 #include "src/ast/scopes.h" | 9 #include "src/ast/scopes.h" |
| 10 #include "src/compiler/code-generator-impl.h" | 10 #include "src/compiler/code-generator-impl.h" |
| (...skipping 20 matching lines...) Expand all Loading... |
| 31 | 31 |
| 32 DoubleRegister InputFloat64Register(size_t index) { | 32 DoubleRegister InputFloat64Register(size_t index) { |
| 33 return InputDoubleRegister(index); | 33 return InputDoubleRegister(index); |
| 34 } | 34 } |
| 35 | 35 |
| 36 CPURegister InputFloat32OrZeroRegister(size_t index) { | 36 CPURegister InputFloat32OrZeroRegister(size_t index) { |
| 37 if (instr_->InputAt(index)->IsImmediate()) { | 37 if (instr_->InputAt(index)->IsImmediate()) { |
| 38 DCHECK(bit_cast<int32_t>(InputFloat32(index)) == 0); | 38 DCHECK(bit_cast<int32_t>(InputFloat32(index)) == 0); |
| 39 return wzr; | 39 return wzr; |
| 40 } | 40 } |
| 41 DCHECK(instr_->InputAt(index)->IsDoubleRegister()); | 41 DCHECK(instr_->InputAt(index)->IsFPRegister()); |
| 42 return InputDoubleRegister(index).S(); | 42 return InputDoubleRegister(index).S(); |
| 43 } | 43 } |
| 44 | 44 |
| 45 CPURegister InputFloat64OrZeroRegister(size_t index) { | 45 CPURegister InputFloat64OrZeroRegister(size_t index) { |
| 46 if (instr_->InputAt(index)->IsImmediate()) { | 46 if (instr_->InputAt(index)->IsImmediate()) { |
| 47 DCHECK(bit_cast<int64_t>(InputDouble(index)) == 0); | 47 DCHECK(bit_cast<int64_t>(InputDouble(index)) == 0); |
| 48 return xzr; | 48 return xzr; |
| 49 } | 49 } |
| 50 DCHECK(instr_->InputAt(index)->IsDoubleRegister()); | 50 DCHECK(instr_->InputAt(index)->IsDoubleRegister()); |
| 51 return InputDoubleRegister(index); | 51 return InputDoubleRegister(index); |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 226 case Constant::kRpoNumber: | 226 case Constant::kRpoNumber: |
| 227 UNREACHABLE(); // TODO(dcarney): RPO immediates on arm64. | 227 UNREACHABLE(); // TODO(dcarney): RPO immediates on arm64. |
| 228 break; | 228 break; |
| 229 } | 229 } |
| 230 UNREACHABLE(); | 230 UNREACHABLE(); |
| 231 return Operand(-1); | 231 return Operand(-1); |
| 232 } | 232 } |
| 233 | 233 |
| 234 MemOperand ToMemOperand(InstructionOperand* op, MacroAssembler* masm) const { | 234 MemOperand ToMemOperand(InstructionOperand* op, MacroAssembler* masm) const { |
| 235 DCHECK_NOT_NULL(op); | 235 DCHECK_NOT_NULL(op); |
| 236 DCHECK(op->IsStackSlot() || op->IsDoubleStackSlot()); | 236 DCHECK(op->IsStackSlot() || op->IsFPStackSlot()); |
| 237 return SlotToMemOperand(AllocatedOperand::cast(op)->index(), masm); | 237 return SlotToMemOperand(AllocatedOperand::cast(op)->index(), masm); |
| 238 } | 238 } |
| 239 | 239 |
| 240 MemOperand SlotToMemOperand(int slot, MacroAssembler* masm) const { | 240 MemOperand SlotToMemOperand(int slot, MacroAssembler* masm) const { |
| 241 FrameOffset offset = frame_access_state()->GetFrameOffset(slot); | 241 FrameOffset offset = frame_access_state()->GetFrameOffset(slot); |
| 242 if (offset.from_frame_pointer()) { | 242 if (offset.from_frame_pointer()) { |
| 243 int from_sp = offset.offset() + frame_access_state()->GetSPToFPOffset(); | 243 int from_sp = offset.offset() + frame_access_state()->GetSPToFPOffset(); |
| 244 // Convert FP-offsets to SP-offsets if it results in better code. | 244 // Convert FP-offsets to SP-offsets if it results in better code. |
| 245 if (Assembler::IsImmLSUnscaled(from_sp) || | 245 if (Assembler::IsImmLSUnscaled(from_sp) || |
| 246 Assembler::IsImmLSScaled(from_sp, LSDoubleWord)) { | 246 Assembler::IsImmLSScaled(from_sp, LSDoubleWord)) { |
| (...skipping 833 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1080 __ Claim(count); | 1080 __ Claim(count); |
| 1081 frame_access_state()->IncreaseSPDelta(count); | 1081 frame_access_state()->IncreaseSPDelta(count); |
| 1082 } | 1082 } |
| 1083 break; | 1083 break; |
| 1084 } | 1084 } |
| 1085 case kArm64PokeCSP: // fall through | 1085 case kArm64PokeCSP: // fall through |
| 1086 case kArm64PokeJSSP: { | 1086 case kArm64PokeJSSP: { |
| 1087 Register prev = __ StackPointer(); | 1087 Register prev = __ StackPointer(); |
| 1088 __ SetStackPointer(arch_opcode == kArm64PokeCSP ? csp : jssp); | 1088 __ SetStackPointer(arch_opcode == kArm64PokeCSP ? csp : jssp); |
| 1089 Operand operand(i.InputInt32(1) * kPointerSize); | 1089 Operand operand(i.InputInt32(1) * kPointerSize); |
| 1090 if (instr->InputAt(0)->IsDoubleRegister()) { | 1090 if (instr->InputAt(0)->IsFPRegister()) { |
| 1091 __ Poke(i.InputFloat64Register(0), operand); | 1091 __ Poke(i.InputFloat64Register(0), operand); |
| 1092 } else { | 1092 } else { |
| 1093 __ Poke(i.InputRegister(0), operand); | 1093 __ Poke(i.InputRegister(0), operand); |
| 1094 } | 1094 } |
| 1095 __ SetStackPointer(prev); | 1095 __ SetStackPointer(prev); |
| 1096 break; | 1096 break; |
| 1097 } | 1097 } |
| 1098 case kArm64PokePair: { | 1098 case kArm64PokePair: { |
| 1099 int slot = i.InputInt32(2) - 1; | 1099 int slot = i.InputInt32(2) - 1; |
| 1100 if (instr->InputAt(0)->IsDoubleRegister()) { | 1100 if (instr->InputAt(0)->IsFPRegister()) { |
| 1101 __ PokePair(i.InputFloat64Register(1), i.InputFloat64Register(0), | 1101 __ PokePair(i.InputFloat64Register(1), i.InputFloat64Register(0), |
| 1102 slot * kPointerSize); | 1102 slot * kPointerSize); |
| 1103 } else { | 1103 } else { |
| 1104 __ PokePair(i.InputRegister(1), i.InputRegister(0), | 1104 __ PokePair(i.InputRegister(1), i.InputRegister(0), |
| 1105 slot * kPointerSize); | 1105 slot * kPointerSize); |
| 1106 } | 1106 } |
| 1107 break; | 1107 break; |
| 1108 } | 1108 } |
| 1109 case kArm64Clz: | 1109 case kArm64Clz: |
| 1110 __ Clz(i.OutputRegister64(), i.InputRegister64(0)); | 1110 __ Clz(i.OutputRegister64(), i.InputRegister64(0)); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1130 case kArm64Cmn32: | 1130 case kArm64Cmn32: |
| 1131 __ Cmn(i.InputOrZeroRegister32(0), i.InputOperand2_32(1)); | 1131 __ Cmn(i.InputOrZeroRegister32(0), i.InputOperand2_32(1)); |
| 1132 break; | 1132 break; |
| 1133 case kArm64Tst: | 1133 case kArm64Tst: |
| 1134 __ Tst(i.InputRegister(0), i.InputOperand(1)); | 1134 __ Tst(i.InputRegister(0), i.InputOperand(1)); |
| 1135 break; | 1135 break; |
| 1136 case kArm64Tst32: | 1136 case kArm64Tst32: |
| 1137 __ Tst(i.InputRegister32(0), i.InputOperand32(1)); | 1137 __ Tst(i.InputRegister32(0), i.InputOperand32(1)); |
| 1138 break; | 1138 break; |
| 1139 case kArm64Float32Cmp: | 1139 case kArm64Float32Cmp: |
| 1140 if (instr->InputAt(1)->IsDoubleRegister()) { | 1140 if (instr->InputAt(1)->IsFPRegister()) { |
| 1141 __ Fcmp(i.InputFloat32Register(0), i.InputFloat32Register(1)); | 1141 __ Fcmp(i.InputFloat32Register(0), i.InputFloat32Register(1)); |
| 1142 } else { | 1142 } else { |
| 1143 DCHECK(instr->InputAt(1)->IsImmediate()); | 1143 DCHECK(instr->InputAt(1)->IsImmediate()); |
| 1144 // 0.0 is the only immediate supported by fcmp instructions. | 1144 // 0.0 is the only immediate supported by fcmp instructions. |
| 1145 DCHECK(i.InputFloat32(1) == 0.0f); | 1145 DCHECK(i.InputFloat32(1) == 0.0f); |
| 1146 __ Fcmp(i.InputFloat32Register(0), i.InputFloat32(1)); | 1146 __ Fcmp(i.InputFloat32Register(0), i.InputFloat32(1)); |
| 1147 } | 1147 } |
| 1148 break; | 1148 break; |
| 1149 case kArm64Float32Add: | 1149 case kArm64Float32Add: |
| 1150 __ Fadd(i.OutputFloat32Register(), i.InputFloat32Register(0), | 1150 __ Fadd(i.OutputFloat32Register(), i.InputFloat32Register(0), |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1174 __ Fcsel(i.OutputFloat32Register(), i.InputFloat32Register(0), | 1174 __ Fcsel(i.OutputFloat32Register(), i.InputFloat32Register(0), |
| 1175 i.InputFloat32Register(1), lo); | 1175 i.InputFloat32Register(1), lo); |
| 1176 break; | 1176 break; |
| 1177 case kArm64Float32Abs: | 1177 case kArm64Float32Abs: |
| 1178 __ Fabs(i.OutputFloat32Register(), i.InputFloat32Register(0)); | 1178 __ Fabs(i.OutputFloat32Register(), i.InputFloat32Register(0)); |
| 1179 break; | 1179 break; |
| 1180 case kArm64Float32Sqrt: | 1180 case kArm64Float32Sqrt: |
| 1181 __ Fsqrt(i.OutputFloat32Register(), i.InputFloat32Register(0)); | 1181 __ Fsqrt(i.OutputFloat32Register(), i.InputFloat32Register(0)); |
| 1182 break; | 1182 break; |
| 1183 case kArm64Float64Cmp: | 1183 case kArm64Float64Cmp: |
| 1184 if (instr->InputAt(1)->IsDoubleRegister()) { | 1184 if (instr->InputAt(1)->IsFPRegister()) { |
| 1185 __ Fcmp(i.InputDoubleRegister(0), i.InputDoubleRegister(1)); | 1185 __ Fcmp(i.InputDoubleRegister(0), i.InputDoubleRegister(1)); |
| 1186 } else { | 1186 } else { |
| 1187 DCHECK(instr->InputAt(1)->IsImmediate()); | 1187 DCHECK(instr->InputAt(1)->IsImmediate()); |
| 1188 // 0.0 is the only immediate supported by fcmp instructions. | 1188 // 0.0 is the only immediate supported by fcmp instructions. |
| 1189 DCHECK(i.InputDouble(1) == 0.0); | 1189 DCHECK(i.InputDouble(1) == 0.0); |
| 1190 __ Fcmp(i.InputDoubleRegister(0), i.InputDouble(1)); | 1190 __ Fcmp(i.InputDoubleRegister(0), i.InputDouble(1)); |
| 1191 } | 1191 } |
| 1192 break; | 1192 break; |
| 1193 case kArm64Float64Add: | 1193 case kArm64Float64Add: |
| 1194 __ Fadd(i.OutputDoubleRegister(), i.InputDoubleRegister(0), | 1194 __ Fadd(i.OutputDoubleRegister(), i.InputDoubleRegister(0), |
| (...skipping 563 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1758 } else { | 1758 } else { |
| 1759 __ LoadObject(dst, src_object); | 1759 __ LoadObject(dst, src_object); |
| 1760 } | 1760 } |
| 1761 } else { | 1761 } else { |
| 1762 __ Mov(dst, g.ToImmediate(source)); | 1762 __ Mov(dst, g.ToImmediate(source)); |
| 1763 } | 1763 } |
| 1764 if (destination->IsStackSlot()) { | 1764 if (destination->IsStackSlot()) { |
| 1765 __ Str(dst, g.ToMemOperand(destination, masm())); | 1765 __ Str(dst, g.ToMemOperand(destination, masm())); |
| 1766 } | 1766 } |
| 1767 } else if (src.type() == Constant::kFloat32) { | 1767 } else if (src.type() == Constant::kFloat32) { |
| 1768 if (destination->IsDoubleRegister()) { | 1768 if (destination->IsFPRegister()) { |
| 1769 FPRegister dst = g.ToDoubleRegister(destination).S(); | 1769 FPRegister dst = g.ToDoubleRegister(destination).S(); |
| 1770 __ Fmov(dst, src.ToFloat32()); | 1770 __ Fmov(dst, src.ToFloat32()); |
| 1771 } else { | 1771 } else { |
| 1772 DCHECK(destination->IsDoubleStackSlot()); | 1772 DCHECK(destination->IsFPStackSlot()); |
| 1773 UseScratchRegisterScope scope(masm()); | 1773 UseScratchRegisterScope scope(masm()); |
| 1774 FPRegister temp = scope.AcquireS(); | 1774 FPRegister temp = scope.AcquireS(); |
| 1775 __ Fmov(temp, src.ToFloat32()); | 1775 __ Fmov(temp, src.ToFloat32()); |
| 1776 __ Str(temp, g.ToMemOperand(destination, masm())); | 1776 __ Str(temp, g.ToMemOperand(destination, masm())); |
| 1777 } | 1777 } |
| 1778 } else { | 1778 } else { |
| 1779 DCHECK_EQ(Constant::kFloat64, src.type()); | 1779 DCHECK_EQ(Constant::kFloat64, src.type()); |
| 1780 if (destination->IsDoubleRegister()) { | 1780 if (destination->IsFPRegister()) { |
| 1781 FPRegister dst = g.ToDoubleRegister(destination); | 1781 FPRegister dst = g.ToDoubleRegister(destination); |
| 1782 __ Fmov(dst, src.ToFloat64()); | 1782 __ Fmov(dst, src.ToFloat64()); |
| 1783 } else { | 1783 } else { |
| 1784 DCHECK(destination->IsDoubleStackSlot()); | 1784 DCHECK(destination->IsFPStackSlot()); |
| 1785 UseScratchRegisterScope scope(masm()); | 1785 UseScratchRegisterScope scope(masm()); |
| 1786 FPRegister temp = scope.AcquireD(); | 1786 FPRegister temp = scope.AcquireD(); |
| 1787 __ Fmov(temp, src.ToFloat64()); | 1787 __ Fmov(temp, src.ToFloat64()); |
| 1788 __ Str(temp, g.ToMemOperand(destination, masm())); | 1788 __ Str(temp, g.ToMemOperand(destination, masm())); |
| 1789 } | 1789 } |
| 1790 } | 1790 } |
| 1791 } else if (source->IsDoubleRegister()) { | 1791 } else if (source->IsFPRegister()) { |
| 1792 FPRegister src = g.ToDoubleRegister(source); | 1792 FPRegister src = g.ToDoubleRegister(source); |
| 1793 if (destination->IsDoubleRegister()) { | 1793 if (destination->IsFPRegister()) { |
| 1794 FPRegister dst = g.ToDoubleRegister(destination); | 1794 FPRegister dst = g.ToDoubleRegister(destination); |
| 1795 __ Fmov(dst, src); | 1795 __ Fmov(dst, src); |
| 1796 } else { | 1796 } else { |
| 1797 DCHECK(destination->IsDoubleStackSlot()); | 1797 DCHECK(destination->IsFPStackSlot()); |
| 1798 __ Str(src, g.ToMemOperand(destination, masm())); | 1798 __ Str(src, g.ToMemOperand(destination, masm())); |
| 1799 } | 1799 } |
| 1800 } else if (source->IsDoubleStackSlot()) { | 1800 } else if (source->IsFPStackSlot()) { |
| 1801 DCHECK(destination->IsDoubleRegister() || destination->IsDoubleStackSlot()); | 1801 DCHECK(destination->IsFPRegister() || destination->IsFPStackSlot()); |
| 1802 MemOperand src = g.ToMemOperand(source, masm()); | 1802 MemOperand src = g.ToMemOperand(source, masm()); |
| 1803 if (destination->IsDoubleRegister()) { | 1803 if (destination->IsFPRegister()) { |
| 1804 __ Ldr(g.ToDoubleRegister(destination), src); | 1804 __ Ldr(g.ToDoubleRegister(destination), src); |
| 1805 } else { | 1805 } else { |
| 1806 UseScratchRegisterScope scope(masm()); | 1806 UseScratchRegisterScope scope(masm()); |
| 1807 FPRegister temp = scope.AcquireD(); | 1807 FPRegister temp = scope.AcquireD(); |
| 1808 __ Ldr(temp, src); | 1808 __ Ldr(temp, src); |
| 1809 __ Str(temp, g.ToMemOperand(destination, masm())); | 1809 __ Str(temp, g.ToMemOperand(destination, masm())); |
| 1810 } | 1810 } |
| 1811 } else { | 1811 } else { |
| 1812 UNREACHABLE(); | 1812 UNREACHABLE(); |
| 1813 } | 1813 } |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1829 __ Mov(temp, src); | 1829 __ Mov(temp, src); |
| 1830 __ Mov(src, dst); | 1830 __ Mov(src, dst); |
| 1831 __ Mov(dst, temp); | 1831 __ Mov(dst, temp); |
| 1832 } else { | 1832 } else { |
| 1833 DCHECK(destination->IsStackSlot()); | 1833 DCHECK(destination->IsStackSlot()); |
| 1834 MemOperand dst = g.ToMemOperand(destination, masm()); | 1834 MemOperand dst = g.ToMemOperand(destination, masm()); |
| 1835 __ Mov(temp, src); | 1835 __ Mov(temp, src); |
| 1836 __ Ldr(src, dst); | 1836 __ Ldr(src, dst); |
| 1837 __ Str(temp, dst); | 1837 __ Str(temp, dst); |
| 1838 } | 1838 } |
| 1839 } else if (source->IsStackSlot() || source->IsDoubleStackSlot()) { | 1839 } else if (source->IsStackSlot() || source->IsFPStackSlot()) { |
| 1840 UseScratchRegisterScope scope(masm()); | 1840 UseScratchRegisterScope scope(masm()); |
| 1841 DoubleRegister temp_0 = scope.AcquireD(); | 1841 DoubleRegister temp_0 = scope.AcquireD(); |
| 1842 DoubleRegister temp_1 = scope.AcquireD(); | 1842 DoubleRegister temp_1 = scope.AcquireD(); |
| 1843 MemOperand src = g.ToMemOperand(source, masm()); | 1843 MemOperand src = g.ToMemOperand(source, masm()); |
| 1844 MemOperand dst = g.ToMemOperand(destination, masm()); | 1844 MemOperand dst = g.ToMemOperand(destination, masm()); |
| 1845 __ Ldr(temp_0, src); | 1845 __ Ldr(temp_0, src); |
| 1846 __ Ldr(temp_1, dst); | 1846 __ Ldr(temp_1, dst); |
| 1847 __ Str(temp_0, dst); | 1847 __ Str(temp_0, dst); |
| 1848 __ Str(temp_1, src); | 1848 __ Str(temp_1, src); |
| 1849 } else if (source->IsDoubleRegister()) { | 1849 } else if (source->IsFPRegister()) { |
| 1850 UseScratchRegisterScope scope(masm()); | 1850 UseScratchRegisterScope scope(masm()); |
| 1851 FPRegister temp = scope.AcquireD(); | 1851 FPRegister temp = scope.AcquireD(); |
| 1852 FPRegister src = g.ToDoubleRegister(source); | 1852 FPRegister src = g.ToDoubleRegister(source); |
| 1853 if (destination->IsDoubleRegister()) { | 1853 if (destination->IsFPRegister()) { |
| 1854 FPRegister dst = g.ToDoubleRegister(destination); | 1854 FPRegister dst = g.ToDoubleRegister(destination); |
| 1855 __ Fmov(temp, src); | 1855 __ Fmov(temp, src); |
| 1856 __ Fmov(src, dst); | 1856 __ Fmov(src, dst); |
| 1857 __ Fmov(dst, temp); | 1857 __ Fmov(dst, temp); |
| 1858 } else { | 1858 } else { |
| 1859 DCHECK(destination->IsDoubleStackSlot()); | 1859 DCHECK(destination->IsFPStackSlot()); |
| 1860 MemOperand dst = g.ToMemOperand(destination, masm()); | 1860 MemOperand dst = g.ToMemOperand(destination, masm()); |
| 1861 __ Fmov(temp, src); | 1861 __ Fmov(temp, src); |
| 1862 __ Ldr(src, dst); | 1862 __ Ldr(src, dst); |
| 1863 __ Str(temp, dst); | 1863 __ Str(temp, dst); |
| 1864 } | 1864 } |
| 1865 } else { | 1865 } else { |
| 1866 // No other combinations are possible. | 1866 // No other combinations are possible. |
| 1867 UNREACHABLE(); | 1867 UNREACHABLE(); |
| 1868 } | 1868 } |
| 1869 } | 1869 } |
| (...skipping 26 matching lines...) Expand all Loading... |
| 1896 padding_size -= kInstructionSize; | 1896 padding_size -= kInstructionSize; |
| 1897 } | 1897 } |
| 1898 } | 1898 } |
| 1899 } | 1899 } |
| 1900 | 1900 |
| 1901 #undef __ | 1901 #undef __ |
| 1902 | 1902 |
| 1903 } // namespace compiler | 1903 } // namespace compiler |
| 1904 } // namespace internal | 1904 } // namespace internal |
| 1905 } // namespace v8 | 1905 } // namespace v8 |
| OLD | NEW |