Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: src/compiler/x64/code-generator-x64.cc

Issue 1391963005: [x64] Use vmovapd and vmovsd when AVX is enabled. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix Win compile. Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | src/x64/assembler-x64.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "src/compiler/code-generator-impl.h" 7 #include "src/compiler/code-generator-impl.h"
8 #include "src/compiler/gap-resolver.h" 8 #include "src/compiler/gap-resolver.h"
9 #include "src/compiler/node-matchers.h" 9 #include "src/compiler/node-matchers.h"
10 #include "src/compiler/osr.h" 10 #include "src/compiler/osr.h"
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
174 174
175 175
176 class OutOfLineTruncateDoubleToI final : public OutOfLineCode { 176 class OutOfLineTruncateDoubleToI final : public OutOfLineCode {
177 public: 177 public:
178 OutOfLineTruncateDoubleToI(CodeGenerator* gen, Register result, 178 OutOfLineTruncateDoubleToI(CodeGenerator* gen, Register result,
179 XMMRegister input) 179 XMMRegister input)
180 : OutOfLineCode(gen), result_(result), input_(input) {} 180 : OutOfLineCode(gen), result_(result), input_(input) {}
181 181
182 void Generate() final { 182 void Generate() final {
183 __ subp(rsp, Immediate(kDoubleSize)); 183 __ subp(rsp, Immediate(kDoubleSize));
184 __ movsd(MemOperand(rsp, 0), input_); 184 __ Movsd(MemOperand(rsp, 0), input_);
185 __ SlowTruncateToI(result_, rsp, 0); 185 __ SlowTruncateToI(result_, rsp, 0);
186 __ addp(rsp, Immediate(kDoubleSize)); 186 __ addp(rsp, Immediate(kDoubleSize));
187 } 187 }
188 188
189 private: 189 private:
190 Register const result_; 190 Register const result_;
191 XMMRegister const input_; 191 XMMRegister const input_;
192 }; 192 };
193 193
194 } // namespace 194 } // namespace
(...skipping 633 matching lines...) Expand 10 before | Expand all | Expand 10 after
828 break; 828 break;
829 case kSSEFloat64Div: 829 case kSSEFloat64Div:
830 ASSEMBLE_SSE_BINOP(divsd); 830 ASSEMBLE_SSE_BINOP(divsd);
831 // Don't delete this mov. It may improve performance on some CPUs, 831 // Don't delete this mov. It may improve performance on some CPUs,
832 // when there is a (v)mulsd depending on the result. 832 // when there is a (v)mulsd depending on the result.
833 __ movaps(i.OutputDoubleRegister(), i.OutputDoubleRegister()); 833 __ movaps(i.OutputDoubleRegister(), i.OutputDoubleRegister());
834 break; 834 break;
835 case kSSEFloat64Mod: { 835 case kSSEFloat64Mod: {
836 __ subq(rsp, Immediate(kDoubleSize)); 836 __ subq(rsp, Immediate(kDoubleSize));
837 // Move values to st(0) and st(1). 837 // Move values to st(0) and st(1).
838 __ movsd(Operand(rsp, 0), i.InputDoubleRegister(1)); 838 __ Movsd(Operand(rsp, 0), i.InputDoubleRegister(1));
839 __ fld_d(Operand(rsp, 0)); 839 __ fld_d(Operand(rsp, 0));
840 __ movsd(Operand(rsp, 0), i.InputDoubleRegister(0)); 840 __ Movsd(Operand(rsp, 0), i.InputDoubleRegister(0));
841 __ fld_d(Operand(rsp, 0)); 841 __ fld_d(Operand(rsp, 0));
842 // Loop while fprem isn't done. 842 // Loop while fprem isn't done.
843 Label mod_loop; 843 Label mod_loop;
844 __ bind(&mod_loop); 844 __ bind(&mod_loop);
845 // This instructions traps on all kinds inputs, but we are assuming the 845 // This instructions traps on all kinds inputs, but we are assuming the
846 // floating point control word is set to ignore them all. 846 // floating point control word is set to ignore them all.
847 __ fprem(); 847 __ fprem();
848 // The following 2 instruction implicitly use rax. 848 // The following 2 instruction implicitly use rax.
849 __ fnstsw_ax(); 849 __ fnstsw_ax();
850 if (CpuFeatures::IsSupported(SAHF)) { 850 if (CpuFeatures::IsSupported(SAHF)) {
851 CpuFeatureScope sahf_scope(masm(), SAHF); 851 CpuFeatureScope sahf_scope(masm(), SAHF);
852 __ sahf(); 852 __ sahf();
853 } else { 853 } else {
854 __ shrl(rax, Immediate(8)); 854 __ shrl(rax, Immediate(8));
855 __ andl(rax, Immediate(0xFF)); 855 __ andl(rax, Immediate(0xFF));
856 __ pushq(rax); 856 __ pushq(rax);
857 __ popfq(); 857 __ popfq();
858 } 858 }
859 __ j(parity_even, &mod_loop); 859 __ j(parity_even, &mod_loop);
860 // Move output to stack and clean up. 860 // Move output to stack and clean up.
861 __ fstp(1); 861 __ fstp(1);
862 __ fstp_d(Operand(rsp, 0)); 862 __ fstp_d(Operand(rsp, 0));
863 __ movsd(i.OutputDoubleRegister(), Operand(rsp, 0)); 863 __ Movsd(i.OutputDoubleRegister(), Operand(rsp, 0));
864 __ addq(rsp, Immediate(kDoubleSize)); 864 __ addq(rsp, Immediate(kDoubleSize));
865 break; 865 break;
866 } 866 }
867 case kSSEFloat64Max: 867 case kSSEFloat64Max:
868 ASSEMBLE_SSE_BINOP(maxsd); 868 ASSEMBLE_SSE_BINOP(maxsd);
869 break; 869 break;
870 case kSSEFloat64Min: 870 case kSSEFloat64Min:
871 ASSEMBLE_SSE_BINOP(minsd); 871 ASSEMBLE_SSE_BINOP(minsd);
872 break; 872 break;
873 case kSSEFloat64Abs: { 873 case kSSEFloat64Abs: {
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after
1157 if (instr->HasOutput()) { 1157 if (instr->HasOutput()) {
1158 __ movss(i.OutputDoubleRegister(), i.MemoryOperand()); 1158 __ movss(i.OutputDoubleRegister(), i.MemoryOperand());
1159 } else { 1159 } else {
1160 size_t index = 0; 1160 size_t index = 0;
1161 Operand operand = i.MemoryOperand(&index); 1161 Operand operand = i.MemoryOperand(&index);
1162 __ movss(operand, i.InputDoubleRegister(index)); 1162 __ movss(operand, i.InputDoubleRegister(index));
1163 } 1163 }
1164 break; 1164 break;
1165 case kX64Movsd: 1165 case kX64Movsd:
1166 if (instr->HasOutput()) { 1166 if (instr->HasOutput()) {
1167 __ movsd(i.OutputDoubleRegister(), i.MemoryOperand()); 1167 __ Movsd(i.OutputDoubleRegister(), i.MemoryOperand());
1168 } else { 1168 } else {
1169 size_t index = 0; 1169 size_t index = 0;
1170 Operand operand = i.MemoryOperand(&index); 1170 Operand operand = i.MemoryOperand(&index);
1171 __ movsd(operand, i.InputDoubleRegister(index)); 1171 __ Movsd(operand, i.InputDoubleRegister(index));
1172 } 1172 }
1173 break; 1173 break;
1174 case kX64BitcastFI: 1174 case kX64BitcastFI:
1175 if (instr->InputAt(0)->IsDoubleStackSlot()) { 1175 if (instr->InputAt(0)->IsDoubleStackSlot()) {
1176 __ movl(i.OutputRegister(), i.InputOperand(0)); 1176 __ movl(i.OutputRegister(), i.InputOperand(0));
1177 } else { 1177 } else {
1178 __ movd(i.OutputRegister(), i.InputDoubleRegister(0)); 1178 __ movd(i.OutputRegister(), i.InputDoubleRegister(0));
1179 } 1179 }
1180 break; 1180 break;
1181 case kX64BitcastDL: 1181 case kX64BitcastDL:
1182 if (instr->InputAt(0)->IsDoubleStackSlot()) { 1182 if (instr->InputAt(0)->IsDoubleStackSlot()) {
1183 __ movq(i.OutputRegister(), i.InputOperand(0)); 1183 __ movq(i.OutputRegister(), i.InputOperand(0));
1184 } else { 1184 } else {
1185 __ movq(i.OutputRegister(), i.InputDoubleRegister(0)); 1185 __ movq(i.OutputRegister(), i.InputDoubleRegister(0));
1186 } 1186 }
1187 break; 1187 break;
1188 case kX64BitcastIF: 1188 case kX64BitcastIF:
1189 if (instr->InputAt(0)->IsRegister()) { 1189 if (instr->InputAt(0)->IsRegister()) {
1190 __ movd(i.OutputDoubleRegister(), i.InputRegister(0)); 1190 __ movd(i.OutputDoubleRegister(), i.InputRegister(0));
1191 } else { 1191 } else {
1192 __ movss(i.OutputDoubleRegister(), i.InputOperand(0)); 1192 __ movss(i.OutputDoubleRegister(), i.InputOperand(0));
1193 } 1193 }
1194 break; 1194 break;
1195 case kX64BitcastLD: 1195 case kX64BitcastLD:
1196 if (instr->InputAt(0)->IsRegister()) { 1196 if (instr->InputAt(0)->IsRegister()) {
1197 __ movq(i.OutputDoubleRegister(), i.InputRegister(0)); 1197 __ movq(i.OutputDoubleRegister(), i.InputRegister(0));
1198 } else { 1198 } else {
1199 __ movsd(i.OutputDoubleRegister(), i.InputOperand(0)); 1199 __ Movsd(i.OutputDoubleRegister(), i.InputOperand(0));
1200 } 1200 }
1201 break; 1201 break;
1202 case kX64Lea32: { 1202 case kX64Lea32: {
1203 AddressingMode mode = AddressingModeField::decode(instr->opcode()); 1203 AddressingMode mode = AddressingModeField::decode(instr->opcode());
1204 // Shorten "leal" to "addl", "subl" or "shll" if the register allocation 1204 // Shorten "leal" to "addl", "subl" or "shll" if the register allocation
1205 // and addressing mode just happens to work out. The "addl"/"subl" forms 1205 // and addressing mode just happens to work out. The "addl"/"subl" forms
1206 // in these cases are faster based on measurements. 1206 // in these cases are faster based on measurements.
1207 if (i.InputRegister(0).is(i.OutputRegister())) { 1207 if (i.InputRegister(0).is(i.OutputRegister())) {
1208 if (mode == kMode_MRI) { 1208 if (mode == kMode_MRI) {
1209 int32_t constant_summand = i.InputInt32(1); 1209 int32_t constant_summand = i.InputInt32(1);
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1244 break; 1244 break;
1245 case kX64Push: 1245 case kX64Push:
1246 if (HasImmediateInput(instr, 0)) { 1246 if (HasImmediateInput(instr, 0)) {
1247 __ pushq(i.InputImmediate(0)); 1247 __ pushq(i.InputImmediate(0));
1248 } else { 1248 } else {
1249 if (instr->InputAt(0)->IsRegister()) { 1249 if (instr->InputAt(0)->IsRegister()) {
1250 __ pushq(i.InputRegister(0)); 1250 __ pushq(i.InputRegister(0));
1251 } else if (instr->InputAt(0)->IsDoubleRegister()) { 1251 } else if (instr->InputAt(0)->IsDoubleRegister()) {
1252 // TODO(titzer): use another machine instruction? 1252 // TODO(titzer): use another machine instruction?
1253 __ subq(rsp, Immediate(kDoubleSize)); 1253 __ subq(rsp, Immediate(kDoubleSize));
1254 __ movsd(Operand(rsp, 0), i.InputDoubleRegister(0)); 1254 __ Movsd(Operand(rsp, 0), i.InputDoubleRegister(0));
1255 } else { 1255 } else {
1256 __ pushq(i.InputOperand(0)); 1256 __ pushq(i.InputOperand(0));
1257 } 1257 }
1258 } 1258 }
1259 break; 1259 break;
1260 case kX64Poke: { 1260 case kX64Poke: {
1261 int const slot = MiscField::decode(instr->opcode()); 1261 int const slot = MiscField::decode(instr->opcode());
1262 if (HasImmediateInput(instr, 0)) { 1262 if (HasImmediateInput(instr, 0)) {
1263 __ movq(Operand(rsp, slot * kPointerSize), i.InputImmediate(0)); 1263 __ movq(Operand(rsp, slot * kPointerSize), i.InputImmediate(0));
1264 } else { 1264 } else {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1299 case kCheckedLoadWord32: 1299 case kCheckedLoadWord32:
1300 ASSEMBLE_CHECKED_LOAD_INTEGER(movl); 1300 ASSEMBLE_CHECKED_LOAD_INTEGER(movl);
1301 break; 1301 break;
1302 case kCheckedLoadWord64: 1302 case kCheckedLoadWord64:
1303 ASSEMBLE_CHECKED_LOAD_INTEGER(movq); 1303 ASSEMBLE_CHECKED_LOAD_INTEGER(movq);
1304 break; 1304 break;
1305 case kCheckedLoadFloat32: 1305 case kCheckedLoadFloat32:
1306 ASSEMBLE_CHECKED_LOAD_FLOAT(movss); 1306 ASSEMBLE_CHECKED_LOAD_FLOAT(movss);
1307 break; 1307 break;
1308 case kCheckedLoadFloat64: 1308 case kCheckedLoadFloat64:
1309 ASSEMBLE_CHECKED_LOAD_FLOAT(movsd); 1309 ASSEMBLE_CHECKED_LOAD_FLOAT(Movsd);
1310 break; 1310 break;
1311 case kCheckedStoreWord8: 1311 case kCheckedStoreWord8:
1312 ASSEMBLE_CHECKED_STORE_INTEGER(movb); 1312 ASSEMBLE_CHECKED_STORE_INTEGER(movb);
1313 break; 1313 break;
1314 case kCheckedStoreWord16: 1314 case kCheckedStoreWord16:
1315 ASSEMBLE_CHECKED_STORE_INTEGER(movw); 1315 ASSEMBLE_CHECKED_STORE_INTEGER(movw);
1316 break; 1316 break;
1317 case kCheckedStoreWord32: 1317 case kCheckedStoreWord32:
1318 ASSEMBLE_CHECKED_STORE_INTEGER(movl); 1318 ASSEMBLE_CHECKED_STORE_INTEGER(movl);
1319 break; 1319 break;
1320 case kCheckedStoreWord64: 1320 case kCheckedStoreWord64:
1321 ASSEMBLE_CHECKED_STORE_INTEGER(movq); 1321 ASSEMBLE_CHECKED_STORE_INTEGER(movq);
1322 break; 1322 break;
1323 case kCheckedStoreFloat32: 1323 case kCheckedStoreFloat32:
1324 ASSEMBLE_CHECKED_STORE_FLOAT(movss); 1324 ASSEMBLE_CHECKED_STORE_FLOAT(movss);
1325 break; 1325 break;
1326 case kCheckedStoreFloat64: 1326 case kCheckedStoreFloat64:
1327 ASSEMBLE_CHECKED_STORE_FLOAT(movsd); 1327 ASSEMBLE_CHECKED_STORE_FLOAT(Movsd);
1328 break; 1328 break;
1329 case kX64StackCheck: 1329 case kX64StackCheck:
1330 __ CompareRoot(rsp, Heap::kStackLimitRootIndex); 1330 __ CompareRoot(rsp, Heap::kStackLimitRootIndex);
1331 break; 1331 break;
1332 } 1332 }
1333 } // NOLINT(readability/fn_size) 1333 } // NOLINT(readability/fn_size)
1334 1334
1335 1335
1336 // Assembles branches after this instruction. 1336 // Assembles branches after this instruction.
1337 void CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) { 1337 void CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) {
(...skipping 379 matching lines...) Expand 10 before | Expand all | Expand 10 after
1717 } 1717 }
1718 } 1718 }
1719 } else if (source->IsDoubleRegister()) { 1719 } else if (source->IsDoubleRegister()) {
1720 XMMRegister src = g.ToDoubleRegister(source); 1720 XMMRegister src = g.ToDoubleRegister(source);
1721 if (destination->IsDoubleRegister()) { 1721 if (destination->IsDoubleRegister()) {
1722 XMMRegister dst = g.ToDoubleRegister(destination); 1722 XMMRegister dst = g.ToDoubleRegister(destination);
1723 __ movaps(dst, src); 1723 __ movaps(dst, src);
1724 } else { 1724 } else {
1725 DCHECK(destination->IsDoubleStackSlot()); 1725 DCHECK(destination->IsDoubleStackSlot());
1726 Operand dst = g.ToOperand(destination); 1726 Operand dst = g.ToOperand(destination);
1727 __ movsd(dst, src); 1727 __ Movsd(dst, src);
1728 } 1728 }
1729 } else if (source->IsDoubleStackSlot()) { 1729 } else if (source->IsDoubleStackSlot()) {
1730 DCHECK(destination->IsDoubleRegister() || destination->IsDoubleStackSlot()); 1730 DCHECK(destination->IsDoubleRegister() || destination->IsDoubleStackSlot());
1731 Operand src = g.ToOperand(source); 1731 Operand src = g.ToOperand(source);
1732 if (destination->IsDoubleRegister()) { 1732 if (destination->IsDoubleRegister()) {
1733 XMMRegister dst = g.ToDoubleRegister(destination); 1733 XMMRegister dst = g.ToDoubleRegister(destination);
1734 __ movsd(dst, src); 1734 __ Movsd(dst, src);
1735 } else { 1735 } else {
1736 // We rely on having xmm0 available as a fixed scratch register. 1736 // We rely on having xmm0 available as a fixed scratch register.
1737 Operand dst = g.ToOperand(destination); 1737 Operand dst = g.ToOperand(destination);
1738 __ movsd(xmm0, src); 1738 __ Movsd(xmm0, src);
1739 __ movsd(dst, xmm0); 1739 __ Movsd(dst, xmm0);
1740 } 1740 }
1741 } else { 1741 } else {
1742 UNREACHABLE(); 1742 UNREACHABLE();
1743 } 1743 }
1744 } 1744 }
1745 1745
1746 1746
1747 void CodeGenerator::AssembleSwap(InstructionOperand* source, 1747 void CodeGenerator::AssembleSwap(InstructionOperand* source,
1748 InstructionOperand* destination) { 1748 InstructionOperand* destination) {
1749 X64OperandConverter g(this, NULL); 1749 X64OperandConverter g(this, NULL);
(...skipping 22 matching lines...) Expand all
1772 XMMRegister src = g.ToDoubleRegister(source); 1772 XMMRegister src = g.ToDoubleRegister(source);
1773 XMMRegister dst = g.ToDoubleRegister(destination); 1773 XMMRegister dst = g.ToDoubleRegister(destination);
1774 __ movaps(xmm0, src); 1774 __ movaps(xmm0, src);
1775 __ movaps(src, dst); 1775 __ movaps(src, dst);
1776 __ movaps(dst, xmm0); 1776 __ movaps(dst, xmm0);
1777 } else if (source->IsDoubleRegister() && destination->IsDoubleStackSlot()) { 1777 } else if (source->IsDoubleRegister() && destination->IsDoubleStackSlot()) {
1778 // XMM register-memory swap. We rely on having xmm0 1778 // XMM register-memory swap. We rely on having xmm0
1779 // available as a fixed scratch register. 1779 // available as a fixed scratch register.
1780 XMMRegister src = g.ToDoubleRegister(source); 1780 XMMRegister src = g.ToDoubleRegister(source);
1781 Operand dst = g.ToOperand(destination); 1781 Operand dst = g.ToOperand(destination);
1782 __ movsd(xmm0, src); 1782 __ Movsd(xmm0, src);
1783 __ movsd(src, dst); 1783 __ Movsd(src, dst);
1784 __ movsd(dst, xmm0); 1784 __ Movsd(dst, xmm0);
1785 } else { 1785 } else {
1786 // No other combinations are possible. 1786 // No other combinations are possible.
1787 UNREACHABLE(); 1787 UNREACHABLE();
1788 } 1788 }
1789 } 1789 }
1790 1790
1791 1791
1792 void CodeGenerator::AssembleJumpTable(Label** targets, size_t target_count) { 1792 void CodeGenerator::AssembleJumpTable(Label** targets, size_t target_count) {
1793 for (size_t index = 0; index < target_count; ++index) { 1793 for (size_t index = 0; index < target_count; ++index) {
1794 __ dq(targets[index]); 1794 __ dq(targets[index]);
(...skipping 17 matching lines...) Expand all
1812 int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc; 1812 int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc;
1813 __ Nop(padding_size); 1813 __ Nop(padding_size);
1814 } 1814 }
1815 } 1815 }
1816 1816
1817 #undef __ 1817 #undef __
1818 1818
1819 } // namespace compiler 1819 } // namespace compiler
1820 } // namespace internal 1820 } // namespace internal
1821 } // namespace v8 1821 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | src/x64/assembler-x64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698