Skip to content

Commit 96b2c3b

Browse files
authored
[X86][MC] Report error when the instruction length exceeds 15 bytes (#83708)
The instruction-size limit of 15 bytes still applies to APX instructions. Note that it is possible for an EVEX-encoded legacy instruction to reach the 15-byte instruction length limit: 4 bytes of EVEX prefix + 1 byte of opcode + 1 byte of ModRM + 1 byte of SIB + 4 bytes of displacement + 4 bytes of immediate = 15 bytes in total, e.g. ``` addq $184, -96, %rax # encoding: [0x62,0xf4,0xfc,0x18,0x81,0x04,0x25,0xa0,0xff,0xff,0xff,0xb8,0x00,0x00,0x00] ``` If we added a segment prefix like fs, the length would be 16. In such a case, no additional (ASIZE or segment override) prefix can be used. To help users find this issue earlier, especially for assembler users, we change the internal compiler error to error in this patch. Diagnostic is aligned with GAS https://sourceware.org/bugzilla/show_bug.cgi?id=31323
1 parent 408d4e1 commit 96b2c3b

File tree

2 files changed

+27
-2
lines changed

2 files changed

+27
-2
lines changed

llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1924,8 +1924,8 @@ void X86MCCodeEmitter::encodeInstruction(const MCInst &MI,
19241924
if ((TSFlags & X86II::OpMapMask) == X86II::ThreeDNow)
19251925
emitByte(X86II::getBaseOpcodeFor(TSFlags), CB);
19261926

1927-
assert(CB.size() - StartByte <= 15 &&
1928-
"The size of instruction must be no longer than 15.");
1927+
if (CB.size() - StartByte > 15)
1928+
Ctx.reportError(MI.getLoc(), "instruction length exceeds the limit of 15");
19291929
#ifndef NDEBUG
19301930
// FIXME: Verify.
19311931
if (/*!Desc.isVariadic() &&*/ CurOp != NumOps) {
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# RUN: not llvm-mc -triple x86_64 -show-encoding %s 2>&1 | FileCheck %s
2+
3+
# CHECK: [[#@LINE+2]]:1: error: instruction length exceeds the limit of 15
4+
# CHECK: addq $1234, %cs:-96, %rax
5+
addq $1234, %cs:-96, %rax
6+
7+
# CHECK: [[#@LINE+2]]:1: error: instruction length exceeds the limit of 15
8+
# CHECK: subq $1234, %fs:257(%rbx, %rcx), %rax
9+
subq $1234, %fs:257(%rbx, %rcx), %rax
10+
11+
# CHECK: [[#@LINE+2]]:1: error: instruction length exceeds the limit of 15
12+
# CHECK: orq $1234, 257(%ebx, %ecx), %rax
13+
orq $1234, 257(%ebx, %ecx), %rax
14+
15+
# CHECK: [[#@LINE+2]]:1: error: instruction length exceeds the limit of 15
16+
# CHECK: xorq $1234, %gs:257(%ebx), %rax
17+
xorq $1234, %gs:257(%ebx), %rax
18+
19+
# CHECK: [[#@LINE+2]]:1: error: instruction length exceeds the limit of 15
20+
# CHECK: {nf} andq $1234, %cs:-96
21+
{nf} andq $1234, %cs:-96
22+
23+
# CHECK: [[#@LINE+2]]:1: error: instruction length exceeds the limit of 15
24+
# CHECK: {evex} adcq $1234, %cs:-96
25+
{evex} adcq $1234, %cs:-96

0 commit comments

Comments
 (0)