mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-16 14:31:59 +00:00
implement more checking to reject things like:
(someinst GR16:$foo, GR32:$foo) Reimplement BuildAliasOperandReference to be correctly based on the names of operands in the result pattern, instead of on the instruction operand definitions. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@118328 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
d0f225cafc
commit
3f2c8e474b
@ -1160,47 +1160,24 @@ BuildInstructionOperandReference(MatchableInfo *II,
|
||||
Op.SrcOpName = OperandName;
|
||||
}
|
||||
|
||||
/// BuildAliasOperandReference - When parsing an operand reference out of the
|
||||
/// matching string (e.g. "movsx $src, $dst"), determine what the class of the
|
||||
/// operand reference is by looking it up in the result pattern definition.
|
||||
void AsmMatcherInfo::BuildAliasOperandReference(MatchableInfo *II,
|
||||
StringRef OperandName,
|
||||
MatchableInfo::AsmOperand &Op) {
|
||||
const CodeGenInstAlias &CGA = *II->DefRec.get<const CodeGenInstAlias*>();
|
||||
|
||||
|
||||
// FIXME: This is a total hack, it should not be a copy of
|
||||
// BuildInstructionOperandReference
|
||||
|
||||
const CGIOperandList &Operands = CGA.Operands;
|
||||
|
||||
// Map this token to an operand. FIXME: Move elsewhere.
|
||||
unsigned Idx;
|
||||
if (!Operands.hasOperandNamed(OperandName, Idx))
|
||||
throw TGError(II->TheDef->getLoc(), "error: unable to find operand: '" +
|
||||
OperandName.str() + "'");
|
||||
|
||||
// Set up the operand class.
|
||||
Op.Class = getOperandClass(Operands[Idx]);
|
||||
|
||||
// If the named operand is tied, canonicalize it to the untied operand.
|
||||
// For example, something like:
|
||||
// (outs GPR:$dst), (ins GPR:$src)
|
||||
// with an asmstring of
|
||||
// "inc $src"
|
||||
// we want to canonicalize to:
|
||||
// "inc $dst"
|
||||
// so that we know how to provide the $dst operand when filling in the result.
|
||||
int OITied = Operands[Idx].getTiedRegister();
|
||||
if (OITied != -1) {
|
||||
// The tied operand index is an MIOperand index, find the operand that
|
||||
// contains it.
|
||||
for (unsigned i = 0, e = Operands.size(); i != e; ++i) {
|
||||
if (Operands[i].MIOperandNo == unsigned(OITied)) {
|
||||
OperandName = Operands[i].Name;
|
||||
break;
|
||||
}
|
||||
for (unsigned i = 0, e = CGA.ResultOperands.size(); i != e; ++i)
|
||||
if (CGA.ResultOperands[i].Name == OperandName) {
|
||||
Op.Class = getOperandClass(CGA.ResultInst->Operands[i]);
|
||||
Op.SrcOpName = OperandName;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Op.SrcOpName = OperandName;
|
||||
|
||||
throw TGError(II->TheDef->getLoc(), "error: unable to find operand: '" +
|
||||
OperandName.str() + "'");
|
||||
}
|
||||
|
||||
void MatchableInfo::BuildResultOperands() {
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "CodeGenTarget.h"
|
||||
#include "Record.h"
|
||||
#include "llvm/ADT/StringExtras.h"
|
||||
#include "llvm/ADT/StringMap.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include <set>
|
||||
using namespace llvm;
|
||||
@ -407,6 +408,10 @@ CodeGenInstAlias::CodeGenInstAlias(Record *R, CodeGenTarget &T)
|
||||
" arguments, but " + ResultInst->TheDef->getName() +
|
||||
" instruction expects " + utostr(ResultInst->Operands.size())+
|
||||
" operands!");
|
||||
|
||||
// NameClass - If argument names are repeated, we need to verify they have
|
||||
// the same class.
|
||||
StringMap<Record*> NameClass;
|
||||
|
||||
// Decode and validate the arguments of the result.
|
||||
for (unsigned i = 0, e = Result->getNumArgs(); i != e; ++i) {
|
||||
@ -425,6 +430,15 @@ CodeGenInstAlias::CodeGenInstAlias(Record *R, CodeGenTarget &T)
|
||||
", instruction operand is class " +
|
||||
ResultInst->Operands[i].Rec->getName());
|
||||
|
||||
// Verify we don't have something like: (someinst GR16:$foo, GR32:$foo)
|
||||
// $foo can exist multiple times in the result list, but it must have the
|
||||
// same type.
|
||||
Record *&Entry = NameClass[Result->getArgName(i)];
|
||||
if (Entry && Entry != ADI->getDef())
|
||||
throw TGError(R->getLoc(), "result value $" + Result->getArgName(i) +
|
||||
" is both " + Entry->getName() + " and " +
|
||||
ADI->getDef()->getName() + "!");
|
||||
|
||||
// Now that it is validated, add it.
|
||||
ResultOperands.push_back(ResultOperand(Result->getArgName(i),
|
||||
ADI->getDef()));
|
||||
|
Loading…
x
Reference in New Issue
Block a user