mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-08-07 12:28:24 +00:00
[x86] Teach the asm comment printing to only print the clarification of
an immediate operand when we don't have instruction-specific comments. This ensures that instruction-specific comments are attached to the same line as the instruction which is important for using them to write readable and maintainable tests. My next commit will just such a test. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@217099 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -45,6 +45,11 @@ void X86ATTInstPrinter::printInst(const MCInst *MI, raw_ostream &OS,
|
|||||||
const MCInstrDesc &Desc = MII.get(MI->getOpcode());
|
const MCInstrDesc &Desc = MII.get(MI->getOpcode());
|
||||||
uint64_t TSFlags = Desc.TSFlags;
|
uint64_t TSFlags = Desc.TSFlags;
|
||||||
|
|
||||||
|
// If verbose assembly is enabled, we can print some informative comments.
|
||||||
|
if (CommentStream)
|
||||||
|
HasCustomInstComment =
|
||||||
|
EmitAnyX86InstComments(MI, *CommentStream, getRegisterName);
|
||||||
|
|
||||||
if (TSFlags & X86II::LOCK)
|
if (TSFlags & X86II::LOCK)
|
||||||
OS << "\tlock\n";
|
OS << "\tlock\n";
|
||||||
|
|
||||||
@@ -54,10 +59,6 @@ void X86ATTInstPrinter::printInst(const MCInst *MI, raw_ostream &OS,
|
|||||||
|
|
||||||
// Next always print the annotation.
|
// Next always print the annotation.
|
||||||
printAnnotation(OS, Annot);
|
printAnnotation(OS, Annot);
|
||||||
|
|
||||||
// If verbose assembly is enabled, we can print some informative comments.
|
|
||||||
if (CommentStream)
|
|
||||||
EmitAnyX86InstComments(MI, *CommentStream, getRegisterName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void X86ATTInstPrinter::printSSECC(const MCInst *MI, unsigned Op,
|
void X86ATTInstPrinter::printSSECC(const MCInst *MI, unsigned Op,
|
||||||
@@ -170,7 +171,11 @@ void X86ATTInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
|
|||||||
<< '$' << formatImm((int64_t)Op.getImm())
|
<< '$' << formatImm((int64_t)Op.getImm())
|
||||||
<< markup(">");
|
<< markup(">");
|
||||||
|
|
||||||
if (CommentStream && (Op.getImm() > 255 || Op.getImm() < -256))
|
// If there are no instruction-specific comments, add a comment clarifying
|
||||||
|
// the hex value of the immediate operand when it isn't in the range
|
||||||
|
// [-256,255].
|
||||||
|
if (CommentStream && !HasCustomInstComment &&
|
||||||
|
(Op.getImm() > 255 || Op.getImm() < -256))
|
||||||
*CommentStream << format("imm = 0x%" PRIX64 "\n", (uint64_t)Op.getImm());
|
*CommentStream << format("imm = 0x%" PRIX64 "\n", (uint64_t)Op.getImm());
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
@@ -129,6 +129,9 @@ public:
|
|||||||
void printMemOffs64(const MCInst *MI, unsigned OpNo, raw_ostream &O) {
|
void printMemOffs64(const MCInst *MI, unsigned OpNo, raw_ostream &O) {
|
||||||
printMemOffset(MI, OpNo, O);
|
printMemOffset(MI, OpNo, O);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool HasCustomInstComment;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -28,13 +28,17 @@ using namespace llvm;
|
|||||||
/// EmitAnyX86InstComments - This function decodes x86 instructions and prints
|
/// EmitAnyX86InstComments - This function decodes x86 instructions and prints
|
||||||
/// newline terminated strings to the specified string if desired. This
|
/// newline terminated strings to the specified string if desired. This
|
||||||
/// information is shown in disassembly dumps when verbose assembly is enabled.
|
/// information is shown in disassembly dumps when verbose assembly is enabled.
|
||||||
void llvm::EmitAnyX86InstComments(const MCInst *MI, raw_ostream &OS,
|
bool llvm::EmitAnyX86InstComments(const MCInst *MI, raw_ostream &OS,
|
||||||
const char *(*getRegName)(unsigned)) {
|
const char *(*getRegName)(unsigned)) {
|
||||||
// If this is a shuffle operation, the switch should fill in this state.
|
// If this is a shuffle operation, the switch should fill in this state.
|
||||||
SmallVector<int, 8> ShuffleMask;
|
SmallVector<int, 8> ShuffleMask;
|
||||||
const char *DestName = nullptr, *Src1Name = nullptr, *Src2Name = nullptr;
|
const char *DestName = nullptr, *Src1Name = nullptr, *Src2Name = nullptr;
|
||||||
|
|
||||||
switch (MI->getOpcode()) {
|
switch (MI->getOpcode()) {
|
||||||
|
default:
|
||||||
|
// Not an instruction for which we can decode comments.
|
||||||
|
return false;
|
||||||
|
|
||||||
case X86::BLENDPDrri:
|
case X86::BLENDPDrri:
|
||||||
case X86::VBLENDPDrri:
|
case X86::VBLENDPDrri:
|
||||||
Src2Name = getRegName(MI->getOperand(2).getReg());
|
Src2Name = getRegName(MI->getOperand(2).getReg());
|
||||||
@@ -553,54 +557,57 @@ void llvm::EmitAnyX86InstComments(const MCInst *MI, raw_ostream &OS,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The only comments we decode are shuffles, so give up if we were unable to
|
||||||
|
// decode a shuffle mask.
|
||||||
|
if (ShuffleMask.empty())
|
||||||
|
return false;
|
||||||
|
|
||||||
// If this was a shuffle operation, print the shuffle mask.
|
if (!DestName) DestName = Src1Name;
|
||||||
if (!ShuffleMask.empty()) {
|
OS << (DestName ? DestName : "mem") << " = ";
|
||||||
if (!DestName) DestName = Src1Name;
|
|
||||||
OS << (DestName ? DestName : "mem") << " = ";
|
|
||||||
|
|
||||||
// If the two sources are the same, canonicalize the input elements to be
|
// If the two sources are the same, canonicalize the input elements to be
|
||||||
// from the first src so that we get larger element spans.
|
// from the first src so that we get larger element spans.
|
||||||
if (Src1Name == Src2Name) {
|
if (Src1Name == Src2Name) {
|
||||||
for (unsigned i = 0, e = ShuffleMask.size(); i != e; ++i) {
|
|
||||||
if ((int)ShuffleMask[i] >= 0 && // Not sentinel.
|
|
||||||
ShuffleMask[i] >= (int)e) // From second mask.
|
|
||||||
ShuffleMask[i] -= e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// The shuffle mask specifies which elements of the src1/src2 fill in the
|
|
||||||
// destination, with a few sentinel values. Loop through and print them
|
|
||||||
// out.
|
|
||||||
for (unsigned i = 0, e = ShuffleMask.size(); i != e; ++i) {
|
for (unsigned i = 0, e = ShuffleMask.size(); i != e; ++i) {
|
||||||
if (i != 0)
|
if ((int)ShuffleMask[i] >= 0 && // Not sentinel.
|
||||||
OS << ',';
|
ShuffleMask[i] >= (int)e) // From second mask.
|
||||||
if (ShuffleMask[i] == SM_SentinelZero) {
|
ShuffleMask[i] -= e;
|
||||||
OS << "zero";
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Otherwise, it must come from src1 or src2. Print the span of elements
|
|
||||||
// that comes from this src.
|
|
||||||
bool isSrc1 = ShuffleMask[i] < (int)ShuffleMask.size();
|
|
||||||
const char *SrcName = isSrc1 ? Src1Name : Src2Name;
|
|
||||||
OS << (SrcName ? SrcName : "mem") << '[';
|
|
||||||
bool IsFirst = true;
|
|
||||||
while (i != e &&
|
|
||||||
(int)ShuffleMask[i] >= 0 &&
|
|
||||||
(ShuffleMask[i] < (int)ShuffleMask.size()) == isSrc1) {
|
|
||||||
if (!IsFirst)
|
|
||||||
OS << ',';
|
|
||||||
else
|
|
||||||
IsFirst = false;
|
|
||||||
OS << ShuffleMask[i] % ShuffleMask.size();
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
OS << ']';
|
|
||||||
--i; // For loop increments element #.
|
|
||||||
}
|
}
|
||||||
//MI->print(OS, 0);
|
|
||||||
OS << "\n";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The shuffle mask specifies which elements of the src1/src2 fill in the
|
||||||
|
// destination, with a few sentinel values. Loop through and print them
|
||||||
|
// out.
|
||||||
|
for (unsigned i = 0, e = ShuffleMask.size(); i != e; ++i) {
|
||||||
|
if (i != 0)
|
||||||
|
OS << ',';
|
||||||
|
if (ShuffleMask[i] == SM_SentinelZero) {
|
||||||
|
OS << "zero";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, it must come from src1 or src2. Print the span of elements
|
||||||
|
// that comes from this src.
|
||||||
|
bool isSrc1 = ShuffleMask[i] < (int)ShuffleMask.size();
|
||||||
|
const char *SrcName = isSrc1 ? Src1Name : Src2Name;
|
||||||
|
OS << (SrcName ? SrcName : "mem") << '[';
|
||||||
|
bool IsFirst = true;
|
||||||
|
while (i != e &&
|
||||||
|
(int)ShuffleMask[i] >= 0 &&
|
||||||
|
(ShuffleMask[i] < (int)ShuffleMask.size()) == isSrc1) {
|
||||||
|
if (!IsFirst)
|
||||||
|
OS << ',';
|
||||||
|
else
|
||||||
|
IsFirst = false;
|
||||||
|
OS << ShuffleMask[i] % ShuffleMask.size();
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
OS << ']';
|
||||||
|
--i; // For loop increments element #.
|
||||||
|
}
|
||||||
|
//MI->print(OS, 0);
|
||||||
|
OS << "\n";
|
||||||
|
|
||||||
|
// We successfully added a comment to this instruction.
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
@@ -18,7 +18,7 @@
|
|||||||
namespace llvm {
|
namespace llvm {
|
||||||
class MCInst;
|
class MCInst;
|
||||||
class raw_ostream;
|
class raw_ostream;
|
||||||
void EmitAnyX86InstComments(const MCInst *MI, raw_ostream &OS,
|
bool EmitAnyX86InstComments(const MCInst *MI, raw_ostream &OS,
|
||||||
const char *(*getRegName)(unsigned));
|
const char *(*getRegName)(unsigned));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user