mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-13 23:18:58 +00:00
Correctly handle physical register inputs. They are not explicit input operands in the resulting machine instrs.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@55893 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
5960e4eb68
commit
98d2d07d41
11
test/CodeGen/X86/fast-isel-phys.ll
Normal file
11
test/CodeGen/X86/fast-isel-phys.ll
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
; RUN: llvm-as < %s | llc -fast-isel -march=x86
|
||||||
|
|
||||||
|
define i8 @t2(i8 %a, i8 %c) nounwind {
|
||||||
|
%tmp = shl i8 %a, %c
|
||||||
|
ret i8 %tmp
|
||||||
|
}
|
||||||
|
|
||||||
|
define i8 @t1(i8 %a) nounwind {
|
||||||
|
%tmp = mul i8 %a, 17
|
||||||
|
ret i8 %tmp
|
||||||
|
}
|
@ -114,7 +114,7 @@ struct OperandsSignature {
|
|||||||
return false;
|
return false;
|
||||||
Record *OpLeafRec = OpDI->getDef();
|
Record *OpLeafRec = OpDI->getDef();
|
||||||
// For now, the only other thing we accept is register operands.
|
// For now, the only other thing we accept is register operands.
|
||||||
|
|
||||||
const CodeGenRegisterClass *RC = 0;
|
const CodeGenRegisterClass *RC = 0;
|
||||||
if (OpLeafRec->isSubClassOf("RegisterClass"))
|
if (OpLeafRec->isSubClassOf("RegisterClass"))
|
||||||
RC = &Target.getRegisterClass(OpLeafRec);
|
RC = &Target.getRegisterClass(OpLeafRec);
|
||||||
@ -157,21 +157,27 @@ struct OperandsSignature {
|
|||||||
void PrintArguments(std::ostream &OS,
|
void PrintArguments(std::ostream &OS,
|
||||||
const std::vector<std::string>& PR) const {
|
const std::vector<std::string>& PR) const {
|
||||||
assert(PR.size() == Operands.size());
|
assert(PR.size() == Operands.size());
|
||||||
|
bool PrintedArg = false;
|
||||||
for (unsigned i = 0, e = Operands.size(); i != e; ++i) {
|
for (unsigned i = 0, e = Operands.size(); i != e; ++i) {
|
||||||
if (PR[i] != "") {
|
if (PR[i] != "")
|
||||||
OS << PR[i];
|
// Implicit physical register operand.
|
||||||
} else if (Operands[i] == "r") {
|
continue;
|
||||||
|
|
||||||
|
if (PrintedArg)
|
||||||
|
OS << ", ";
|
||||||
|
if (Operands[i] == "r") {
|
||||||
OS << "Op" << i;
|
OS << "Op" << i;
|
||||||
|
PrintedArg = true;
|
||||||
} else if (Operands[i] == "i") {
|
} else if (Operands[i] == "i") {
|
||||||
OS << "imm" << i;
|
OS << "imm" << i;
|
||||||
|
PrintedArg = true;
|
||||||
} else if (Operands[i] == "f") {
|
} else if (Operands[i] == "f") {
|
||||||
OS << "f" << i;
|
OS << "f" << i;
|
||||||
|
PrintedArg = true;
|
||||||
} else {
|
} else {
|
||||||
assert("Unknown operand kind!");
|
assert("Unknown operand kind!");
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
if (i + 1 != e)
|
|
||||||
OS << ", ";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -193,6 +199,20 @@ struct OperandsSignature {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PrintManglingSuffix(std::ostream &OS,
|
||||||
|
const std::vector<std::string>& PR) const {
|
||||||
|
for (unsigned i = 0, e = Operands.size(); i != e; ++i) {
|
||||||
|
if (PR[i] != "")
|
||||||
|
// Implicit physical register operand. e.g. Instruction::Mul expect to
|
||||||
|
// select to a binary op. On x86, mul may take a single operand with
|
||||||
|
// the other operand being implicit. We must emit something that looks
|
||||||
|
// like a binary instruction except for the very inner FastEmitInst_*
|
||||||
|
// call.
|
||||||
|
continue;
|
||||||
|
OS << Operands[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void PrintManglingSuffix(std::ostream &OS) const {
|
void PrintManglingSuffix(std::ostream &OS) const {
|
||||||
for (unsigned i = 0, e = Operands.size(); i != e; ++i) {
|
for (unsigned i = 0, e = Operands.size(); i != e; ++i) {
|
||||||
OS << Operands[i];
|
OS << Operands[i];
|
||||||
@ -430,7 +450,7 @@ void FastISelMap::PrintFunctionDefinitions(std::ostream &OS) {
|
|||||||
|
|
||||||
OS << " return FastEmitInst_";
|
OS << " return FastEmitInst_";
|
||||||
if (Memo.SubRegNo == (unsigned char)~0) {
|
if (Memo.SubRegNo == (unsigned char)~0) {
|
||||||
Operands.PrintManglingSuffix(OS);
|
Operands.PrintManglingSuffix(OS, *Memo.PhysRegs);
|
||||||
OS << "(" << InstNS << Memo.Name << ", ";
|
OS << "(" << InstNS << Memo.Name << ", ";
|
||||||
OS << InstNS << Memo.RC->getName() << "RegisterClass";
|
OS << InstNS << Memo.RC->getName() << "RegisterClass";
|
||||||
if (!Operands.empty())
|
if (!Operands.empty())
|
||||||
@ -497,7 +517,8 @@ void FastISelMap::PrintFunctionDefinitions(std::ostream &OS) {
|
|||||||
|
|
||||||
// Emit code for each possible instruction. There may be
|
// Emit code for each possible instruction. There may be
|
||||||
// multiple if there are subtarget concerns.
|
// multiple if there are subtarget concerns.
|
||||||
for (PredMap::const_iterator PI = PM.begin(), PE = PM.end(); PI != PE; ++PI) {
|
for (PredMap::const_iterator PI = PM.begin(), PE = PM.end(); PI != PE;
|
||||||
|
++PI) {
|
||||||
std::string PredicateCheck = PI->first;
|
std::string PredicateCheck = PI->first;
|
||||||
const InstructionMemo &Memo = PI->second;
|
const InstructionMemo &Memo = PI->second;
|
||||||
|
|
||||||
@ -523,7 +544,7 @@ void FastISelMap::PrintFunctionDefinitions(std::ostream &OS) {
|
|||||||
OS << " return FastEmitInst_";
|
OS << " return FastEmitInst_";
|
||||||
|
|
||||||
if (Memo.SubRegNo == (unsigned char)~0) {
|
if (Memo.SubRegNo == (unsigned char)~0) {
|
||||||
Operands.PrintManglingSuffix(OS);
|
Operands.PrintManglingSuffix(OS, *Memo.PhysRegs);
|
||||||
OS << "(" << InstNS << Memo.Name << ", ";
|
OS << "(" << InstNS << Memo.Name << ", ";
|
||||||
OS << InstNS << Memo.RC->getName() << "RegisterClass";
|
OS << InstNS << Memo.RC->getName() << "RegisterClass";
|
||||||
if (!Operands.empty())
|
if (!Operands.empty())
|
||||||
|
Loading…
Reference in New Issue
Block a user