mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-08 12:21:04 +00:00
correct suffix matching to search for s/l/t suffixes on
floating point stack instructions instead of looking for b/w/l/q. This fixes issues where we'd accidentally match fistp to fistpl, when it is in fact an ambiguous instruction. This changes the behavior of llvm-mc to reject fstp, which was the correct fix for rdar://8456389: t.s:1:1: error: ambiguous instructions require an explicit suffix (could be 'fstps', 'fstpl', or 'fstpt') fstp (%rax) it also causes us to correctly reject fistp and fist, which addresses PR8528: t.s:2:1: error: ambiguous instructions require an explicit suffix (could be 'fistps', or 'fistpl') fistp (%rax) ^ t.s:3:1: error: ambiguous instructions require an explicit suffix (could be 'fists', or 'fistl') fist (%rax) ^ Thanks to Ismail Donmez for tracking down the issue here! llvm-svn: 118346
This commit is contained in:
parent
96ac873014
commit
1beb2b3fc5
@ -919,14 +919,6 @@ ParseInstruction(StringRef Name, SMLoc NameLoc,
|
|||||||
NameLoc, NameLoc));
|
NameLoc, NameLoc));
|
||||||
}
|
}
|
||||||
|
|
||||||
// fstp <mem> -> fstps <mem>. Without this, we'll default to fstpl due to
|
|
||||||
// suffix searching.
|
|
||||||
if (Name == "fstp" && Operands.size() == 2 &&
|
|
||||||
static_cast<X86Operand*>(Operands[1])->isMem()) {
|
|
||||||
delete Operands[0];
|
|
||||||
Operands[0] = X86Operand::CreateToken("fstps", NameLoc);
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME: Hack to handle recognize "aa[dm]" -> "aa[dm] $0xA".
|
// FIXME: Hack to handle recognize "aa[dm]" -> "aa[dm] $0xA".
|
||||||
if ((Name.startswith("aad") || Name.startswith("aam")) &&
|
if ((Name.startswith("aad") || Name.startswith("aam")) &&
|
||||||
Operands.size() == 1) {
|
Operands.size() == 1) {
|
||||||
@ -1002,16 +994,26 @@ MatchAndEmitInstruction(SMLoc IDLoc,
|
|||||||
Tmp += ' ';
|
Tmp += ' ';
|
||||||
Op->setTokenValue(Tmp.str());
|
Op->setTokenValue(Tmp.str());
|
||||||
|
|
||||||
|
// If this instruction starts with an 'f', then it is a floating point stack
|
||||||
|
// instruction. These come in up to three forms for 32-bit, 64-bit, and
|
||||||
|
// 80-bit floating point, which use the suffixes s,l,t respectively.
|
||||||
|
//
|
||||||
|
// Otherwise, we assume that this may be an integer instruction, which comes
|
||||||
|
// in 8/16/32/64-bit forms using the b,w,l,q suffixes respectively.
|
||||||
|
const char *Suffixes = Base[0] != 'f' ? "bwlq" : "slt\0";
|
||||||
|
|
||||||
// Check for the various suffix matches.
|
// Check for the various suffix matches.
|
||||||
Tmp[Base.size()] = 'b';
|
Tmp[Base.size()] = Suffixes[0];
|
||||||
unsigned BErrorInfo, WErrorInfo, LErrorInfo, QErrorInfo;
|
unsigned ErrorInfoIgnore;
|
||||||
MatchResultTy MatchB = MatchInstructionImpl(Operands, Inst, BErrorInfo);
|
MatchResultTy Match1, Match2, Match3, Match4;
|
||||||
Tmp[Base.size()] = 'w';
|
|
||||||
MatchResultTy MatchW = MatchInstructionImpl(Operands, Inst, WErrorInfo);
|
Match1 = MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore);
|
||||||
Tmp[Base.size()] = 'l';
|
Tmp[Base.size()] = Suffixes[1];
|
||||||
MatchResultTy MatchL = MatchInstructionImpl(Operands, Inst, LErrorInfo);
|
Match2 = MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore);
|
||||||
Tmp[Base.size()] = 'q';
|
Tmp[Base.size()] = Suffixes[2];
|
||||||
MatchResultTy MatchQ = MatchInstructionImpl(Operands, Inst, QErrorInfo);
|
Match3 = MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore);
|
||||||
|
Tmp[Base.size()] = Suffixes[3];
|
||||||
|
Match4 = MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore);
|
||||||
|
|
||||||
// Restore the old token.
|
// Restore the old token.
|
||||||
Op->setTokenValue(Base);
|
Op->setTokenValue(Base);
|
||||||
@ -1020,8 +1022,8 @@ MatchAndEmitInstruction(SMLoc IDLoc,
|
|||||||
// instruction will already have been filled in correctly, since the failing
|
// instruction will already have been filled in correctly, since the failing
|
||||||
// matches won't have modified it).
|
// matches won't have modified it).
|
||||||
unsigned NumSuccessfulMatches =
|
unsigned NumSuccessfulMatches =
|
||||||
(MatchB == Match_Success) + (MatchW == Match_Success) +
|
(Match1 == Match_Success) + (Match2 == Match_Success) +
|
||||||
(MatchL == Match_Success) + (MatchQ == Match_Success);
|
(Match3 == Match_Success) + (Match4 == Match_Success);
|
||||||
if (NumSuccessfulMatches == 1) {
|
if (NumSuccessfulMatches == 1) {
|
||||||
Out.EmitInstruction(Inst);
|
Out.EmitInstruction(Inst);
|
||||||
return false;
|
return false;
|
||||||
@ -1034,14 +1036,10 @@ MatchAndEmitInstruction(SMLoc IDLoc,
|
|||||||
if (NumSuccessfulMatches > 1) {
|
if (NumSuccessfulMatches > 1) {
|
||||||
char MatchChars[4];
|
char MatchChars[4];
|
||||||
unsigned NumMatches = 0;
|
unsigned NumMatches = 0;
|
||||||
if (MatchB == Match_Success)
|
if (Match1 == Match_Success) MatchChars[NumMatches++] = Suffixes[0];
|
||||||
MatchChars[NumMatches++] = 'b';
|
if (Match2 == Match_Success) MatchChars[NumMatches++] = Suffixes[1];
|
||||||
if (MatchW == Match_Success)
|
if (Match3 == Match_Success) MatchChars[NumMatches++] = Suffixes[2];
|
||||||
MatchChars[NumMatches++] = 'w';
|
if (Match4 == Match_Success) MatchChars[NumMatches++] = Suffixes[3];
|
||||||
if (MatchL == Match_Success)
|
|
||||||
MatchChars[NumMatches++] = 'l';
|
|
||||||
if (MatchQ == Match_Success)
|
|
||||||
MatchChars[NumMatches++] = 'q';
|
|
||||||
|
|
||||||
SmallString<126> Msg;
|
SmallString<126> Msg;
|
||||||
raw_svector_ostream OS(Msg);
|
raw_svector_ostream OS(Msg);
|
||||||
@ -1062,8 +1060,8 @@ MatchAndEmitInstruction(SMLoc IDLoc,
|
|||||||
|
|
||||||
// If all of the instructions reported an invalid mnemonic, then the original
|
// If all of the instructions reported an invalid mnemonic, then the original
|
||||||
// mnemonic was invalid.
|
// mnemonic was invalid.
|
||||||
if ((MatchB == Match_MnemonicFail) && (MatchW == Match_MnemonicFail) &&
|
if ((Match1 == Match_MnemonicFail) && (Match2 == Match_MnemonicFail) &&
|
||||||
(MatchL == Match_MnemonicFail) && (MatchQ == Match_MnemonicFail)) {
|
(Match3 == Match_MnemonicFail) && (Match4 == Match_MnemonicFail)) {
|
||||||
if (!WasOriginallyInvalidOperand) {
|
if (!WasOriginallyInvalidOperand) {
|
||||||
Error(IDLoc, "invalid instruction mnemonic '" + Base + "'");
|
Error(IDLoc, "invalid instruction mnemonic '" + Base + "'");
|
||||||
return true;
|
return true;
|
||||||
@ -1084,16 +1082,16 @@ MatchAndEmitInstruction(SMLoc IDLoc,
|
|||||||
|
|
||||||
// If one instruction matched with a missing feature, report this as a
|
// If one instruction matched with a missing feature, report this as a
|
||||||
// missing feature.
|
// missing feature.
|
||||||
if ((MatchB == Match_MissingFeature) + (MatchW == Match_MissingFeature) +
|
if ((Match1 == Match_MissingFeature) + (Match2 == Match_MissingFeature) +
|
||||||
(MatchL == Match_MissingFeature) + (MatchQ == Match_MissingFeature) == 1){
|
(Match3 == Match_MissingFeature) + (Match4 == Match_MissingFeature) == 1){
|
||||||
Error(IDLoc, "instruction requires a CPU feature not currently enabled");
|
Error(IDLoc, "instruction requires a CPU feature not currently enabled");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If one instruction matched with an invalid operand, report this as an
|
// If one instruction matched with an invalid operand, report this as an
|
||||||
// operand failure.
|
// operand failure.
|
||||||
if ((MatchB == Match_InvalidOperand) + (MatchW == Match_InvalidOperand) +
|
if ((Match1 == Match_InvalidOperand) + (Match2 == Match_InvalidOperand) +
|
||||||
(MatchL == Match_InvalidOperand) + (MatchQ == Match_InvalidOperand) == 1){
|
(Match3 == Match_InvalidOperand) + (Match4 == Match_InvalidOperand) == 1){
|
||||||
Error(IDLoc, "invalid operand for instruction");
|
Error(IDLoc, "invalid operand for instruction");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -331,11 +331,6 @@ enter $0x7ace,$1
|
|||||||
enter $0x7ace,$0x7f
|
enter $0x7ace,$0x7f
|
||||||
|
|
||||||
|
|
||||||
// rdar://8456389
|
|
||||||
// CHECK: fstps (%eax)
|
|
||||||
// CHECK: encoding: [0x67,0xd9,0x18]
|
|
||||||
fstp (%eax)
|
|
||||||
|
|
||||||
// rdar://8456364
|
// rdar://8456364
|
||||||
// CHECK: movw %cs, %ax
|
// CHECK: movw %cs, %ax
|
||||||
mov %CS, %ax
|
mov %CS, %ax
|
||||||
|
Loading…
Reference in New Issue
Block a user