OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 <limits> | 7 #include <limits> |
8 | 8 |
9 #include "src/compilation-info.h" | 9 #include "src/compilation-info.h" |
10 #include "src/compiler/code-generator-impl.h" | 10 #include "src/compiler/code-generator-impl.h" |
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
263 Operand const operand_; | 263 Operand const operand_; |
264 Register const value_; | 264 Register const value_; |
265 Register const scratch0_; | 265 Register const scratch0_; |
266 Register const scratch1_; | 266 Register const scratch1_; |
267 RecordWriteMode const mode_; | 267 RecordWriteMode const mode_; |
268 }; | 268 }; |
269 | 269 |
270 class WasmOutOfLineTrap final : public OutOfLineCode { | 270 class WasmOutOfLineTrap final : public OutOfLineCode { |
271 public: | 271 public: |
272 WasmOutOfLineTrap(CodeGenerator* gen, int pc, bool frame_elided, | 272 WasmOutOfLineTrap(CodeGenerator* gen, int pc, bool frame_elided, |
273 int32_t position, Instruction* instr) | 273 int32_t position) |
274 : OutOfLineCode(gen), | 274 : OutOfLineCode(gen), |
275 gen_(gen), | 275 gen_(gen), |
276 pc_(pc), | 276 pc_(pc), |
277 frame_elided_(frame_elided), | 277 frame_elided_(frame_elided), |
278 position_(position), | 278 position_(position) {} |
279 instr_(instr) {} | |
280 | 279 |
281 // TODO(eholk): Refactor this method to take the code generator as a | 280 // TODO(eholk): Refactor this method to take the code generator as a |
282 // parameter. | 281 // parameter. |
283 void Generate() final { | 282 void Generate() final { |
284 __ RecordProtectedInstructionLanding(pc_); | 283 __ RecordProtectedInstructionLanding(pc_); |
285 | 284 |
286 if (frame_elided_) { | 285 if (frame_elided_) { |
287 __ EnterFrame(StackFrame::WASM_COMPILED); | 286 __ EnterFrame(StackFrame::WASM_COMPILED); |
288 } | 287 } |
289 | 288 |
290 wasm::TrapReason trap_id = wasm::kTrapMemOutOfBounds; | 289 wasm::TrapReason trap_id = wasm::kTrapMemOutOfBounds; |
291 int trap_reason = wasm::WasmOpcodes::TrapReasonToMessageId(trap_id); | 290 int trap_reason = wasm::WasmOpcodes::TrapReasonToMessageId(trap_id); |
292 __ Push(Smi::FromInt(trap_reason)); | 291 __ Push(Smi::FromInt(trap_reason)); |
| 292 // TODO(eholk): use AssembleSourcePosition instead of passing in position_ |
| 293 // as a parameter. See AssembleArchTrap as an example. Consider sharing code |
| 294 // with AssembleArchTrap. |
293 __ Push(Smi::FromInt(position_)); | 295 __ Push(Smi::FromInt(position_)); |
294 __ Move(rsi, gen_->isolate()->native_context()); | 296 __ Move(rsi, Smi::kZero); |
295 __ CallRuntime(Runtime::kThrowWasmError); | 297 __ CallRuntime(Runtime::kThrowWasmError); |
296 | 298 |
297 if (instr_->reference_map() != nullptr) { | 299 ReferenceMap* reference_map = |
298 gen_->RecordSafepoint(instr_->reference_map(), Safepoint::kSimple, 0, | 300 new (gen_->code()->zone()) ReferenceMap(gen_->code()->zone()); |
299 Safepoint::kNoLazyDeopt); | 301 gen_->RecordSafepoint(reference_map, Safepoint::kSimple, 0, |
300 } | 302 Safepoint::kNoLazyDeopt); |
301 } | 303 } |
302 | 304 |
303 private: | 305 private: |
304 CodeGenerator* gen_; | 306 CodeGenerator* gen_; |
305 int pc_; | 307 int pc_; |
306 bool frame_elided_; | 308 bool frame_elided_; |
307 int32_t position_; | 309 int32_t position_; |
308 Instruction* instr_; | |
309 }; | 310 }; |
310 | 311 |
311 void EmitOOLTrapIfNeeded(Zone* zone, CodeGenerator* codegen, | 312 void EmitOOLTrapIfNeeded(Zone* zone, CodeGenerator* codegen, |
312 InstructionCode opcode, size_t input_count, | 313 InstructionCode opcode, size_t input_count, |
313 X64OperandConverter& i, int pc, Instruction* instr) { | 314 X64OperandConverter& i, int pc) { |
314 const X64MemoryProtection protection = | 315 const X64MemoryProtection protection = |
315 static_cast<X64MemoryProtection>(MiscField::decode(opcode)); | 316 static_cast<X64MemoryProtection>(MiscField::decode(opcode)); |
316 if (protection == X64MemoryProtection::kProtected) { | 317 if (protection == X64MemoryProtection::kProtected) { |
317 const bool frame_elided = !codegen->frame_access_state()->has_frame(); | 318 const bool frame_elided = !codegen->frame_access_state()->has_frame(); |
318 const int32_t position = i.InputInt32(input_count - 1); | 319 const int32_t position = i.InputInt32(input_count - 1); |
319 new (zone) WasmOutOfLineTrap(codegen, pc, frame_elided, position, instr); | 320 new (zone) WasmOutOfLineTrap(codegen, pc, frame_elided, position); |
320 } | 321 } |
321 } | 322 } |
322 } // namespace | 323 } // namespace |
323 | 324 |
324 | 325 |
325 #define ASSEMBLE_UNOP(asm_instr) \ | 326 #define ASSEMBLE_UNOP(asm_instr) \ |
326 do { \ | 327 do { \ |
327 if (instr->Output()->IsRegister()) { \ | 328 if (instr->Output()->IsRegister()) { \ |
328 __ asm_instr(i.OutputRegister()); \ | 329 __ asm_instr(i.OutputRegister()); \ |
329 } else { \ | 330 } else { \ |
(...skipping 1522 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1852 i.InputOperand(0)); | 1853 i.InputOperand(0)); |
1853 } | 1854 } |
1854 break; | 1855 break; |
1855 } | 1856 } |
1856 case kSSEFloat64SilenceNaN: | 1857 case kSSEFloat64SilenceNaN: |
1857 __ Xorpd(kScratchDoubleReg, kScratchDoubleReg); | 1858 __ Xorpd(kScratchDoubleReg, kScratchDoubleReg); |
1858 __ Subsd(i.InputDoubleRegister(0), kScratchDoubleReg); | 1859 __ Subsd(i.InputDoubleRegister(0), kScratchDoubleReg); |
1859 break; | 1860 break; |
1860 case kX64Movsxbl: | 1861 case kX64Movsxbl: |
1861 EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, | 1862 EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, |
1862 __ pc_offset(), instr); | 1863 __ pc_offset()); |
1863 ASSEMBLE_MOVX(movsxbl); | 1864 ASSEMBLE_MOVX(movsxbl); |
1864 __ AssertZeroExtended(i.OutputRegister()); | 1865 __ AssertZeroExtended(i.OutputRegister()); |
1865 break; | 1866 break; |
1866 case kX64Movzxbl: | 1867 case kX64Movzxbl: |
1867 EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, | 1868 EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, |
1868 __ pc_offset(), instr); | 1869 __ pc_offset()); |
1869 ASSEMBLE_MOVX(movzxbl); | 1870 ASSEMBLE_MOVX(movzxbl); |
1870 __ AssertZeroExtended(i.OutputRegister()); | 1871 __ AssertZeroExtended(i.OutputRegister()); |
1871 break; | 1872 break; |
1872 case kX64Movsxbq: | 1873 case kX64Movsxbq: |
1873 EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, | 1874 EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, |
1874 __ pc_offset(), instr); | 1875 __ pc_offset()); |
1875 ASSEMBLE_MOVX(movsxbq); | 1876 ASSEMBLE_MOVX(movsxbq); |
1876 break; | 1877 break; |
1877 case kX64Movzxbq: | 1878 case kX64Movzxbq: |
1878 EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, | 1879 EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, |
1879 __ pc_offset(), instr); | 1880 __ pc_offset()); |
1880 ASSEMBLE_MOVX(movzxbq); | 1881 ASSEMBLE_MOVX(movzxbq); |
1881 __ AssertZeroExtended(i.OutputRegister()); | 1882 __ AssertZeroExtended(i.OutputRegister()); |
1882 break; | 1883 break; |
1883 case kX64Movb: { | 1884 case kX64Movb: { |
1884 EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, | 1885 EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, |
1885 __ pc_offset(), instr); | 1886 __ pc_offset()); |
1886 size_t index = 0; | 1887 size_t index = 0; |
1887 Operand operand = i.MemoryOperand(&index); | 1888 Operand operand = i.MemoryOperand(&index); |
1888 if (HasImmediateInput(instr, index)) { | 1889 if (HasImmediateInput(instr, index)) { |
1889 __ movb(operand, Immediate(i.InputInt8(index))); | 1890 __ movb(operand, Immediate(i.InputInt8(index))); |
1890 } else { | 1891 } else { |
1891 __ movb(operand, i.InputRegister(index)); | 1892 __ movb(operand, i.InputRegister(index)); |
1892 } | 1893 } |
1893 break; | 1894 break; |
1894 } | 1895 } |
1895 case kX64Movsxwl: | 1896 case kX64Movsxwl: |
1896 EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, | 1897 EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, |
1897 __ pc_offset(), instr); | 1898 __ pc_offset()); |
1898 ASSEMBLE_MOVX(movsxwl); | 1899 ASSEMBLE_MOVX(movsxwl); |
1899 __ AssertZeroExtended(i.OutputRegister()); | 1900 __ AssertZeroExtended(i.OutputRegister()); |
1900 break; | 1901 break; |
1901 case kX64Movzxwl: | 1902 case kX64Movzxwl: |
1902 EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, | 1903 EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, |
1903 __ pc_offset(), instr); | 1904 __ pc_offset()); |
1904 ASSEMBLE_MOVX(movzxwl); | 1905 ASSEMBLE_MOVX(movzxwl); |
1905 __ AssertZeroExtended(i.OutputRegister()); | 1906 __ AssertZeroExtended(i.OutputRegister()); |
1906 break; | 1907 break; |
1907 case kX64Movsxwq: | 1908 case kX64Movsxwq: |
1908 EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, | 1909 EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, |
1909 __ pc_offset(), instr); | 1910 __ pc_offset()); |
1910 ASSEMBLE_MOVX(movsxwq); | 1911 ASSEMBLE_MOVX(movsxwq); |
1911 break; | 1912 break; |
1912 case kX64Movzxwq: | 1913 case kX64Movzxwq: |
1913 EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, | 1914 EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, |
1914 __ pc_offset(), instr); | 1915 __ pc_offset()); |
1915 ASSEMBLE_MOVX(movzxwq); | 1916 ASSEMBLE_MOVX(movzxwq); |
1916 __ AssertZeroExtended(i.OutputRegister()); | 1917 __ AssertZeroExtended(i.OutputRegister()); |
1917 break; | 1918 break; |
1918 case kX64Movw: { | 1919 case kX64Movw: { |
1919 EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, | 1920 EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, |
1920 __ pc_offset(), instr); | 1921 __ pc_offset()); |
1921 size_t index = 0; | 1922 size_t index = 0; |
1922 Operand operand = i.MemoryOperand(&index); | 1923 Operand operand = i.MemoryOperand(&index); |
1923 if (HasImmediateInput(instr, index)) { | 1924 if (HasImmediateInput(instr, index)) { |
1924 __ movw(operand, Immediate(i.InputInt16(index))); | 1925 __ movw(operand, Immediate(i.InputInt16(index))); |
1925 } else { | 1926 } else { |
1926 __ movw(operand, i.InputRegister(index)); | 1927 __ movw(operand, i.InputRegister(index)); |
1927 } | 1928 } |
1928 break; | 1929 break; |
1929 } | 1930 } |
1930 case kX64Movl: | 1931 case kX64Movl: |
1931 EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, | 1932 EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, |
1932 __ pc_offset(), instr); | 1933 __ pc_offset()); |
1933 if (instr->HasOutput()) { | 1934 if (instr->HasOutput()) { |
1934 if (instr->addressing_mode() == kMode_None) { | 1935 if (instr->addressing_mode() == kMode_None) { |
1935 if (instr->InputAt(0)->IsRegister()) { | 1936 if (instr->InputAt(0)->IsRegister()) { |
1936 __ movl(i.OutputRegister(), i.InputRegister(0)); | 1937 __ movl(i.OutputRegister(), i.InputRegister(0)); |
1937 } else { | 1938 } else { |
1938 __ movl(i.OutputRegister(), i.InputOperand(0)); | 1939 __ movl(i.OutputRegister(), i.InputOperand(0)); |
1939 } | 1940 } |
1940 } else { | 1941 } else { |
1941 __ movl(i.OutputRegister(), i.MemoryOperand()); | 1942 __ movl(i.OutputRegister(), i.MemoryOperand()); |
1942 } | 1943 } |
1943 __ AssertZeroExtended(i.OutputRegister()); | 1944 __ AssertZeroExtended(i.OutputRegister()); |
1944 } else { | 1945 } else { |
1945 size_t index = 0; | 1946 size_t index = 0; |
1946 Operand operand = i.MemoryOperand(&index); | 1947 Operand operand = i.MemoryOperand(&index); |
1947 if (HasImmediateInput(instr, index)) { | 1948 if (HasImmediateInput(instr, index)) { |
1948 __ movl(operand, i.InputImmediate(index)); | 1949 __ movl(operand, i.InputImmediate(index)); |
1949 } else { | 1950 } else { |
1950 __ movl(operand, i.InputRegister(index)); | 1951 __ movl(operand, i.InputRegister(index)); |
1951 } | 1952 } |
1952 } | 1953 } |
1953 break; | 1954 break; |
1954 case kX64Movsxlq: | 1955 case kX64Movsxlq: |
1955 EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, | 1956 EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, |
1956 __ pc_offset(), instr); | 1957 __ pc_offset()); |
1957 ASSEMBLE_MOVX(movsxlq); | 1958 ASSEMBLE_MOVX(movsxlq); |
1958 break; | 1959 break; |
1959 case kX64Movq: | 1960 case kX64Movq: |
1960 EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, | 1961 EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, |
1961 __ pc_offset(), instr); | 1962 __ pc_offset()); |
1962 if (instr->HasOutput()) { | 1963 if (instr->HasOutput()) { |
1963 __ movq(i.OutputRegister(), i.MemoryOperand()); | 1964 __ movq(i.OutputRegister(), i.MemoryOperand()); |
1964 } else { | 1965 } else { |
1965 size_t index = 0; | 1966 size_t index = 0; |
1966 Operand operand = i.MemoryOperand(&index); | 1967 Operand operand = i.MemoryOperand(&index); |
1967 if (HasImmediateInput(instr, index)) { | 1968 if (HasImmediateInput(instr, index)) { |
1968 __ movq(operand, i.InputImmediate(index)); | 1969 __ movq(operand, i.InputImmediate(index)); |
1969 } else { | 1970 } else { |
1970 __ movq(operand, i.InputRegister(index)); | 1971 __ movq(operand, i.InputRegister(index)); |
1971 } | 1972 } |
1972 } | 1973 } |
1973 break; | 1974 break; |
1974 case kX64Movss: | 1975 case kX64Movss: |
1975 EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, | 1976 EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, |
1976 __ pc_offset(), instr); | 1977 __ pc_offset()); |
1977 if (instr->HasOutput()) { | 1978 if (instr->HasOutput()) { |
1978 __ movss(i.OutputDoubleRegister(), i.MemoryOperand()); | 1979 __ movss(i.OutputDoubleRegister(), i.MemoryOperand()); |
1979 } else { | 1980 } else { |
1980 size_t index = 0; | 1981 size_t index = 0; |
1981 Operand operand = i.MemoryOperand(&index); | 1982 Operand operand = i.MemoryOperand(&index); |
1982 __ movss(operand, i.InputDoubleRegister(index)); | 1983 __ movss(operand, i.InputDoubleRegister(index)); |
1983 } | 1984 } |
1984 break; | 1985 break; |
1985 case kX64Movsd: | 1986 case kX64Movsd: |
1986 EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, | 1987 EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, |
1987 __ pc_offset(), instr); | 1988 __ pc_offset()); |
1988 if (instr->HasOutput()) { | 1989 if (instr->HasOutput()) { |
1989 __ Movsd(i.OutputDoubleRegister(), i.MemoryOperand()); | 1990 __ Movsd(i.OutputDoubleRegister(), i.MemoryOperand()); |
1990 } else { | 1991 } else { |
1991 size_t index = 0; | 1992 size_t index = 0; |
1992 Operand operand = i.MemoryOperand(&index); | 1993 Operand operand = i.MemoryOperand(&index); |
1993 __ Movsd(operand, i.InputDoubleRegister(index)); | 1994 __ Movsd(operand, i.InputDoubleRegister(index)); |
1994 } | 1995 } |
1995 break; | 1996 break; |
1996 case kX64BitcastFI: | 1997 case kX64BitcastFI: |
1997 if (instr->InputAt(0)->IsFPStackSlot()) { | 1998 if (instr->InputAt(0)->IsFPStackSlot()) { |
(...skipping 880 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2878 int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc; | 2879 int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc; |
2879 __ Nop(padding_size); | 2880 __ Nop(padding_size); |
2880 } | 2881 } |
2881 } | 2882 } |
2882 | 2883 |
2883 #undef __ | 2884 #undef __ |
2884 | 2885 |
2885 } // namespace compiler | 2886 } // namespace compiler |
2886 } // namespace internal | 2887 } // namespace internal |
2887 } // namespace v8 | 2888 } // namespace v8 |
OLD | NEW |