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

Side by Side Diff: runtime/vm/flow_graph_compiler_ia32.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.cc ('k') | runtime/vm/flow_graph_compiler_x64.cc » ('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_IA32. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32.
6 #if defined(TARGET_ARCH_IA32) 6 #if defined(TARGET_ARCH_IA32)
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 862 matching lines...) Expand 10 before | Expand all | Expand 10 after
873 __ testl(EAX, Immediate(kSmiTagMask)); 873 __ testl(EAX, Immediate(kSmiTagMask));
874 __ j(ZERO, &smi_to_double); 874 __ j(ZERO, &smi_to_double);
875 __ CompareClassId(EAX, kDoubleCid, EBX); 875 __ CompareClassId(EAX, kDoubleCid, EBX);
876 __ j(NOT_EQUAL, &call_method); 876 __ j(NOT_EQUAL, &call_method);
877 __ movsd(XMM1, FieldAddress(EAX, Double::value_offset())); 877 __ movsd(XMM1, FieldAddress(EAX, Double::value_offset()));
878 __ Bind(&double_op); 878 __ Bind(&double_op);
879 __ sqrtsd(XMM0, XMM1); 879 __ sqrtsd(XMM0, XMM1);
880 AssemblerMacros::TryAllocate(assembler_, 880 AssemblerMacros::TryAllocate(assembler_,
881 double_class_, 881 double_class_,
882 &call_method, 882 &call_method,
883 Assembler::kNearJump,
883 EAX); // Result register. 884 EAX); // Result register.
884 __ movsd(FieldAddress(EAX, Double::value_offset()), XMM0); 885 __ movsd(FieldAddress(EAX, Double::value_offset()), XMM0);
885 __ Drop(1); 886 __ Drop(1);
886 __ jmp(done); 887 __ jmp(done);
887 __ Bind(&smi_to_double); 888 __ Bind(&smi_to_double);
888 __ SmiUntag(EAX); 889 __ SmiUntag(EAX);
889 __ cvtsi2sd(XMM1, EAX); 890 __ cvtsi2sd(XMM1, EAX);
890 __ jmp(&double_op); 891 __ jmp(&double_op);
891 __ Bind(&call_method); 892 __ Bind(&call_method);
892 } 893 }
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
1099 __ movsd(result, FieldAddress(reg, Double::value_offset())); 1100 __ movsd(result, FieldAddress(reg, Double::value_offset()));
1100 __ jmp(&done); 1101 __ jmp(&done);
1101 __ Bind(&is_smi); 1102 __ Bind(&is_smi);
1102 __ movl(temp, reg); 1103 __ movl(temp, reg);
1103 __ SmiUntag(temp); 1104 __ SmiUntag(temp);
1104 __ cvtsi2sd(result, temp); 1105 __ cvtsi2sd(result, temp);
1105 __ Bind(&done); 1106 __ Bind(&done);
1106 } 1107 }
1107 1108
1108 1109
1110 void FlowGraphCompiler::SaveLiveRegisters(LocationSummary* locs) {
1111 // TODO(vegorov): consider saving only caller save (volatile) registers.
1112 const intptr_t xmm_regs_count = locs->live_registers()->xmm_regs_count();
1113 if (xmm_regs_count > 0) {
1114 intptr_t stack_offs = (StackSize() + 1) * kWordSize;
1115 for (intptr_t reg_idx = 0; reg_idx < kNumberOfXmmRegisters; ++reg_idx) {
1116 XmmRegister xmm_reg = static_cast<XmmRegister>(reg_idx);
1117 if (locs->live_registers()->ContainsXmmRegister(xmm_reg)) {
1118 __ movsd(Address(EBP, -stack_offs), xmm_reg);
1119 stack_offs += kDoubleSize;
1120 }
1121 }
1122 }
1123
1124 for (intptr_t reg_idx = 0; reg_idx < kNumberOfCpuRegisters; ++reg_idx) {
1125 Register reg = static_cast<Register>(reg_idx);
1126 if (locs->live_registers()->ContainsRegister(reg)) {
1127 __ pushl(reg);
1128 }
1129 }
1130 }
1131
1132
1133 void FlowGraphCompiler::RestoreLiveRegisters(LocationSummary* locs) {
1134 for (intptr_t reg_idx = kNumberOfCpuRegisters - 1; reg_idx >= 0; --reg_idx) {
1135 Register reg = static_cast<Register>(reg_idx);
1136 if (locs->live_registers()->ContainsRegister(reg)) {
1137 __ popl(reg);
1138 }
1139 }
1140
1141 const intptr_t xmm_regs_count = locs->live_registers()->xmm_regs_count();
1142 if (xmm_regs_count > 0) {
1143 intptr_t stack_offs = (StackSize() + 1) * kWordSize;
1144 for (intptr_t reg_idx = 0; reg_idx < kNumberOfXmmRegisters; ++reg_idx) {
1145 XmmRegister xmm_reg = static_cast<XmmRegister>(reg_idx);
1146 if (locs->live_registers()->ContainsXmmRegister(xmm_reg)) {
1147 __ movsd(xmm_reg, Address(EBP, -stack_offs));
1148 stack_offs += kDoubleSize;
1149 }
1150 }
1151 }
1152 }
1153
1154
1109 #undef __ 1155 #undef __
1110 #define __ compiler_->assembler()-> 1156 #define __ compiler_->assembler()->
1111 1157
1112 1158
1113 static Address ToStackSlotAddress(Location loc) { 1159 static Address ToStackSlotAddress(Location loc) {
1114 ASSERT(loc.IsStackSlot());
1115 const intptr_t index = loc.stack_index(); 1160 const intptr_t index = loc.stack_index();
1116 if (index < 0) { 1161 if (index < 0) {
1117 const intptr_t offset = (1 - index) * kWordSize; 1162 const intptr_t offset = (1 - index) * kWordSize;
1118 return Address(EBP, offset); 1163 return Address(EBP, offset);
1119 } else { 1164 } else {
1120 const intptr_t offset = 1165 const intptr_t offset =
1121 (ParsedFunction::kFirstLocalSlotIndex - index) * kWordSize; 1166 (ParsedFunction::kFirstLocalSlotIndex - index) * kWordSize;
1122 return Address(EBP, offset); 1167 return Address(EBP, offset);
1123 } 1168 }
1124 } 1169 }
(...skipping 12 matching lines...) Expand all
1137 __ movl(ToStackSlotAddress(destination), source.reg()); 1182 __ movl(ToStackSlotAddress(destination), source.reg());
1138 } 1183 }
1139 } else if (source.IsStackSlot()) { 1184 } else if (source.IsStackSlot()) {
1140 if (destination.IsRegister()) { 1185 if (destination.IsRegister()) {
1141 __ movl(destination.reg(), ToStackSlotAddress(source)); 1186 __ movl(destination.reg(), ToStackSlotAddress(source));
1142 } else { 1187 } else {
1143 ASSERT(destination.IsStackSlot()); 1188 ASSERT(destination.IsStackSlot());
1144 MoveMemoryToMemory(ToStackSlotAddress(destination), 1189 MoveMemoryToMemory(ToStackSlotAddress(destination),
1145 ToStackSlotAddress(source)); 1190 ToStackSlotAddress(source));
1146 } 1191 }
1192 } else if (source.IsXmmRegister()) {
1193 if (destination.IsXmmRegister()) {
1194 // Optimization manual recommends using MOVAPS for register
1195 // to register moves.
1196 __ movaps(destination.xmm_reg(), source.xmm_reg());
1197 } else {
1198 ASSERT(destination.IsDoubleStackSlot());
1199 __ movsd(ToStackSlotAddress(destination), source.xmm_reg());
1200 }
1201 } else if (source.IsDoubleStackSlot()) {
1202 if (destination.IsXmmRegister()) {
1203 __ movsd(destination.xmm_reg(), ToStackSlotAddress(source));
1204 } else {
1205 ASSERT(destination.IsDoubleStackSlot());
1206 __ movsd(XMM0, ToStackSlotAddress(source));
1207 __ movsd(ToStackSlotAddress(destination), XMM0);
1208 }
1147 } else { 1209 } else {
1148 ASSERT(source.IsConstant()); 1210 ASSERT(source.IsConstant());
1149 if (destination.IsRegister()) { 1211 if (destination.IsRegister()) {
1150 __ LoadObject(destination.reg(), source.constant()); 1212 __ LoadObject(destination.reg(), source.constant());
1151 } else { 1213 } else {
1152 ASSERT(destination.IsStackSlot()); 1214 ASSERT(destination.IsStackSlot());
1153 StoreObject(ToStackSlotAddress(destination), source.constant()); 1215 StoreObject(ToStackSlotAddress(destination), source.constant());
1154 } 1216 }
1155 } 1217 }
1156 1218
1157 move->Eliminate(); 1219 move->Eliminate();
1158 } 1220 }
1159 1221
1160 1222
1161 void ParallelMoveResolver::EmitSwap(int index) { 1223 void ParallelMoveResolver::EmitSwap(int index) {
1162 MoveOperands* move = moves_[index]; 1224 MoveOperands* move = moves_[index];
1163 const Location source = move->src(); 1225 const Location source = move->src();
1164 const Location destination = move->dest(); 1226 const Location destination = move->dest();
1165 1227
1166 if (source.IsRegister() && destination.IsRegister()) { 1228 if (source.IsRegister() && destination.IsRegister()) {
1167 __ xchgl(destination.reg(), source.reg()); 1229 __ xchgl(destination.reg(), source.reg());
1168 } else if (source.IsRegister() && destination.IsStackSlot()) { 1230 } else if (source.IsRegister() && destination.IsStackSlot()) {
1169 Exchange(source.reg(), ToStackSlotAddress(destination)); 1231 Exchange(source.reg(), ToStackSlotAddress(destination));
1170 } else if (source.IsStackSlot() && destination.IsRegister()) { 1232 } else if (source.IsStackSlot() && destination.IsRegister()) {
1171 Exchange(destination.reg(), ToStackSlotAddress(source)); 1233 Exchange(destination.reg(), ToStackSlotAddress(source));
1172 } else if (source.IsStackSlot() && destination.IsStackSlot()) { 1234 } else if (source.IsStackSlot() && destination.IsStackSlot()) {
1173 Exchange(ToStackSlotAddress(destination), ToStackSlotAddress(source)); 1235 Exchange(ToStackSlotAddress(destination), ToStackSlotAddress(source));
1236 } else if (source.IsXmmRegister() && destination.IsXmmRegister()) {
1237 __ movaps(XMM0, source.xmm_reg());
1238 __ movaps(source.xmm_reg(), destination.xmm_reg());
1239 __ movaps(destination.xmm_reg(), XMM0);
1240 } else if (source.IsXmmRegister() || destination.IsXmmRegister()) {
1241 ASSERT(destination.IsDoubleStackSlot() || source.IsDoubleStackSlot());
1242 XmmRegister reg = source.IsXmmRegister() ? source.xmm_reg()
1243 : destination.xmm_reg();
1244 Address slot_address =
1245 ToStackSlotAddress(source.IsXmmRegister() ? destination : source);
1246
1247 __ movsd(XMM0, slot_address);
1248 __ movsd(slot_address, reg);
1249 __ movaps(reg, XMM0);
1174 } else { 1250 } else {
1175 UNREACHABLE(); 1251 UNREACHABLE();
1176 } 1252 }
1177 1253
1178 // The swap of source and destination has executed a move from source to 1254 // The swap of source and destination has executed a move from source to
1179 // destination. 1255 // destination.
1180 move->Eliminate(); 1256 move->Eliminate();
1181 1257
1182 // Any unperformed (including pending) move with a source of either 1258 // Any unperformed (including pending) move with a source of either
1183 // this move's source or destination needs to have their source 1259 // this move's source or destination needs to have their source
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1234 __ popl(ECX); 1310 __ popl(ECX);
1235 __ popl(EAX); 1311 __ popl(EAX);
1236 } 1312 }
1237 1313
1238 1314
1239 #undef __ 1315 #undef __
1240 1316
1241 } // namespace dart 1317 } // namespace dart
1242 1318
1243 #endif // defined TARGET_ARCH_IA32 1319 #endif // defined TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_compiler.cc ('k') | runtime/vm/flow_graph_compiler_x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698