llvm.org GIT mirror llvm / 9e8528f
fix X86 encoder to output [disp] only addresses with no SIB byte in X86-32 mode. This is still required in x86-64 mode to avoid forming [disp+rip] encoding. Rewrite the SIB byte decision logic to be actually understandable. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@95693 91177308-0d34-0410-b5e6-96231b3b80d8 Chris Lattner 9 years ago
2 changed file(s) with 92 addition(s) and 77 deletion(s). Raw diff Collapse all Expand all
386386 // If no BaseReg, issue a RIP relative instruction only if the MCE can
387387 // resolve addresses on-the-fly, otherwise use SIB (Intel Manual 2A, table
388388 // 2-7) and absolute references.
389 if ((!Is64BitMode || DispForReloc || BaseReg != 0) &&
389 if (// The SIB byte must be used if there is an index register.
390390 IndexReg.getReg() == 0 &&
391 ((BaseReg == 0 && MCE.earlyResolveAddresses()) || BaseReg == X86::RIP ||
392 (BaseReg != 0 && getX86RegNum(BaseReg) != N86::ESP))) {
393 if (BaseReg == 0 || BaseReg == X86::RIP) { // Just a displacement?
394 // Emit special case [disp32] encoding
391 // The SIB byte must be used if the base is ESP/RSP.
392 BaseReg != X86::ESP && BaseReg != X86::RSP &&
393 // If there is no base register and we're in 64-bit mode, we need a SIB
394 // byte to emit an addr that is just 'disp32' (the non-RIP relative form).
395 (!Is64BitMode || BaseReg != 0)) {
396 if (BaseReg == 0 || // [disp32] in X86-32 mode
397 BaseReg == X86::RIP) { // [disp32+RIP] in X86-64 mode
395398 MCE.emitByte(ModRMByte(0, RegOpcodeField, 5));
396399 emitDisplacementField(DispForReloc, DispVal, PCAdj, true);
397 } else {
398 unsigned BaseRegNo = getX86RegNum(BaseReg);
399 if (!DispForReloc && DispVal == 0 && BaseRegNo != N86::EBP) {
400 // Emit simple indirect register encoding... [EAX] f.e.
401 MCE.emitByte(ModRMByte(0, RegOpcodeField, BaseRegNo));
402 } else if (!DispForReloc && isDisp8(DispVal)) {
403 // Emit the disp8 encoding... [REG+disp8]
404 MCE.emitByte(ModRMByte(1, RegOpcodeField, BaseRegNo));
405 emitConstant(DispVal, 1);
406 } else {
407 // Emit the most general non-SIB encoding: [REG+disp32]
408 MCE.emitByte(ModRMByte(2, RegOpcodeField, BaseRegNo));
409 emitDisplacementField(DispForReloc, DispVal, PCAdj, IsPCRel);
410 }
411 }
412
413 } else { // We need a SIB byte, so start by outputting the ModR/M byte first
414 assert(IndexReg.getReg() != X86::ESP &&
415 IndexReg.getReg() != X86::RSP && "Cannot use ESP as index reg!");
416
417 bool ForceDisp32 = false;
418 bool ForceDisp8 = false;
419 if (BaseReg == 0) {
420 // If there is no base register, we emit the special case SIB byte with
421 // MOD=0, BASE=5, to JUST get the index, scale, and displacement.
422 MCE.emitByte(ModRMByte(0, RegOpcodeField, 4));
423 ForceDisp32 = true;
424 } else if (DispForReloc) {
425 // Emit the normal disp32 encoding.
426 MCE.emitByte(ModRMByte(2, RegOpcodeField, 4));
427 ForceDisp32 = true;
428 } else if (DispVal == 0 && getX86RegNum(BaseReg) != N86::EBP) {
429 // Emit no displacement ModR/M byte
430 MCE.emitByte(ModRMByte(0, RegOpcodeField, 4));
431 } else if (isDisp8(DispVal)) {
432 // Emit the disp8 encoding...
433 MCE.emitByte(ModRMByte(1, RegOpcodeField, 4));
434 ForceDisp8 = true; // Make sure to force 8 bit disp if Base=EBP
435 } else {
436 // Emit the normal disp32 encoding...
437 MCE.emitByte(ModRMByte(2, RegOpcodeField, 4));
438 }
439
440 // Calculate what the SS field value should be...
441 static const unsigned SSTable[] = { ~0, 0, 1, ~0, 2, ~0, ~0, ~0, 3 };
442 unsigned SS = SSTable[Scale.getImm()];
443
444 if (BaseReg == 0) {
445 // Handle the SIB byte for the case where there is no base, see Intel
446 // Manual 2A, table 2-7. The displacement has already been output.
447 unsigned IndexRegNo;
448 if (IndexReg.getReg())
449 IndexRegNo = getX86RegNum(IndexReg.getReg());
450 else // Examples: [ESP+1*+4] or [scaled idx]+disp32 (MOD=0,BASE=5)
451 IndexRegNo = 4;
452 emitSIBByte(SS, IndexRegNo, 5);
453 } else {
454 unsigned BaseRegNo = getX86RegNum(BaseReg);
455 unsigned IndexRegNo;
456 if (IndexReg.getReg())
457 IndexRegNo = getX86RegNum(IndexReg.getReg());
458 else
459 IndexRegNo = 4; // For example [ESP+1*+4]
460 emitSIBByte(SS, IndexRegNo, BaseRegNo);
461 }
462
463 // Do we need to output a displacement?
464 if (ForceDisp8) {
400 return;
401 }
402
403 unsigned BaseRegNo = getX86RegNum(BaseReg);
404 // If the base is not EBP/ESP and there is no displacement, use simple
405 // indirect register encoding, this handles addresses like [EAX]. The
406 // encoding for [EBP] with no displacement means [disp32] so we handle it
407 // by emitting a displacement of 0 below.
408 if (!DispForReloc && DispVal == 0 && BaseRegNo != N86::EBP) {
409 MCE.emitByte(ModRMByte(0, RegOpcodeField, BaseRegNo));
410 return;
411 }
412
413 // Otherwise, if the displacement fits in a byte, encode as [REG+disp8].
414 if (!DispForReloc && isDisp8(DispVal)) {
415 MCE.emitByte(ModRMByte(1, RegOpcodeField, BaseRegNo));
465416 emitConstant(DispVal, 1);
466 } else if (DispVal != 0 || ForceDisp32) {
467 emitDisplacementField(DispForReloc, DispVal, PCAdj, IsPCRel);
468 }
417 return;
418 }
419
420 // Otherwise, emit the most general non-SIB encoding: [REG+disp32]
421 MCE.emitByte(ModRMByte(2, RegOpcodeField, BaseRegNo));
422 emitDisplacementField(DispForReloc, DispVal, PCAdj, IsPCRel);
423 return;
424 }
425
426 // Otherwise we need a SIB byte, so start by outputting the ModR/M byte first.
427 assert(IndexReg.getReg() != X86::ESP &&
428 IndexReg.getReg() != X86::RSP && "Cannot use ESP as index reg!");
429
430 bool ForceDisp32 = false;
431 bool ForceDisp8 = false;
432 if (BaseReg == 0) {
433 // If there is no base register, we emit the special case SIB byte with
434 // MOD=0, BASE=4, to JUST get the index, scale, and displacement.
435 MCE.emitByte(ModRMByte(0, RegOpcodeField, 4));
436 ForceDisp32 = true;
437 } else if (DispForReloc) {
438 // Emit the normal disp32 encoding.
439 MCE.emitByte(ModRMByte(2, RegOpcodeField, 4));
440 ForceDisp32 = true;
441 } else if (DispVal == 0 && getX86RegNum(BaseReg) != N86::EBP) {
442 // Emit no displacement ModR/M byte
443 MCE.emitByte(ModRMByte(0, RegOpcodeField, 4));
444 } else if (isDisp8(DispVal)) {
445 // Emit the disp8 encoding...
446 MCE.emitByte(ModRMByte(1, RegOpcodeField, 4));
447 ForceDisp8 = true; // Make sure to force 8 bit disp if Base=EBP
448 } else {
449 // Emit the normal disp32 encoding...
450 MCE.emitByte(ModRMByte(2, RegOpcodeField, 4));
451 }
452
453 // Calculate what the SS field value should be...
454 static const unsigned SSTable[] = { ~0, 0, 1, ~0, 2, ~0, ~0, ~0, 3 };
455 unsigned SS = SSTable[Scale.getImm()];
456
457 if (BaseReg == 0) {
458 // Handle the SIB byte for the case where there is no base, see Intel
459 // Manual 2A, table 2-7. The displacement has already been output.
460 unsigned IndexRegNo;
461 if (IndexReg.getReg())
462 IndexRegNo = getX86RegNum(IndexReg.getReg());
463 else // Examples: [ESP+1*+4] or [scaled idx]+disp32 (MOD=0,BASE=5)
464 IndexRegNo = 4;
465 emitSIBByte(SS, IndexRegNo, 5);
466 } else {
467 unsigned BaseRegNo = getX86RegNum(BaseReg);
468 unsigned IndexRegNo;
469 if (IndexReg.getReg())
470 IndexRegNo = getX86RegNum(IndexReg.getReg());
471 else
472 IndexRegNo = 4; // For example [ESP+1*+4]
473 emitSIBByte(SS, IndexRegNo, BaseRegNo);
474 }
475
476 // Do we need to output a displacement?
477 if (ForceDisp8) {
478 emitConstant(DispVal, 1);
479 } else if (DispVal != 0 || ForceDisp32) {
480 emitDisplacementField(DispForReloc, DispVal, PCAdj, IsPCRel);
469481 }
470482 }
471483
33 # CHECK: encoding: [0xdb,0x8c,0xcb,0xef,0xbe,0xad,0xde]
44
55 sbbb $0xfe,0xdeadbeef(%ebx,%ecx,8)
6 # CHECK: encoding: [0x80,0x9c,0xcb,0xef,0xbe,0xad,0xde,0xfe]
67
7 # CHECK: encoding: [0x80,0x9c,0xcb,0xef,0xbe,0xad,0xde,0xfe]
8 psllw 69, %mm3
9 # CHECK: encoding: [0x0f,0xf1,0x1d,0x45,0x00,0x00,0x00]
10