OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 // Modified by the Subzero authors. | 5 // Modified by the Subzero authors. |
6 // | 6 // |
7 //===- subzero/src/assembler_ia32.cpp - Assembler for x86-32 -------------===// | 7 //===- subzero/src/assembler_ia32.cpp - Assembler for x86-32 -------------===// |
8 // | 8 // |
9 // The Subzero Code Generator | 9 // The Subzero Code Generator |
10 // | 10 // |
(...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
333 } | 333 } |
334 | 334 |
335 void AssemblerX86::movd(const Address &dst, XmmRegister src) { | 335 void AssemblerX86::movd(const Address &dst, XmmRegister src) { |
336 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 336 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
337 EmitUint8(0x66); | 337 EmitUint8(0x66); |
338 EmitUint8(0x0F); | 338 EmitUint8(0x0F); |
339 EmitUint8(0x7E); | 339 EmitUint8(0x7E); |
340 EmitOperand(src, dst); | 340 EmitOperand(src, dst); |
341 } | 341 } |
342 | 342 |
| 343 void AssemblerX86::movq(XmmRegister dst, XmmRegister src) { |
| 344 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 345 EmitUint8(0xF3); |
| 346 EmitUint8(0x0F); |
| 347 EmitUint8(0x7E); |
| 348 EmitRegisterOperand(dst, src); |
| 349 } |
| 350 |
343 void AssemblerX86::movq(const Address &dst, XmmRegister src) { | 351 void AssemblerX86::movq(const Address &dst, XmmRegister src) { |
344 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 352 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
345 EmitUint8(0x66); | 353 EmitUint8(0x66); |
346 EmitUint8(0x0F); | 354 EmitUint8(0x0F); |
347 EmitUint8(0xD6); | 355 EmitUint8(0xD6); |
348 EmitOperand(src, Operand(dst)); | 356 EmitOperand(src, dst); |
349 } | 357 } |
350 | 358 |
351 void AssemblerX86::movq(XmmRegister dst, const Address &src) { | 359 void AssemblerX86::movq(XmmRegister dst, const Address &src) { |
352 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 360 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
353 EmitUint8(0xF3); | 361 EmitUint8(0xF3); |
354 EmitUint8(0x0F); | 362 EmitUint8(0x0F); |
355 EmitUint8(0x7E); | 363 EmitUint8(0x7E); |
356 EmitOperand(dst, Operand(src)); | 364 EmitOperand(dst, src); |
357 } | 365 } |
358 | 366 |
359 void AssemblerX86::addss(Type Ty, XmmRegister dst, XmmRegister src) { | 367 void AssemblerX86::addss(Type Ty, XmmRegister dst, XmmRegister src) { |
360 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 368 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
361 EmitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2); | 369 EmitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2); |
362 EmitUint8(0x0F); | 370 EmitUint8(0x0F); |
363 EmitUint8(0x58); | 371 EmitUint8(0x58); |
364 EmitXmmRegisterOperand(dst, src); | 372 EmitXmmRegisterOperand(dst, src); |
365 } | 373 } |
366 | 374 |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
456 EmitXmmRegisterOperand(src, dst); | 464 EmitXmmRegisterOperand(src, dst); |
457 } | 465 } |
458 | 466 |
459 void AssemblerX86::movaps(XmmRegister dst, XmmRegister src) { | 467 void AssemblerX86::movaps(XmmRegister dst, XmmRegister src) { |
460 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 468 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
461 EmitUint8(0x0F); | 469 EmitUint8(0x0F); |
462 EmitUint8(0x28); | 470 EmitUint8(0x28); |
463 EmitXmmRegisterOperand(dst, src); | 471 EmitXmmRegisterOperand(dst, src); |
464 } | 472 } |
465 | 473 |
| 474 void AssemblerX86::movups(XmmRegister dst, XmmRegister src) { |
| 475 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 476 EmitUint8(0x0F); |
| 477 EmitUint8(0x10); |
| 478 EmitRegisterOperand(dst, src); |
| 479 } |
| 480 |
466 void AssemblerX86::movups(XmmRegister dst, const Address &src) { | 481 void AssemblerX86::movups(XmmRegister dst, const Address &src) { |
467 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 482 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
468 EmitUint8(0x0F); | 483 EmitUint8(0x0F); |
469 EmitUint8(0x10); | 484 EmitUint8(0x10); |
470 EmitOperand(dst, src); | 485 EmitOperand(dst, src); |
471 } | 486 } |
472 | 487 |
473 void AssemblerX86::movups(const Address &dst, XmmRegister src) { | 488 void AssemblerX86::movups(const Address &dst, XmmRegister src) { |
474 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 489 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
475 EmitUint8(0x0F); | 490 EmitUint8(0x0F); |
(...skipping 806 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1282 EmitUint8(0xDB); | 1297 EmitUint8(0xDB); |
1283 EmitOperand(0, src); | 1298 EmitOperand(0, src); |
1284 } | 1299 } |
1285 | 1300 |
1286 void AssemblerX86::fincstp() { | 1301 void AssemblerX86::fincstp() { |
1287 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1302 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1288 EmitUint8(0xD9); | 1303 EmitUint8(0xD9); |
1289 EmitUint8(0xF7); | 1304 EmitUint8(0xF7); |
1290 } | 1305 } |
1291 | 1306 |
1292 void AssemblerX86::cmpl(GPRRegister reg, const Immediate &imm) { | 1307 void AssemblerX86::cmp(Type Ty, GPRRegister reg, const Immediate &imm) { |
1293 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1308 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1294 EmitComplex(BrokenType, 7, Operand(reg), imm); | 1309 if (isByteSizedType(Ty)) { |
| 1310 EmitComplexI8(7, Operand(reg), imm); |
| 1311 return; |
| 1312 } |
| 1313 if (Ty == IceType_i16) |
| 1314 EmitOperandSizeOverride(); |
| 1315 EmitComplex(Ty, 7, Operand(reg), imm); |
1295 } | 1316 } |
1296 | 1317 |
1297 void AssemblerX86::cmpl(GPRRegister reg0, GPRRegister reg1) { | 1318 void AssemblerX86::cmp(Type Ty, GPRRegister reg0, GPRRegister reg1) { |
1298 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1319 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1299 EmitUint8(0x3B); | 1320 if (Ty == IceType_i16) |
1300 EmitOperand(reg0, Operand(reg1)); | 1321 EmitOperandSizeOverride(); |
| 1322 if (isByteSizedType(Ty)) |
| 1323 EmitUint8(0x3A); |
| 1324 else |
| 1325 EmitUint8(0x3B); |
| 1326 EmitRegisterOperand(reg0, reg1); |
1301 } | 1327 } |
1302 | 1328 |
1303 void AssemblerX86::cmpl(GPRRegister reg, const Address &address) { | 1329 void AssemblerX86::cmp(Type Ty, GPRRegister reg, const Address &address) { |
1304 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1330 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1305 EmitUint8(0x3B); | 1331 if (Ty == IceType_i16) |
| 1332 EmitOperandSizeOverride(); |
| 1333 if (isByteSizedType(Ty)) |
| 1334 EmitUint8(0x3A); |
| 1335 else |
| 1336 EmitUint8(0x3B); |
1306 EmitOperand(reg, address); | 1337 EmitOperand(reg, address); |
1307 } | 1338 } |
1308 | 1339 |
1309 void AssemblerX86::cmpl(const Address &address, GPRRegister reg) { | 1340 void AssemblerX86::cmp(Type Ty, const Address &address, GPRRegister reg) { |
1310 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1341 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1311 EmitUint8(0x39); | 1342 if (Ty == IceType_i16) |
| 1343 EmitOperandSizeOverride(); |
| 1344 if (isByteSizedType(Ty)) |
| 1345 EmitUint8(0x38); |
| 1346 else |
| 1347 EmitUint8(0x39); |
1312 EmitOperand(reg, address); | 1348 EmitOperand(reg, address); |
1313 } | 1349 } |
1314 | 1350 |
1315 void AssemblerX86::cmpl(const Address &address, const Immediate &imm) { | 1351 void AssemblerX86::cmp(Type Ty, const Address &address, const Immediate &imm) { |
1316 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1352 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1317 EmitComplex(BrokenType, 7, address, imm); | 1353 if (isByteSizedType(Ty)) { |
| 1354 EmitComplexI8(7, address, imm); |
| 1355 return; |
| 1356 } |
| 1357 if (Ty == IceType_i16) |
| 1358 EmitOperandSizeOverride(); |
| 1359 EmitComplex(Ty, 7, address, imm); |
1318 } | 1360 } |
1319 | 1361 |
1320 void AssemblerX86::cmpb(const Address &address, const Immediate &imm) { | 1362 void AssemblerX86::test(Type Ty, GPRRegister reg1, GPRRegister reg2) { |
1321 assert(imm.is_int8()); | |
1322 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1363 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1323 EmitUint8(0x80); | 1364 if (Ty == IceType_i16) |
1324 EmitOperand(7, address); | 1365 EmitOperandSizeOverride(); |
1325 EmitUint8(imm.value() & 0xFF); | 1366 if (isByteSizedType(Ty)) |
1326 } | 1367 EmitUint8(0x84); |
1327 | 1368 else |
1328 void AssemblerX86::testl(GPRRegister reg1, GPRRegister reg2) { | 1369 EmitUint8(0x85); |
1329 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | |
1330 EmitUint8(0x85); | |
1331 EmitRegisterOperand(reg1, reg2); | 1370 EmitRegisterOperand(reg1, reg2); |
1332 } | 1371 } |
1333 | 1372 |
1334 void AssemblerX86::testl(GPRRegister reg, const Immediate &immediate) { | 1373 void AssemblerX86::test(Type Ty, const Address &addr, GPRRegister reg) { |
| 1374 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1375 if (Ty == IceType_i16) |
| 1376 EmitOperandSizeOverride(); |
| 1377 if (isByteSizedType(Ty)) |
| 1378 EmitUint8(0x84); |
| 1379 else |
| 1380 EmitUint8(0x85); |
| 1381 EmitOperand(reg, addr); |
| 1382 } |
| 1383 |
| 1384 void AssemblerX86::test(Type Ty, GPRRegister reg, const Immediate &immediate) { |
1335 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1385 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1336 // For registers that have a byte variant (EAX, EBX, ECX, and EDX) | 1386 // For registers that have a byte variant (EAX, EBX, ECX, and EDX) |
1337 // we only test the byte register to keep the encoding short. | 1387 // we only test the byte register to keep the encoding short. |
| 1388 // This is legal even if the register had high bits set since |
| 1389 // this only sets flags registers based on the "AND" of the two operands, |
| 1390 // and the immediate had zeros at those high bits. |
1338 if (immediate.is_uint8() && reg < 4) { | 1391 if (immediate.is_uint8() && reg < 4) { |
1339 // Use zero-extended 8-bit immediate. | 1392 // Use zero-extended 8-bit immediate. |
1340 if (reg == RegX8632::Encoded_Reg_eax) { | 1393 if (reg == RegX8632::Encoded_Reg_eax) { |
1341 EmitUint8(0xA8); | 1394 EmitUint8(0xA8); |
1342 } else { | 1395 } else { |
1343 EmitUint8(0xF6); | 1396 EmitUint8(0xF6); |
1344 EmitUint8(0xC0 + reg); | 1397 EmitUint8(0xC0 + reg); |
1345 } | 1398 } |
1346 EmitUint8(immediate.value() & 0xFF); | 1399 EmitUint8(immediate.value() & 0xFF); |
1347 } else if (reg == RegX8632::Encoded_Reg_eax) { | 1400 } else if (reg == RegX8632::Encoded_Reg_eax) { |
1348 // Use short form if the destination is EAX. | 1401 // Use short form if the destination is EAX. |
| 1402 if (Ty == IceType_i16) |
| 1403 EmitOperandSizeOverride(); |
1349 EmitUint8(0xA9); | 1404 EmitUint8(0xA9); |
1350 EmitImmediate(BrokenType, immediate); | 1405 EmitImmediate(Ty, immediate); |
1351 } else { | 1406 } else { |
| 1407 if (Ty == IceType_i16) |
| 1408 EmitOperandSizeOverride(); |
1352 EmitUint8(0xF7); | 1409 EmitUint8(0xF7); |
1353 EmitOperand(0, Operand(reg)); | 1410 EmitRegisterOperand(0, reg); |
1354 EmitImmediate(BrokenType, immediate); | 1411 EmitImmediate(Ty, immediate); |
1355 } | 1412 } |
1356 } | 1413 } |
1357 | 1414 |
| 1415 void AssemblerX86::test(Type Ty, const Address &addr, |
| 1416 const Immediate &immediate) { |
| 1417 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1418 // If the immediate is short, we only test the byte addr to keep the |
| 1419 // encoding short. |
| 1420 if (immediate.is_uint8()) { |
| 1421 // Use zero-extended 8-bit immediate. |
| 1422 EmitUint8(0xF6); |
| 1423 EmitOperand(0, addr); |
| 1424 EmitUint8(immediate.value() & 0xFF); |
| 1425 } else { |
| 1426 if (Ty == IceType_i16) |
| 1427 EmitOperandSizeOverride(); |
| 1428 EmitUint8(0xF7); |
| 1429 EmitOperand(0, addr); |
| 1430 EmitImmediate(Ty, immediate); |
| 1431 } |
| 1432 } |
| 1433 |
1358 void AssemblerX86::And(Type Ty, GPRRegister dst, GPRRegister src) { | 1434 void AssemblerX86::And(Type Ty, GPRRegister dst, GPRRegister src) { |
1359 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1435 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1360 if (Ty == IceType_i16) | 1436 if (Ty == IceType_i16) |
1361 EmitOperandSizeOverride(); | 1437 EmitOperandSizeOverride(); |
1362 if (isByteSizedType(Ty)) | 1438 if (isByteSizedType(Ty)) |
1363 EmitUint8(0x22); | 1439 EmitUint8(0x22); |
1364 else | 1440 else |
1365 EmitUint8(0x23); | 1441 EmitUint8(0x23); |
1366 EmitRegisterOperand(dst, src); | 1442 EmitRegisterOperand(dst, src); |
1367 } | 1443 } |
(...skipping 638 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2006 void AssemblerX86::int3() { | 2082 void AssemblerX86::int3() { |
2007 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 2083 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
2008 EmitUint8(0xCC); | 2084 EmitUint8(0xCC); |
2009 } | 2085 } |
2010 | 2086 |
2011 void AssemblerX86::hlt() { | 2087 void AssemblerX86::hlt() { |
2012 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 2088 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
2013 EmitUint8(0xF4); | 2089 EmitUint8(0xF4); |
2014 } | 2090 } |
2015 | 2091 |
| 2092 void AssemblerX86::ud2() { |
| 2093 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 2094 EmitUint8(0x0F); |
| 2095 EmitUint8(0x0B); |
| 2096 } |
| 2097 |
2016 void AssemblerX86::j(CondX86::BrCond condition, Label *label, bool near) { | 2098 void AssemblerX86::j(CondX86::BrCond condition, Label *label, bool near) { |
2017 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 2099 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
2018 if (label->IsBound()) { | 2100 if (label->IsBound()) { |
2019 static const int kShortSize = 2; | 2101 static const int kShortSize = 2; |
2020 static const int kLongSize = 6; | 2102 static const int kLongSize = 6; |
2021 intptr_t offset = label->Position() - buffer_.Size(); | 2103 intptr_t offset = label->Position() - buffer_.Size(); |
2022 assert(offset <= 0); | 2104 assert(offset <= 0); |
2023 if (Utils::IsInt(8, offset - kShortSize)) { | 2105 if (Utils::IsInt(8, offset - kShortSize)) { |
2024 EmitUint8(0x70 + condition); | 2106 EmitUint8(0x70 + condition); |
2025 EmitUint8((offset - kShortSize) & 0xFF); | 2107 EmitUint8((offset - kShortSize) & 0xFF); |
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2277 assert(shifter == RegX8632::Encoded_Reg_ecx); | 2359 assert(shifter == RegX8632::Encoded_Reg_ecx); |
2278 (void)shifter; | 2360 (void)shifter; |
2279 if (Ty == IceType_i16) | 2361 if (Ty == IceType_i16) |
2280 EmitOperandSizeOverride(); | 2362 EmitOperandSizeOverride(); |
2281 EmitUint8(isByteSizedArithType(Ty) ? 0xD2 : 0xD3); | 2363 EmitUint8(isByteSizedArithType(Ty) ? 0xD2 : 0xD3); |
2282 EmitOperand(rm, operand); | 2364 EmitOperand(rm, operand); |
2283 } | 2365 } |
2284 | 2366 |
2285 } // end of namespace x86 | 2367 } // end of namespace x86 |
2286 } // end of namespace Ice | 2368 } // end of namespace Ice |
OLD | NEW |