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

Side by Side Diff: runtime/vm/flow_graph_compiler_x64.cc

Issue 10875030: Add support for XMM registers in SSA code generation pipeline. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: fix a bug pointed out by Florian Created 8 years, 4 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 | Annotate | Revision Log
« no previous file with comments | « runtime/vm/flow_graph_compiler_ia32.cc ('k') | runtime/vm/flow_graph_optimizer.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 (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64.
6 #if defined(TARGET_ARCH_X64) 6 #if defined(TARGET_ARCH_X64)
7 7
8 #include "vm/flow_graph_compiler.h" 8 #include "vm/flow_graph_compiler.h"
9 9
10 #include "lib/error.h" 10 #include "lib/error.h"
(...skipping 867 matching lines...) Expand 10 before | Expand all | Expand 10 after
878 __ testq(RAX, Immediate(kSmiTagMask)); 878 __ testq(RAX, Immediate(kSmiTagMask));
879 __ j(ZERO, &smi_to_double); 879 __ j(ZERO, &smi_to_double);
880 __ CompareClassId(RAX, kDoubleCid); 880 __ CompareClassId(RAX, kDoubleCid);
881 __ j(NOT_EQUAL, &call_method); 881 __ j(NOT_EQUAL, &call_method);
882 __ movsd(XMM1, FieldAddress(RAX, Double::value_offset())); 882 __ movsd(XMM1, FieldAddress(RAX, Double::value_offset()));
883 __ Bind(&double_op); 883 __ Bind(&double_op);
884 __ sqrtsd(XMM0, XMM1); 884 __ sqrtsd(XMM0, XMM1);
885 AssemblerMacros::TryAllocate(assembler_, 885 AssemblerMacros::TryAllocate(assembler_,
886 double_class_, 886 double_class_,
887 &call_method, 887 &call_method,
888 Assembler::kNearJump,
888 RAX); // Result register. 889 RAX); // Result register.
889 __ movsd(FieldAddress(RAX, Double::value_offset()), XMM0); 890 __ movsd(FieldAddress(RAX, Double::value_offset()), XMM0);
890 __ Drop(1); 891 __ Drop(1);
891 __ jmp(done); 892 __ jmp(done);
892 __ Bind(&smi_to_double); 893 __ Bind(&smi_to_double);
893 __ SmiUntag(RAX); 894 __ SmiUntag(RAX);
894 __ cvtsi2sd(XMM1, RAX); 895 __ cvtsi2sd(XMM1, RAX);
895 __ jmp(&double_op); 896 __ jmp(&double_op);
896 __ Bind(&call_method); 897 __ Bind(&call_method);
897 } 898 }
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after
1107 __ movsd(result, FieldAddress(reg, Double::value_offset())); 1108 __ movsd(result, FieldAddress(reg, Double::value_offset()));
1108 __ jmp(&done); 1109 __ jmp(&done);
1109 __ Bind(&is_smi); 1110 __ Bind(&is_smi);
1110 __ movq(temp, reg); 1111 __ movq(temp, reg);
1111 __ SmiUntag(temp); 1112 __ SmiUntag(temp);
1112 __ cvtsi2sd(result, temp); 1113 __ cvtsi2sd(result, temp);
1113 __ Bind(&done); 1114 __ Bind(&done);
1114 } 1115 }
1115 1116
1116 1117
1118 void FlowGraphCompiler::SaveLiveRegisters(LocationSummary* locs) {
1119 // TODO(vegorov): consider saving only caller save (volatile) registers.
1120 const intptr_t xmm_regs_count = locs->live_registers()->xmm_regs_count();
1121 if (xmm_regs_count > 0) {
1122 // Pointer maps don't support pushed untagged values so we reserve spill
1123 // slots at the top of the spill slot area for live XMM registers.
1124 intptr_t stack_offs = (StackSize() + 1) * kWordSize;
1125 for (intptr_t reg_idx = 0; reg_idx < kNumberOfXmmRegisters; ++reg_idx) {
1126 XmmRegister xmm_reg = static_cast<XmmRegister>(reg_idx);
1127 if (locs->live_registers()->ContainsXmmRegister(xmm_reg)) {
1128 __ movsd(Address(RBP, -stack_offs), xmm_reg);
1129 stack_offs += kDoubleSize;
1130 }
1131 }
1132 }
1133
1134 for (intptr_t reg_idx = 0; reg_idx < kNumberOfCpuRegisters; ++reg_idx) {
1135 Register reg = static_cast<Register>(reg_idx);
1136 if (locs->live_registers()->ContainsRegister(reg)) {
1137 __ pushq(reg);
1138 }
1139 }
1140 }
1141
1142
1143 void FlowGraphCompiler::RestoreLiveRegisters(LocationSummary* locs) {
1144 for (intptr_t reg_idx = kNumberOfCpuRegisters - 1; reg_idx >= 0; --reg_idx) {
1145 Register reg = static_cast<Register>(reg_idx);
1146 if (locs->live_registers()->ContainsRegister(reg)) {
1147 __ popq(reg);
1148 }
1149 }
1150
1151 const intptr_t xmm_regs_count = locs->live_registers()->xmm_regs_count();
1152 if (xmm_regs_count > 0) {
1153 // Pointer maps don't support pushed untagged values so we reserve spill
1154 // slots at the top of the spill slot area for live XMM registers.
1155 intptr_t stack_offs = (StackSize() + 1) * kWordSize;
1156 for (intptr_t reg_idx = 0; reg_idx < kNumberOfXmmRegisters; ++reg_idx) {
1157 XmmRegister xmm_reg = static_cast<XmmRegister>(reg_idx);
1158 if (locs->live_registers()->ContainsXmmRegister(xmm_reg)) {
1159 __ movsd(xmm_reg, Address(RBP, -stack_offs));
1160 stack_offs += kDoubleSize;
1161 }
1162 }
1163 }
1164 }
1165
1166
1117 #undef __ 1167 #undef __
1118 #define __ compiler_->assembler()-> 1168 #define __ compiler_->assembler()->
1119 1169
1120 1170
1121 static Address ToStackSlotAddress(Location loc) { 1171 static Address ToStackSlotAddress(Location loc) {
1122 ASSERT(loc.IsStackSlot());
1123 const intptr_t index = loc.stack_index(); 1172 const intptr_t index = loc.stack_index();
1124 if (index < 0) { 1173 if (index < 0) {
1125 const intptr_t offset = (1 - index) * kWordSize; 1174 const intptr_t offset = (1 - index) * kWordSize;
1126 return Address(RBP, offset); 1175 return Address(RBP, offset);
1127 } else { 1176 } else {
1128 const intptr_t offset = 1177 const intptr_t offset =
1129 (ParsedFunction::kFirstLocalSlotIndex - index) * kWordSize; 1178 (ParsedFunction::kFirstLocalSlotIndex - index) * kWordSize;
1130 return Address(RBP, offset); 1179 return Address(RBP, offset);
1131 } 1180 }
1132 } 1181 }
(...skipping 12 matching lines...) Expand all
1145 __ movq(ToStackSlotAddress(destination), source.reg()); 1194 __ movq(ToStackSlotAddress(destination), source.reg());
1146 } 1195 }
1147 } else if (source.IsStackSlot()) { 1196 } else if (source.IsStackSlot()) {
1148 if (destination.IsRegister()) { 1197 if (destination.IsRegister()) {
1149 __ movq(destination.reg(), ToStackSlotAddress(source)); 1198 __ movq(destination.reg(), ToStackSlotAddress(source));
1150 } else { 1199 } else {
1151 ASSERT(destination.IsStackSlot()); 1200 ASSERT(destination.IsStackSlot());
1152 MoveMemoryToMemory(ToStackSlotAddress(destination), 1201 MoveMemoryToMemory(ToStackSlotAddress(destination),
1153 ToStackSlotAddress(source)); 1202 ToStackSlotAddress(source));
1154 } 1203 }
1204 } else if (source.IsXmmRegister()) {
1205 if (destination.IsXmmRegister()) {
1206 // Optimization manual recommends using MOVAPS for register
1207 // to register moves.
1208 __ movaps(destination.xmm_reg(), source.xmm_reg());
1209 } else {
1210 ASSERT(destination.IsDoubleStackSlot());
1211 __ movsd(ToStackSlotAddress(destination), source.xmm_reg());
1212 }
1213 } else if (source.IsDoubleStackSlot()) {
1214 if (destination.IsXmmRegister()) {
1215 __ movsd(destination.xmm_reg(), ToStackSlotAddress(source));
1216 } else {
1217 ASSERT(destination.IsDoubleStackSlot());
1218 __ movsd(XMM0, ToStackSlotAddress(source));
1219 __ movsd(ToStackSlotAddress(destination), XMM0);
1220 }
1155 } else { 1221 } else {
1156 ASSERT(source.IsConstant()); 1222 ASSERT(source.IsConstant());
1157 if (destination.IsRegister()) { 1223 if (destination.IsRegister()) {
1158 __ LoadObject(destination.reg(), source.constant()); 1224 __ LoadObject(destination.reg(), source.constant());
1159 } else { 1225 } else {
1160 ASSERT(destination.IsStackSlot()); 1226 ASSERT(destination.IsStackSlot());
1161 StoreObject(ToStackSlotAddress(destination), source.constant()); 1227 StoreObject(ToStackSlotAddress(destination), source.constant());
1162 } 1228 }
1163 } 1229 }
1164 1230
1165 move->Eliminate(); 1231 move->Eliminate();
1166 } 1232 }
1167 1233
1168 1234
1169 void ParallelMoveResolver::EmitSwap(int index) { 1235 void ParallelMoveResolver::EmitSwap(int index) {
1170 MoveOperands* move = moves_[index]; 1236 MoveOperands* move = moves_[index];
1171 const Location source = move->src(); 1237 const Location source = move->src();
1172 const Location destination = move->dest(); 1238 const Location destination = move->dest();
1173 1239
1174 if (source.IsRegister() && destination.IsRegister()) { 1240 if (source.IsRegister() && destination.IsRegister()) {
1175 __ xchgq(destination.reg(), source.reg()); 1241 __ xchgq(destination.reg(), source.reg());
1176 } else if (source.IsRegister() && destination.IsStackSlot()) { 1242 } else if (source.IsRegister() && destination.IsStackSlot()) {
1177 Exchange(source.reg(), ToStackSlotAddress(destination)); 1243 Exchange(source.reg(), ToStackSlotAddress(destination));
1178 } else if (source.IsStackSlot() && destination.IsRegister()) { 1244 } else if (source.IsStackSlot() && destination.IsRegister()) {
1179 Exchange(destination.reg(), ToStackSlotAddress(source)); 1245 Exchange(destination.reg(), ToStackSlotAddress(source));
1180 } else if (source.IsStackSlot() && destination.IsStackSlot()) { 1246 } else if (source.IsStackSlot() && destination.IsStackSlot()) {
1181 Exchange(ToStackSlotAddress(destination), ToStackSlotAddress(source)); 1247 Exchange(ToStackSlotAddress(destination), ToStackSlotAddress(source));
1248 } else if (source.IsXmmRegister() && destination.IsXmmRegister()) {
1249 __ movaps(XMM0, source.xmm_reg());
1250 __ movaps(source.xmm_reg(), destination.xmm_reg());
1251 __ movaps(destination.xmm_reg(), XMM0);
1252 } else if (source.IsXmmRegister() || destination.IsXmmRegister()) {
1253 ASSERT(destination.IsDoubleStackSlot() || source.IsDoubleStackSlot());
1254 XmmRegister reg = source.IsXmmRegister() ? source.xmm_reg()
1255 : destination.xmm_reg();
1256 Address slot_address =
1257 ToStackSlotAddress(source.IsXmmRegister() ? destination : source);
1258
1259 __ movsd(XMM0, slot_address);
1260 __ movsd(slot_address, reg);
1261 __ movaps(reg, XMM0);
1182 } else { 1262 } else {
1183 UNREACHABLE(); 1263 UNREACHABLE();
1184 } 1264 }
1185 1265
1186 // The swap of source and destination has executed a move from source to 1266 // The swap of source and destination has executed a move from source to
1187 // destination. 1267 // destination.
1188 move->Eliminate(); 1268 move->Eliminate();
1189 1269
1190 // Any unperformed (including pending) move with a source of either 1270 // Any unperformed (including pending) move with a source of either
1191 // this move's source or destination needs to have their source 1271 // this move's source or destination needs to have their source
(...skipping 28 matching lines...) Expand all
1220 void ParallelMoveResolver::Exchange(const Address& mem1, const Address& mem2) { 1300 void ParallelMoveResolver::Exchange(const Address& mem1, const Address& mem2) {
1221 __ Exchange(mem1, mem2); 1301 __ Exchange(mem1, mem2);
1222 } 1302 }
1223 1303
1224 1304
1225 #undef __ 1305 #undef __
1226 1306
1227 } // namespace dart 1307 } // namespace dart
1228 1308
1229 #endif // defined TARGET_ARCH_X64 1309 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_compiler_ia32.cc ('k') | runtime/vm/flow_graph_optimizer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698