| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <stdarg.h> | 5 #include <stdarg.h> |
| 6 #include <stdlib.h> | 6 #include <stdlib.h> |
| 7 #include <cmath> | 7 #include <cmath> |
| 8 | 8 |
| 9 #if V8_TARGET_ARCH_ARM | 9 #if V8_TARGET_ARCH_ARM |
| 10 | 10 |
| (...skipping 1089 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1100 | 1100 |
| 1101 | 1101 |
| 1102 void Simulator::TrashCallerSaveRegisters() { | 1102 void Simulator::TrashCallerSaveRegisters() { |
| 1103 // We don't trash the registers with the return value. | 1103 // We don't trash the registers with the return value. |
| 1104 registers_[2] = 0x50Bad4U; | 1104 registers_[2] = 0x50Bad4U; |
| 1105 registers_[3] = 0x50Bad4U; | 1105 registers_[3] = 0x50Bad4U; |
| 1106 registers_[12] = 0x50Bad4U; | 1106 registers_[12] = 0x50Bad4U; |
| 1107 } | 1107 } |
| 1108 | 1108 |
| 1109 | 1109 |
| 1110 // Some Operating Systems allow unaligned access on ARMv7 targets. We | |
| 1111 // assume that unaligned accesses are not allowed unless the v8 build system | |
| 1112 // defines the CAN_USE_UNALIGNED_ACCESSES macro to be non-zero. | |
| 1113 // The following statements below describes the behavior of the ARM CPUs | |
| 1114 // that don't support unaligned access. | |
| 1115 // Some ARM platforms raise an interrupt on detecting unaligned access. | |
| 1116 // On others it does a funky rotation thing. For now we | |
| 1117 // simply disallow unaligned reads. Note that simulator runs have the runtime | |
| 1118 // system running directly on the host system and only generated code is | |
| 1119 // executed in the simulator. Since the host is typically IA32 we will not | |
| 1120 // get the correct ARM-like behaviour on unaligned accesses for those ARM | |
| 1121 // targets that don't support unaligned loads and stores. | |
| 1122 | |
| 1123 | |
| 1124 int Simulator::ReadW(int32_t addr, Instruction* instr) { | 1110 int Simulator::ReadW(int32_t addr, Instruction* instr) { |
| 1125 if (FLAG_enable_unaligned_accesses || (addr & 3) == 0) { | 1111 // All supported ARM targets allow unaligned accesses, so we don't need to |
| 1126 intptr_t* ptr = reinterpret_cast<intptr_t*>(addr); | 1112 // check the alignment here. |
| 1127 return *ptr; | 1113 intptr_t* ptr = reinterpret_cast<intptr_t*>(addr); |
| 1128 } else { | 1114 return *ptr; |
| 1129 PrintF("Unaligned read at 0x%08x, pc=0x%08" V8PRIxPTR "\n", | |
| 1130 addr, | |
| 1131 reinterpret_cast<intptr_t>(instr)); | |
| 1132 UNIMPLEMENTED(); | |
| 1133 return 0; | |
| 1134 } | |
| 1135 } | 1115 } |
| 1136 | 1116 |
| 1137 | 1117 |
| 1138 void Simulator::WriteW(int32_t addr, int value, Instruction* instr) { | 1118 void Simulator::WriteW(int32_t addr, int value, Instruction* instr) { |
| 1139 if (FLAG_enable_unaligned_accesses || (addr & 3) == 0) { | 1119 // All supported ARM targets allow unaligned accesses, so we don't need to |
| 1140 intptr_t* ptr = reinterpret_cast<intptr_t*>(addr); | 1120 // check the alignment here. |
| 1141 *ptr = value; | 1121 intptr_t* ptr = reinterpret_cast<intptr_t*>(addr); |
| 1142 } else { | 1122 *ptr = value; |
| 1143 PrintF("Unaligned write at 0x%08x, pc=0x%08" V8PRIxPTR "\n", | |
| 1144 addr, | |
| 1145 reinterpret_cast<intptr_t>(instr)); | |
| 1146 UNIMPLEMENTED(); | |
| 1147 } | |
| 1148 } | 1123 } |
| 1149 | 1124 |
| 1150 | 1125 |
| 1151 uint16_t Simulator::ReadHU(int32_t addr, Instruction* instr) { | 1126 uint16_t Simulator::ReadHU(int32_t addr, Instruction* instr) { |
| 1152 if (FLAG_enable_unaligned_accesses || (addr & 1) == 0) { | 1127 // All supported ARM targets allow unaligned accesses, so we don't need to |
| 1153 uint16_t* ptr = reinterpret_cast<uint16_t*>(addr); | 1128 // check the alignment here. |
| 1154 return *ptr; | 1129 uint16_t* ptr = reinterpret_cast<uint16_t*>(addr); |
| 1155 } else { | 1130 return *ptr; |
| 1156 PrintF("Unaligned unsigned halfword read at 0x%08x, pc=0x%08" | |
| 1157 V8PRIxPTR "\n", | |
| 1158 addr, | |
| 1159 reinterpret_cast<intptr_t>(instr)); | |
| 1160 UNIMPLEMENTED(); | |
| 1161 return 0; | |
| 1162 } | |
| 1163 } | 1131 } |
| 1164 | 1132 |
| 1165 | 1133 |
| 1166 int16_t Simulator::ReadH(int32_t addr, Instruction* instr) { | 1134 int16_t Simulator::ReadH(int32_t addr, Instruction* instr) { |
| 1167 if (FLAG_enable_unaligned_accesses || (addr & 1) == 0) { | 1135 // All supported ARM targets allow unaligned accesses, so we don't need to |
| 1168 int16_t* ptr = reinterpret_cast<int16_t*>(addr); | 1136 // check the alignment here. |
| 1169 return *ptr; | 1137 int16_t* ptr = reinterpret_cast<int16_t*>(addr); |
| 1170 } else { | 1138 return *ptr; |
| 1171 PrintF("Unaligned signed halfword read at 0x%08x\n", addr); | |
| 1172 UNIMPLEMENTED(); | |
| 1173 return 0; | |
| 1174 } | |
| 1175 } | 1139 } |
| 1176 | 1140 |
| 1177 | 1141 |
| 1178 void Simulator::WriteH(int32_t addr, uint16_t value, Instruction* instr) { | 1142 void Simulator::WriteH(int32_t addr, uint16_t value, Instruction* instr) { |
| 1179 if (FLAG_enable_unaligned_accesses || (addr & 1) == 0) { | 1143 // All supported ARM targets allow unaligned accesses, so we don't need to |
| 1180 uint16_t* ptr = reinterpret_cast<uint16_t*>(addr); | 1144 // check the alignment here. |
| 1181 *ptr = value; | 1145 uint16_t* ptr = reinterpret_cast<uint16_t*>(addr); |
| 1182 } else { | 1146 *ptr = value; |
| 1183 PrintF("Unaligned unsigned halfword write at 0x%08x, pc=0x%08" | |
| 1184 V8PRIxPTR "\n", | |
| 1185 addr, | |
| 1186 reinterpret_cast<intptr_t>(instr)); | |
| 1187 UNIMPLEMENTED(); | |
| 1188 } | |
| 1189 } | 1147 } |
| 1190 | 1148 |
| 1191 | 1149 |
| 1192 void Simulator::WriteH(int32_t addr, int16_t value, Instruction* instr) { | 1150 void Simulator::WriteH(int32_t addr, int16_t value, Instruction* instr) { |
| 1193 if (FLAG_enable_unaligned_accesses || (addr & 1) == 0) { | 1151 // All supported ARM targets allow unaligned accesses, so we don't need to |
| 1194 int16_t* ptr = reinterpret_cast<int16_t*>(addr); | 1152 // check the alignment here. |
| 1195 *ptr = value; | 1153 int16_t* ptr = reinterpret_cast<int16_t*>(addr); |
| 1196 } else { | 1154 *ptr = value; |
| 1197 PrintF("Unaligned halfword write at 0x%08x, pc=0x%08" V8PRIxPTR "\n", | |
| 1198 addr, | |
| 1199 reinterpret_cast<intptr_t>(instr)); | |
| 1200 UNIMPLEMENTED(); | |
| 1201 } | |
| 1202 } | 1155 } |
| 1203 | 1156 |
| 1204 | 1157 |
| 1205 uint8_t Simulator::ReadBU(int32_t addr) { | 1158 uint8_t Simulator::ReadBU(int32_t addr) { |
| 1206 uint8_t* ptr = reinterpret_cast<uint8_t*>(addr); | 1159 uint8_t* ptr = reinterpret_cast<uint8_t*>(addr); |
| 1207 return *ptr; | 1160 return *ptr; |
| 1208 } | 1161 } |
| 1209 | 1162 |
| 1210 | 1163 |
| 1211 int8_t Simulator::ReadB(int32_t addr) { | 1164 int8_t Simulator::ReadB(int32_t addr) { |
| 1212 int8_t* ptr = reinterpret_cast<int8_t*>(addr); | 1165 int8_t* ptr = reinterpret_cast<int8_t*>(addr); |
| 1213 return *ptr; | 1166 return *ptr; |
| 1214 } | 1167 } |
| 1215 | 1168 |
| 1216 | 1169 |
| 1217 void Simulator::WriteB(int32_t addr, uint8_t value) { | 1170 void Simulator::WriteB(int32_t addr, uint8_t value) { |
| 1218 uint8_t* ptr = reinterpret_cast<uint8_t*>(addr); | 1171 uint8_t* ptr = reinterpret_cast<uint8_t*>(addr); |
| 1219 *ptr = value; | 1172 *ptr = value; |
| 1220 } | 1173 } |
| 1221 | 1174 |
| 1222 | 1175 |
| 1223 void Simulator::WriteB(int32_t addr, int8_t value) { | 1176 void Simulator::WriteB(int32_t addr, int8_t value) { |
| 1224 int8_t* ptr = reinterpret_cast<int8_t*>(addr); | 1177 int8_t* ptr = reinterpret_cast<int8_t*>(addr); |
| 1225 *ptr = value; | 1178 *ptr = value; |
| 1226 } | 1179 } |
| 1227 | 1180 |
| 1228 | 1181 |
| 1229 int32_t* Simulator::ReadDW(int32_t addr) { | 1182 int32_t* Simulator::ReadDW(int32_t addr) { |
| 1230 if (FLAG_enable_unaligned_accesses || (addr & 3) == 0) { | 1183 // All supported ARM targets allow unaligned accesses, so we don't need to |
| 1231 int32_t* ptr = reinterpret_cast<int32_t*>(addr); | 1184 // check the alignment here. |
| 1232 return ptr; | 1185 int32_t* ptr = reinterpret_cast<int32_t*>(addr); |
| 1233 } else { | 1186 return ptr; |
| 1234 PrintF("Unaligned read at 0x%08x\n", addr); | |
| 1235 UNIMPLEMENTED(); | |
| 1236 return 0; | |
| 1237 } | |
| 1238 } | 1187 } |
| 1239 | 1188 |
| 1240 | 1189 |
| 1241 void Simulator::WriteDW(int32_t addr, int32_t value1, int32_t value2) { | 1190 void Simulator::WriteDW(int32_t addr, int32_t value1, int32_t value2) { |
| 1242 if (FLAG_enable_unaligned_accesses || (addr & 3) == 0) { | 1191 // All supported ARM targets allow unaligned accesses, so we don't need to |
| 1243 int32_t* ptr = reinterpret_cast<int32_t*>(addr); | 1192 // check the alignment here. |
| 1244 *ptr++ = value1; | 1193 int32_t* ptr = reinterpret_cast<int32_t*>(addr); |
| 1245 *ptr = value2; | 1194 *ptr++ = value1; |
| 1246 } else { | 1195 *ptr = value2; |
| 1247 PrintF("Unaligned write at 0x%08x\n", addr); | |
| 1248 UNIMPLEMENTED(); | |
| 1249 } | |
| 1250 } | 1196 } |
| 1251 | 1197 |
| 1252 | 1198 |
| 1253 // Returns the limit of the stack area to enable checking for stack overflows. | 1199 // Returns the limit of the stack area to enable checking for stack overflows. |
| 1254 uintptr_t Simulator::StackLimit(uintptr_t c_limit) const { | 1200 uintptr_t Simulator::StackLimit(uintptr_t c_limit) const { |
| 1255 // The simulator uses a separate JS stack. If we have exhausted the C stack, | 1201 // The simulator uses a separate JS stack. If we have exhausted the C stack, |
| 1256 // we also drop down the JS limit to reflect the exhaustion on the JS stack. | 1202 // we also drop down the JS limit to reflect the exhaustion on the JS stack. |
| 1257 if (GetCurrentStackPosition() < c_limit) { | 1203 if (GetCurrentStackPosition() < c_limit) { |
| 1258 return reinterpret_cast<uintptr_t>(get_sp()); | 1204 return reinterpret_cast<uintptr_t>(get_sp()); |
| 1259 } | 1205 } |
| (...skipping 3049 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4309 set_register(sp, current_sp + sizeof(uintptr_t)); | 4255 set_register(sp, current_sp + sizeof(uintptr_t)); |
| 4310 return address; | 4256 return address; |
| 4311 } | 4257 } |
| 4312 | 4258 |
| 4313 } // namespace internal | 4259 } // namespace internal |
| 4314 } // namespace v8 | 4260 } // namespace v8 |
| 4315 | 4261 |
| 4316 #endif // USE_SIMULATOR | 4262 #endif // USE_SIMULATOR |
| 4317 | 4263 |
| 4318 #endif // V8_TARGET_ARCH_ARM | 4264 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |