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 |