diff options
Diffstat (limited to 'llvm/lib/Target/X86/X86CodeEmitter.cpp')
| -rw-r--r-- | llvm/lib/Target/X86/X86CodeEmitter.cpp | 154 |
1 files changed, 52 insertions, 102 deletions
diff --git a/llvm/lib/Target/X86/X86CodeEmitter.cpp b/llvm/lib/Target/X86/X86CodeEmitter.cpp index dc75e60345e..5d36d936c58 100644 --- a/llvm/lib/Target/X86/X86CodeEmitter.cpp +++ b/llvm/lib/Target/X86/X86CodeEmitter.cpp @@ -658,40 +658,16 @@ void Emitter<CodeEmitter>::emitOpcodePrefix(uint64_t TSFlags, if (TSFlags & X86II::OpSize) MCE.emitByte(0x66); - bool Need0FPrefix = false; - switch (Desc->TSFlags & X86II::Op0Mask) { - case X86II::TB: // Two-byte opcode prefix - case X86II::T8: // 0F 38 - case X86II::TA: // 0F 3A - case X86II::A6: // 0F A6 - case X86II::A7: // 0F A7 - Need0FPrefix = true; - break; - case X86II::PD: // 66 0F - case X86II::T8PD: // 66 0F 38 - case X86II::TAPD: // 66 0F 3A - MCE.emitByte(0x66); - Need0FPrefix = true; - break; - case X86II::T8XS: // F3 0F 38 - case X86II::XS: // F3 0F - MCE.emitByte(0xF3); - Need0FPrefix = true; - break; - case X86II::T8XD: // F2 0F 38 - case X86II::TAXD: // F2 0F 3A - case X86II::XD: // F2 0F - MCE.emitByte(0xF2); - Need0FPrefix = true; - break; - case X86II::D8: case X86II::D9: case X86II::DA: case X86II::DB: - case X86II::DC: case X86II::DD: case X86II::DE: case X86II::DF: - MCE.emitByte(0xD8+ - (((Desc->TSFlags & X86II::Op0Mask)-X86II::D8) - >> X86II::Op0Shift)); - break; // Two-byte opcode prefix - default: llvm_unreachable("Invalid prefix!"); - case 0: break; // No prefix! + switch (Desc->TSFlags & X86II::OpPrefixMask) { + case X86II::PD: // 66 + MCE.emitByte(0x66); + break; + case X86II::XS: // F3 + MCE.emitByte(0xF3); + break; + case X86II::XD: // F2 + MCE.emitByte(0xF2); + break; } // Handle REX prefix. @@ -701,27 +677,35 @@ void Emitter<CodeEmitter>::emitOpcodePrefix(uint64_t TSFlags, } // 0x0F escape code must be emitted just before the opcode. - if (Need0FPrefix) + switch (Desc->TSFlags & X86II::OpMapMask) { + case X86II::TB: // Two-byte opcode map + case X86II::T8: // 0F 38 + case X86II::TA: // 0F 3A + case X86II::A6: // 0F A6 + case X86II::A7: // 0F A7 MCE.emitByte(0x0F); + break; + case X86II::D8: case X86II::D9: case X86II::DA: case X86II::DB: + case X86II::DC: case X86II::DD: case X86II::DE: case X86II::DF: + MCE.emitByte(0xD8+ + (((Desc->TSFlags & X86II::OpMapMask)-X86II::D8) + >> X86II::OpMapShift)); + break; + } - switch (Desc->TSFlags & X86II::Op0Mask) { - case X86II::T8PD: // 66 0F 38 - case X86II::T8XD: // F2 0F 38 - case X86II::T8XS: // F3 0F 38 - case X86II::T8: // 0F 38 - MCE.emitByte(0x38); - break; - case X86II::TAPD: // 66 0F 38 - case X86II::TAXD: // F2 0F 38 - case X86II::TA: // 0F 3A - MCE.emitByte(0x3A); - break; - case X86II::A6: // 0F A6 - MCE.emitByte(0xA6); - break; - case X86II::A7: // 0F A7 - MCE.emitByte(0xA7); - break; + switch (Desc->TSFlags & X86II::OpMapMask) { + case X86II::T8: // 0F 38 + MCE.emitByte(0x38); + break; + case X86II::TA: // 0F 3A + MCE.emitByte(0x3A); + break; + case X86II::A6: // 0F A6 + MCE.emitByte(0xA6); + break; + case X86II::A7: // 0F A7 + MCE.emitByte(0xA7); + break; } } @@ -817,7 +801,7 @@ void Emitter<CodeEmitter>::emitVEXOpcodePrefix(uint64_t TSFlags, // 0b01000: XOP map select - 08h instructions with imm byte // 0b01001: XOP map select - 09h instructions with no imm byte // 0b01010: XOP map select - 0Ah instructions with imm dword - unsigned char VEX_5M = 0x1; + unsigned char VEX_5M = 0; // VEX_4V (VEX vvvv field): a register specifier // (in 1's complement form) or 1111 if unused. @@ -846,56 +830,22 @@ void Emitter<CodeEmitter>::emitVEXOpcodePrefix(uint64_t TSFlags, if ((TSFlags >> X86II::VEXShift) & X86II::VEX_L) VEX_L = 1; - switch (TSFlags & X86II::Op0Mask) { - default: llvm_unreachable("Invalid prefix!"); - case X86II::T8: // 0F 38 - VEX_5M = 0x2; - break; - case X86II::TA: // 0F 3A - VEX_5M = 0x3; - break; - case X86II::T8PD: // 66 0F 38 - VEX_PP = 0x1; - VEX_5M = 0x2; - break; - case X86II::T8XS: // F3 0F 38 - VEX_PP = 0x2; - VEX_5M = 0x2; - break; - case X86II::T8XD: // F2 0F 38 - VEX_PP = 0x3; - VEX_5M = 0x2; - break; - case X86II::TAPD: // 66 0F 3A - VEX_PP = 0x1; - VEX_5M = 0x3; - break; - case X86II::TAXD: // F2 0F 3A - VEX_PP = 0x3; - VEX_5M = 0x3; - break; - case X86II::PD: // 66 0F - VEX_PP = 0x1; - break; - case X86II::XS: // F3 0F - VEX_PP = 0x2; - break; - case X86II::XD: // F2 0F - VEX_PP = 0x3; - break; - case X86II::XOP8: - VEX_5M = 0x8; - break; - case X86II::XOP9: - VEX_5M = 0x9; - break; - case X86II::XOPA: - VEX_5M = 0xA; - break; - case X86II::TB: // VEX_5M/VEX_PP already correct - break; + switch (TSFlags & X86II::OpPrefixMask) { + default: break; // VEX_PP already correct + case X86II::PD: VEX_PP = 0x1; break; // 66 + case X86II::XS: VEX_PP = 0x2; break; // F3 + case X86II::XD: VEX_PP = 0x3; break; // F2 } + switch (TSFlags & X86II::OpMapMask) { + default: llvm_unreachable("Invalid prefix!"); + case X86II::TB: VEX_5M = 0x1; break; // 0F + case X86II::T8: VEX_5M = 0x2; break; // 0F 38 + case X86II::TA: VEX_5M = 0x3; break; // 0F 3A + case X86II::XOP8: VEX_5M = 0x8; break; + case X86II::XOP9: VEX_5M = 0x9; break; + case X86II::XOPA: VEX_5M = 0xA; break; + } // Classify VEX_B, VEX_4V, VEX_R, VEX_X unsigned NumOps = Desc->getNumOperands(); |

