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 |