Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 1091 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1102 __ SmiUntag(temp); | 1102 __ SmiUntag(temp); |
| 1103 __ cvtsi2sd(result, temp); | 1103 __ cvtsi2sd(result, temp); |
| 1104 __ Bind(&done); | 1104 __ Bind(&done); |
| 1105 } | 1105 } |
| 1106 | 1106 |
| 1107 | 1107 |
| 1108 #undef __ | 1108 #undef __ |
| 1109 #define __ compiler_->assembler()-> | 1109 #define __ compiler_->assembler()-> |
| 1110 | 1110 |
| 1111 | 1111 |
| 1112 static Address ToAddress(Location loc) { | |
|
srdjan
2012/07/23 16:18:59
The name is to generic: s/ToAddress/ToSpillAddress
| |
| 1113 ASSERT(loc.IsSpillSlot()); | |
| 1114 const intptr_t offset = | |
| 1115 (ParsedFunction::kFirstLocalSlotIndex - loc.spill_index()) * kWordSize; | |
| 1116 return Address(EBP, offset); | |
| 1117 } | |
| 1118 | |
| 1119 | |
| 1112 void ParallelMoveResolver::EmitMove(int index) { | 1120 void ParallelMoveResolver::EmitMove(int index) { |
| 1113 MoveOperands* move = moves_[index]; | 1121 MoveOperands* move = moves_[index]; |
| 1114 const Location source = move->src(); | 1122 const Location source = move->src(); |
| 1115 const Location destination = move->dest(); | 1123 const Location destination = move->dest(); |
| 1116 | 1124 |
| 1117 ASSERT(destination.IsRegister()); | |
| 1118 if (source.IsRegister()) { | 1125 if (source.IsRegister()) { |
| 1119 __ movl(destination.reg(), source.reg()); | 1126 if (destination.IsRegister()) { |
| 1127 __ movl(destination.reg(), source.reg()); | |
| 1128 } else { | |
| 1129 ASSERT(destination.IsSpillSlot()); | |
| 1130 __ movl(ToAddress(destination), source.reg()); | |
| 1131 } | |
| 1132 } else if (source.IsSpillSlot()) { | |
| 1133 if (destination.IsRegister()) { | |
| 1134 __ movl(destination.reg(), ToAddress(source)); | |
| 1135 } else { | |
| 1136 ASSERT(destination.IsSpillSlot()); | |
| 1137 // TODO(vegorov): allocate temporary register for such moves. | |
| 1138 __ pushl(EAX); | |
| 1139 __ movl(EAX, ToAddress(source)); | |
| 1140 __ movl(ToAddress(destination), EAX); | |
| 1141 __ popl(EAX); | |
| 1142 } | |
| 1120 } else { | 1143 } else { |
| 1121 ASSERT(source.IsConstant()); | 1144 ASSERT(source.IsConstant()); |
| 1122 __ LoadObject(destination.reg(), source.constant()); | 1145 if (destination.IsRegister()) { |
| 1146 __ LoadObject(destination.reg(), source.constant()); | |
| 1147 } else { | |
| 1148 ASSERT(destination.IsSpillSlot()); | |
| 1149 // TODO(vegorov): allocate temporary register for such moves. | |
| 1150 __ pushl(EAX); | |
| 1151 __ LoadObject(EAX, source.constant()); | |
| 1152 __ movl(ToAddress(destination), EAX); | |
| 1153 __ popl(EAX); | |
| 1154 } | |
| 1123 } | 1155 } |
| 1156 | |
| 1124 move->Eliminate(); | 1157 move->Eliminate(); |
| 1125 } | 1158 } |
| 1126 | 1159 |
| 1127 | 1160 |
| 1128 void ParallelMoveResolver::EmitSwap(int index) { | 1161 void ParallelMoveResolver::EmitSwap(int index) { |
| 1129 MoveOperands* move = moves_[index]; | 1162 MoveOperands* move = moves_[index]; |
| 1130 const Location source = move->src(); | 1163 const Location source = move->src(); |
| 1131 const Location destination = move->dest(); | 1164 const Location destination = move->dest(); |
| 1132 | 1165 |
| 1133 ASSERT(source.IsRegister() && destination.IsRegister()); | 1166 if (source.IsRegister() && destination.IsRegister()) { |
| 1134 __ xchgl(destination.reg(), source.reg()); | 1167 __ xchgl(destination.reg(), source.reg()); |
| 1168 } else if (source.IsRegister() && destination.IsSpillSlot()) { | |
| 1169 // TODO(vegorov): allocate temporary register for such moves. | |
| 1170 Register scratch = (source.reg() == EAX) ? ECX : EAX; | |
| 1171 __ pushl(scratch); | |
| 1172 __ movl(scratch, ToAddress(destination)); | |
| 1173 __ xchgl(scratch, source.reg()); | |
| 1174 __ movl(ToAddress(destination), scratch); | |
| 1175 __ popl(scratch); | |
| 1176 } else if (source.IsSpillSlot() && destination.IsRegister()) { | |
| 1177 // TODO(vegorov): allocate temporary register for such moves. | |
| 1178 Register scratch = (destination.reg() == EAX) ? ECX : EAX; | |
| 1179 __ pushl(scratch); | |
| 1180 __ movl(scratch, ToAddress(source)); | |
| 1181 __ xchgl(scratch, destination.reg()); | |
| 1182 __ movl(ToAddress(source), scratch); | |
| 1183 __ popl(scratch); | |
| 1184 } else if (source.IsSpillSlot() && destination.IsSpillSlot()) { | |
| 1185 // TODO(vegorov): allocate temporary registers for such moves. | |
| 1186 __ pushl(EAX); | |
| 1187 __ pushl(ECX); | |
| 1188 __ movl(EAX, ToAddress(source)); | |
|
Kevin Millikin (Google)
2012/07/23 12:52:30
This code would be much nicer if there were helper
Vyacheslav Egorov (Google)
2012/07/23 14:06:10
Done. But it looks a bit ugly because on x64 only
| |
| 1189 __ movl(ECX, ToAddress(destination)); | |
|
srdjan
2012/07/23 16:18:59
Please upload the latest CL once comments are addr
| |
| 1190 __ movl(ToAddress(source), ECX); | |
| 1191 __ movl(ToAddress(destination), EAX); | |
| 1192 __ popl(ECX); | |
| 1193 __ popl(EAX); | |
| 1194 } else { | |
| 1195 UNREACHABLE(); | |
| 1196 } | |
| 1135 | 1197 |
| 1136 // The swap of source and destination has executed a move from source to | 1198 // The swap of source and destination has executed a move from source to |
| 1137 // destination. | 1199 // destination. |
| 1138 move->Eliminate(); | 1200 move->Eliminate(); |
| 1139 | 1201 |
| 1140 // Any unperformed (including pending) move with a source of either | 1202 // Any unperformed (including pending) move with a source of either |
| 1141 // this move's source or destination needs to have their source | 1203 // this move's source or destination needs to have their source |
| 1142 // changed to reflect the state of affairs after the swap. | 1204 // changed to reflect the state of affairs after the swap. |
| 1143 for (int i = 0; i < moves_.length(); ++i) { | 1205 for (int i = 0; i < moves_.length(); ++i) { |
| 1144 const MoveOperands& other_move = *moves_[i]; | 1206 const MoveOperands& other_move = *moves_[i]; |
| 1145 if (other_move.Blocks(source)) { | 1207 if (other_move.Blocks(source)) { |
| 1146 moves_[i]->set_src(destination); | 1208 moves_[i]->set_src(destination); |
| 1147 } else if (other_move.Blocks(destination)) { | 1209 } else if (other_move.Blocks(destination)) { |
| 1148 moves_[i]->set_src(source); | 1210 moves_[i]->set_src(source); |
| 1149 } | 1211 } |
| 1150 } | 1212 } |
| 1151 } | 1213 } |
| 1152 | 1214 |
| 1153 | 1215 |
| 1154 #undef __ | 1216 #undef __ |
| 1155 | 1217 |
| 1156 } // namespace dart | 1218 } // namespace dart |
| 1157 | 1219 |
| 1158 #endif // defined TARGET_ARCH_IA32 | 1220 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |