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

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

Issue 1584663007: [turbofan] Implement rounding of floats on x64 and ia32 without sse4.1. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 11 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
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/ast/scopes.h" 7 #include "src/ast/scopes.h"
8 #include "src/compiler/code-generator-impl.h" 8 #include "src/compiler/code-generator-impl.h"
9 #include "src/compiler/gap-resolver.h" 9 #include "src/compiler/gap-resolver.h"
10 #include "src/compiler/node-matchers.h" 10 #include "src/compiler/node-matchers.h"
(...skipping 923 matching lines...) Expand 10 before | Expand all | Expand 10 after
934 case kSSEFloat32Max: 934 case kSSEFloat32Max:
935 ASSEMBLE_SSE_BINOP(maxss); 935 ASSEMBLE_SSE_BINOP(maxss);
936 break; 936 break;
937 case kSSEFloat32Min: 937 case kSSEFloat32Min:
938 ASSEMBLE_SSE_BINOP(minss); 938 ASSEMBLE_SSE_BINOP(minss);
939 break; 939 break;
940 case kSSEFloat32ToFloat64: 940 case kSSEFloat32ToFloat64:
941 ASSEMBLE_SSE_UNOP(Cvtss2sd); 941 ASSEMBLE_SSE_UNOP(Cvtss2sd);
942 break; 942 break;
943 case kSSEFloat32Round: { 943 case kSSEFloat32Round: {
944 CpuFeatureScope sse_scope(masm(), SSE4_1);
945 RoundingMode const mode = 944 RoundingMode const mode =
946 static_cast<RoundingMode>(MiscField::decode(instr->opcode())); 945 static_cast<RoundingMode>(MiscField::decode(instr->opcode()));
947 __ Roundss(i.OutputDoubleRegister(), i.InputDoubleRegister(0), mode); 946 if (CpuFeatures::IsSupported(SSE4_1)) {
947 CpuFeatureScope sse_scope(masm(), SSE4_1);
948 __ Roundss(i.OutputDoubleRegister(), i.InputDoubleRegister(0), mode);
949 } else {
950 // Set the rounding mode.
951 // We have to store the original rounding mode in memory.
952 __ subq(rsp, Immediate(kPointerSize * 2));
953 __ stmxcsr(Operand(rsp, 0));
954 __ movl(kScratchRegister, Operand(rsp, 0));
955 __ andl(kScratchRegister, Immediate(0xffff9fff));
956 __ orl(kScratchRegister, Immediate(mode << 13));
957 __ movl(Operand(rsp, kPointerSize), kScratchRegister);
958 __ ldmxcsr(Operand(rsp, kPointerSize));
959
960 // Start with the conversion.
961 if (instr->InputAt(0)->IsDoubleRegister()) {
962 __ Cvtss2siq(kScratchRegister, i.InputDoubleRegister(0));
963 } else {
964 __ Cvtss2siq(kScratchRegister, i.InputOperand(0));
965 }
966
967 Label out_of_range;
968 Label done;
969 __ cmpq(kScratchRegister, Immediate(1));
970 // If the conversion results in INT64_MIN, then the input is out of
971 // int64 range.
972 __ j(overflow, &out_of_range);
973 // Rounding is done by converting the value back to float.
974 __ Cvtqsi2ss(i.OutputDoubleRegister(), kScratchRegister);
975 __ jmp(&done);
976
977 __ bind(&out_of_range);
978 // The input is out of int64 range. Fractions are not possible for
979 // inputs out of int64 range, so we don't have to do any rounding.
980 if (instr->InputAt(0)->IsDoubleRegister()) {
981 __ movss(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
982 } else {
983 __ movss(i.OutputDoubleRegister(), i.InputOperand(0));
984 }
985
986 __ bind(&done);
987 // Restore the original rounding mode.
988 __ ldmxcsr(Operand(rsp, 0));
989 __ addq(rsp, Immediate(kPointerSize * 2));
990 }
948 break; 991 break;
949 } 992 }
950 case kSSEFloat64Cmp: 993 case kSSEFloat64Cmp:
951 ASSEMBLE_SSE_BINOP(Ucomisd); 994 ASSEMBLE_SSE_BINOP(Ucomisd);
952 break; 995 break;
953 case kSSEFloat64Add: 996 case kSSEFloat64Add:
954 ASSEMBLE_SSE_BINOP(addsd); 997 ASSEMBLE_SSE_BINOP(addsd);
955 break; 998 break;
956 case kSSEFloat64Sub: 999 case kSSEFloat64Sub:
957 ASSEMBLE_SSE_BINOP(subsd); 1000 ASSEMBLE_SSE_BINOP(subsd);
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
1014 // TODO(bmeurer): Use RIP relative 128-bit constants. 1057 // TODO(bmeurer): Use RIP relative 128-bit constants.
1015 __ pcmpeqd(kScratchDoubleReg, kScratchDoubleReg); 1058 __ pcmpeqd(kScratchDoubleReg, kScratchDoubleReg);
1016 __ psllq(kScratchDoubleReg, 63); 1059 __ psllq(kScratchDoubleReg, 63);
1017 __ xorpd(i.OutputDoubleRegister(), kScratchDoubleReg); 1060 __ xorpd(i.OutputDoubleRegister(), kScratchDoubleReg);
1018 break; 1061 break;
1019 } 1062 }
1020 case kSSEFloat64Sqrt: 1063 case kSSEFloat64Sqrt:
1021 ASSEMBLE_SSE_UNOP(sqrtsd); 1064 ASSEMBLE_SSE_UNOP(sqrtsd);
1022 break; 1065 break;
1023 case kSSEFloat64Round: { 1066 case kSSEFloat64Round: {
1024 CpuFeatureScope sse_scope(masm(), SSE4_1);
1025 RoundingMode const mode = 1067 RoundingMode const mode =
1026 static_cast<RoundingMode>(MiscField::decode(instr->opcode())); 1068 static_cast<RoundingMode>(MiscField::decode(instr->opcode()));
1027 __ Roundsd(i.OutputDoubleRegister(), i.InputDoubleRegister(0), mode); 1069 if (CpuFeatures::IsSupported(SSE4_1)) {
1070 CpuFeatureScope sse_scope(masm(), SSE4_1);
1071 __ Roundsd(i.OutputDoubleRegister(), i.InputDoubleRegister(0), mode);
1072 } else {
1073 // Set the rounding mode.
1074 // We have to store the original rounding mode in memory.
1075 __ subq(rsp, Immediate(kPointerSize * 2));
1076 __ stmxcsr(Operand(rsp, 0));
1077 __ movl(kScratchRegister, Operand(rsp, 0));
1078 __ andl(kScratchRegister, Immediate(0xffff9fff));
1079 __ orl(kScratchRegister, Immediate(mode << 13));
1080 __ movl(Operand(rsp, kPointerSize), kScratchRegister);
1081 __ ldmxcsr(Operand(rsp, kPointerSize));
1082
1083 // Start with the conversion.
1084 if (instr->InputAt(0)->IsDoubleRegister()) {
1085 __ Cvtsd2siq(kScratchRegister, i.InputDoubleRegister(0));
1086 } else {
1087 __ Cvtsd2siq(kScratchRegister, i.InputOperand(0));
1088 }
1089
1090 Label out_of_range;
1091 Label done;
1092 __ cmpq(kScratchRegister, Immediate(1));
1093 // If the conversion results in INT64_MIN, but the input was not
1094 // INT64_MIN, then the conversion fails.
1095 __ j(overflow, &out_of_range);
1096 __ Cvtqsi2sd(i.OutputDoubleRegister(), kScratchRegister);
1097 __ jmp(&done);
1098
1099 __ bind(&out_of_range);
1100 // The input is out of int64 range. Fractions are not possible for
1101 // inputs
1102 // out of int64 range, so we don't have to do any rounding.
1103 if (instr->InputAt(0)->IsDoubleRegister()) {
1104 __ movsd(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
1105 } else {
1106 __ movsd(i.OutputDoubleRegister(), i.InputOperand(0));
1107 }
1108
1109 __ bind(&done);
1110 // Restore the original rounding mode.
1111 __ ldmxcsr(Operand(rsp, 0));
1112 __ addq(rsp, Immediate(kPointerSize * 2));
1113 }
1028 break; 1114 break;
1029 } 1115 }
1030 case kSSEFloat64ToFloat32: 1116 case kSSEFloat64ToFloat32:
1031 ASSEMBLE_SSE_UNOP(Cvtsd2ss); 1117 ASSEMBLE_SSE_UNOP(Cvtsd2ss);
1032 break; 1118 break;
1033 case kSSEFloat64ToInt32: 1119 case kSSEFloat64ToInt32:
1034 if (instr->InputAt(0)->IsDoubleRegister()) { 1120 if (instr->InputAt(0)->IsDoubleRegister()) {
1035 __ Cvttsd2si(i.OutputRegister(), i.InputDoubleRegister(0)); 1121 __ Cvttsd2si(i.OutputRegister(), i.InputDoubleRegister(0));
1036 } else { 1122 } else {
1037 __ Cvttsd2si(i.OutputRegister(), i.InputOperand(0)); 1123 __ Cvttsd2si(i.OutputRegister(), i.InputOperand(0));
(...skipping 1069 matching lines...) Expand 10 before | Expand all | Expand 10 after
2107 int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc; 2193 int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc;
2108 __ Nop(padding_size); 2194 __ Nop(padding_size);
2109 } 2195 }
2110 } 2196 }
2111 2197
2112 #undef __ 2198 #undef __
2113 2199
2114 } // namespace compiler 2200 } // namespace compiler
2115 } // namespace internal 2201 } // namespace internal
2116 } // namespace v8 2202 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698