| 1271 | } |
| 1272 | |
| 1273 | void JitCodeGen::write(JitWidth width, MemPtr mem, RegPtr src) { |
| 1274 | if (!mem->emulatedAddress) { |
| 1275 | writeHost(width, mem, src); |
| 1276 | return; |
| 1277 | } |
| 1278 | if (mem->rm || mem->sib) { |
| 1279 | write(width, calculateAddress(mem), src); |
| 1280 | return; |
| 1281 | } |
| 1282 | RegPtr tmp = getTmpReg8(); |
| 1283 | #ifdef BOXEDWINE_MEM_CACHE |
| 1284 | if (currentOp->exceptionCount < MAX_OP_EXCEPTION_COUNT && (KSystem::canJitUse4KPage || !doesSpanPage(width, mem->offset))) { |
| 1285 | #ifdef _DEBUG |
| 1286 | writeCurrentEip(0); |
| 1287 | #endif |
| 1288 | readMMU(tmp, K_NUMBER_OF_PAGES * 2 + (mem->offset >> K_PAGE_SHIFT)); |
| 1289 | writeHost(width, createMemPtr(tmp, mem->offset), src); |
| 1290 | return; |
| 1291 | } |
| 1292 | #endif |
| 1293 | |
| 1294 | U32 address = mem->offset; |
| 1295 | if (width == JitWidth::b16) { |
| 1296 | if ((address & 0xFFF) == 0xFFF) { |
| 1297 | emulateSingleOp(); |
| 1298 | return; |
| 1299 | } |
| 1300 | } else if (width == JitWidth::b32) { |
| 1301 | if ((address & 0xFFF) >= 0xFFD) { |
| 1302 | emulateSingleOp(); |
| 1303 | return; |
| 1304 | } |
| 1305 | } else if (width != JitWidth::b8) { |
| 1306 | kpanic_fmt("JitCodeGen::write unknown width %d", (U32)width); |
| 1307 | } |
| 1308 | readMMU(tmp, address >> K_PAGE_SHIFT); |
| 1309 | |
| 1310 | IfNotTestBit(JitWidth::b32, tmp, 1); { |
| 1311 | emulateSingleOp(); |
| 1312 | } EndIf(); |
| 1313 | |
| 1314 | andValueNative(tmp, ~0xfff); |
| 1315 | writeHost(width, createMemPtr(tmp, address & K_PAGE_MASK), src); |
| 1316 | } |
| 1317 | |
| 1318 | void JitCodeGen::write(JitWidth width, RegPtr addressReg, RegPtr src, std::function<void(MemPtr address)> customMemoryOp, std::function<void()> failedMemoryOp, bool checkAlignment) { |
| 1319 | RegPtr tmp = getTmpReg(); |