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 |