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

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: 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
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 846 matching lines...) Expand 10 before | Expand all | Expand 10 after
857 __ testl(EAX, Immediate(kSmiTagMask)); 857 __ testl(EAX, Immediate(kSmiTagMask));
858 __ j(ZERO, &smi_to_double); 858 __ j(ZERO, &smi_to_double);
859 __ CompareClassId(EAX, kDoubleCid, EBX); 859 __ CompareClassId(EAX, kDoubleCid, EBX);
860 __ j(NOT_EQUAL, &call_method); 860 __ j(NOT_EQUAL, &call_method);
861 __ movsd(XMM1, FieldAddress(EAX, Double::value_offset())); 861 __ movsd(XMM1, FieldAddress(EAX, Double::value_offset()));
862 __ Bind(&double_op); 862 __ Bind(&double_op);
863 __ sqrtsd(XMM0, XMM1); 863 __ sqrtsd(XMM0, XMM1);
864 AssemblerMacros::TryAllocate(assembler_, 864 AssemblerMacros::TryAllocate(assembler_,
865 double_class_, 865 double_class_,
866 &call_method, 866 &call_method,
867 Assembler::kNearJump,
867 EAX); // Result register. 868 EAX); // Result register.
868 __ movsd(FieldAddress(EAX, Double::value_offset()), XMM0); 869 __ movsd(FieldAddress(EAX, Double::value_offset()), XMM0);
869 __ Drop(1); 870 __ Drop(1);
870 __ jmp(done); 871 __ jmp(done);
871 __ Bind(&smi_to_double); 872 __ Bind(&smi_to_double);
872 __ SmiUntag(EAX); 873 __ SmiUntag(EAX);
873 __ cvtsi2sd(XMM1, EAX); 874 __ cvtsi2sd(XMM1, EAX);
874 __ jmp(&double_op); 875 __ jmp(&double_op);
875 __ Bind(&call_method); 876 __ Bind(&call_method);
876 } 877 }
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
1079 __ movsd(result, FieldAddress(reg, Double::value_offset())); 1080 __ movsd(result, FieldAddress(reg, Double::value_offset()));
1080 __ jmp(&done); 1081 __ jmp(&done);
1081 __ Bind(&is_smi); 1082 __ Bind(&is_smi);
1082 __ movl(temp, reg); 1083 __ movl(temp, reg);
1083 __ SmiUntag(temp); 1084 __ SmiUntag(temp);
1084 __ cvtsi2sd(result, temp); 1085 __ cvtsi2sd(result, temp);
1085 __ Bind(&done); 1086 __ Bind(&done);
1086 } 1087 }
1087 1088
1088 1089
1090 void FlowGraphCompiler::SaveLiveRegisters(LocationSummary* locs) {
1091 // TODO(vegorov): consider saving only caller save (volatile) registers.
1092 const intptr_t xmm_regs_count = locs->live_registers()->xmm_regs_count();
1093 if (xmm_regs_count > 0) {
1094 intptr_t stack_offs = (StackSize() + 1) * kWordSize;
1095 for (intptr_t reg_idx = 0; reg_idx < kNumberOfXmmRegisters; ++reg_idx) {
1096 XmmRegister xmm_reg = static_cast<XmmRegister>(reg_idx);
1097 if (locs->live_registers()->ContainsXmmRegister(xmm_reg)) {
1098 __ movsd(Address(EBP, -stack_offs), xmm_reg);
1099 stack_offs += kDoubleSize;
1100 }
1101 }
1102 }
1103
1104 for (intptr_t reg_idx = 0; reg_idx < kNumberOfCpuRegisters; ++reg_idx) {
1105 Register reg = static_cast<Register>(reg_idx);
1106 if (locs->live_registers()->ContainsRegister(reg)) {
1107 __ pushl(reg);
1108 }
1109 }
1110 }
1111
1112
1113 void FlowGraphCompiler::RestoreLiveRegisters(LocationSummary* locs) {
1114 for (intptr_t reg_idx = kNumberOfCpuRegisters - 1; reg_idx >= 0; --reg_idx) {
1115 Register reg = static_cast<Register>(reg_idx);
1116 if (locs->live_registers()->ContainsRegister(reg)) {
1117 __ popl(reg);
1118 }
1119 }
1120
1121 const intptr_t xmm_regs_count = locs->live_registers()->xmm_regs_count();
1122 if (xmm_regs_count > 0) {
1123 intptr_t stack_offs = (StackSize() + 1) * kWordSize;
1124 for (intptr_t reg_idx = 0; reg_idx < kNumberOfXmmRegisters; ++reg_idx) {
1125 XmmRegister xmm_reg = static_cast<XmmRegister>(reg_idx);
1126 if (locs->live_registers()->ContainsXmmRegister(xmm_reg)) {
1127 __ movsd(xmm_reg, Address(EBP, -stack_offs));
1128 stack_offs += kDoubleSize;
1129 }
1130 }
1131 }
1132 }
1133
1134
1089 #undef __ 1135 #undef __
1090 #define __ compiler_->assembler()-> 1136 #define __ compiler_->assembler()->
1091 1137
1092 1138
1093 static Address ToStackSlotAddress(Location loc) { 1139 static Address ToStackSlotAddress(Location loc) {
1094 ASSERT(loc.IsStackSlot());
1095 const intptr_t index = loc.stack_index(); 1140 const intptr_t index = loc.stack_index();
1096 if (index < 0) { 1141 if (index < 0) {
1097 const intptr_t offset = (1 - index) * kWordSize; 1142 const intptr_t offset = (1 - index) * kWordSize;
1098 return Address(EBP, offset); 1143 return Address(EBP, offset);
1099 } else { 1144 } else {
1100 const intptr_t offset = 1145 const intptr_t offset =
1101 (ParsedFunction::kFirstLocalSlotIndex - index) * kWordSize; 1146 (ParsedFunction::kFirstLocalSlotIndex - index) * kWordSize;
1102 return Address(EBP, offset); 1147 return Address(EBP, offset);
1103 } 1148 }
1104 } 1149 }
(...skipping 12 matching lines...) Expand all
1117 __ movl(ToStackSlotAddress(destination), source.reg()); 1162 __ movl(ToStackSlotAddress(destination), source.reg());
1118 } 1163 }
1119 } else if (source.IsStackSlot()) { 1164 } else if (source.IsStackSlot()) {
1120 if (destination.IsRegister()) { 1165 if (destination.IsRegister()) {
1121 __ movl(destination.reg(), ToStackSlotAddress(source)); 1166 __ movl(destination.reg(), ToStackSlotAddress(source));
1122 } else { 1167 } else {
1123 ASSERT(destination.IsStackSlot()); 1168 ASSERT(destination.IsStackSlot());
1124 MoveMemoryToMemory(ToStackSlotAddress(destination), 1169 MoveMemoryToMemory(ToStackSlotAddress(destination),
1125 ToStackSlotAddress(source)); 1170 ToStackSlotAddress(source));
1126 } 1171 }
1172 } else if (source.IsXmmRegister()) {
1173 if (destination.IsXmmRegister()) {
1174 // Optimization manual recommends using MOVAPS for register
1175 // to register moves.
1176 __ movaps(destination.xmm_reg(), source.xmm_reg());
1177 } else {
1178 ASSERT(destination.IsDoubleStackSlot());
1179 __ movsd(ToStackSlotAddress(destination), source.xmm_reg());
1180 }
1181 } else if (source.IsDoubleStackSlot()) {
1182 if (destination.IsXmmRegister()) {
1183 __ movsd(destination.xmm_reg(), ToStackSlotAddress(source));
1184 } else {
1185 ASSERT(destination.IsDoubleStackSlot());
1186 __ movsd(XMM0, ToStackSlotAddress(source));
1187 __ movsd(ToStackSlotAddress(destination), XMM0);
1188 }
1127 } else { 1189 } else {
1128 ASSERT(source.IsConstant()); 1190 ASSERT(source.IsConstant());
1129 if (destination.IsRegister()) { 1191 if (destination.IsRegister()) {
1130 __ LoadObject(destination.reg(), source.constant()); 1192 __ LoadObject(destination.reg(), source.constant());
1131 } else { 1193 } else {
1132 ASSERT(destination.IsStackSlot()); 1194 ASSERT(destination.IsStackSlot());
1133 StoreObject(ToStackSlotAddress(destination), source.constant()); 1195 StoreObject(ToStackSlotAddress(destination), source.constant());
1134 } 1196 }
1135 } 1197 }
1136 1198
1137 move->Eliminate(); 1199 move->Eliminate();
1138 } 1200 }
1139 1201
1140 1202
1141 void ParallelMoveResolver::EmitSwap(int index) { 1203 void ParallelMoveResolver::EmitSwap(int index) {
1142 MoveOperands* move = moves_[index]; 1204 MoveOperands* move = moves_[index];
1143 const Location source = move->src(); 1205 const Location source = move->src();
1144 const Location destination = move->dest(); 1206 const Location destination = move->dest();
1145 1207
1146 if (source.IsRegister() && destination.IsRegister()) { 1208 if (source.IsRegister() && destination.IsRegister()) {
1147 __ xchgl(destination.reg(), source.reg()); 1209 __ xchgl(destination.reg(), source.reg());
1148 } else if (source.IsRegister() && destination.IsStackSlot()) { 1210 } else if (source.IsRegister() && destination.IsStackSlot()) {
1149 Exchange(source.reg(), ToStackSlotAddress(destination)); 1211 Exchange(source.reg(), ToStackSlotAddress(destination));
1150 } else if (source.IsStackSlot() && destination.IsRegister()) { 1212 } else if (source.IsStackSlot() && destination.IsRegister()) {
1151 Exchange(destination.reg(), ToStackSlotAddress(source)); 1213 Exchange(destination.reg(), ToStackSlotAddress(source));
1152 } else if (source.IsStackSlot() && destination.IsStackSlot()) { 1214 } else if (source.IsStackSlot() && destination.IsStackSlot()) {
1153 Exchange(ToStackSlotAddress(destination), ToStackSlotAddress(source)); 1215 Exchange(ToStackSlotAddress(destination), ToStackSlotAddress(source));
1216 } else if (source.IsXmmRegister() && destination.IsXmmRegister()) {
1217 __ movaps(XMM0, source.xmm_reg());
1218 __ movaps(source.xmm_reg(), destination.xmm_reg());
1219 __ movaps(destination.xmm_reg(), XMM0);
1220 } else if (source.IsXmmRegister() || destination.IsXmmRegister()) {
1221 ASSERT(destination.IsDoubleStackSlot() || source.IsDoubleStackSlot());
1222 XmmRegister reg = source.IsXmmRegister() ? source.xmm_reg()
1223 : destination.xmm_reg();
1224 Address slot_address =
1225 ToStackSlotAddress(source.IsXmmRegister() ? destination : source);
1226
1227 __ movsd(XMM0, slot_address);
1228 __ movsd(slot_address, reg);
1229 __ movaps(reg, XMM0);
1154 } else { 1230 } else {
1155 UNREACHABLE(); 1231 UNREACHABLE();
1156 } 1232 }
1157 1233
1158 // The swap of source and destination has executed a move from source to 1234 // The swap of source and destination has executed a move from source to
1159 // destination. 1235 // destination.
1160 move->Eliminate(); 1236 move->Eliminate();
1161 1237
1162 // Any unperformed (including pending) move with a source of either 1238 // Any unperformed (including pending) move with a source of either
1163 // this move's source or destination needs to have their source 1239 // this move's source or destination needs to have their source
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1214 __ popl(ECX); 1290 __ popl(ECX);
1215 __ popl(EAX); 1291 __ popl(EAX);
1216 } 1292 }
1217 1293
1218 1294
1219 #undef __ 1295 #undef __
1220 1296
1221 } // namespace dart 1297 } // namespace dart
1222 1298
1223 #endif // defined TARGET_ARCH_IA32 1299 #endif // defined TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698