forked from OSchip/llvm-project
TableGen: use correct MIOperand when printing aliases
Previously, TableGen assumed that every aliased operand consumed precisely 1 MachineInstr slot (this was reasonable because until a couple of days ago, nothing more complicated was eligible for printing). This allows a couple more ARM64 aliases to print so we can remove the special code. On the X86 side, I've gone for explicit AT&T size specifiers as the default, so turned off a few of the aliases that would have just started printing. llvm-svn: 208880
This commit is contained in:
parent
cb7f9c40f8
commit
60091cfeb9
|
@ -240,14 +240,6 @@ void ARM64InstPrinter::printInst(const MCInst *MI, raw_ostream &O,
|
|||
printShiftedRegister(MI, 2, O);
|
||||
return;
|
||||
}
|
||||
// SUBS WZR, Wn, #imm ==> CMP Wn, #imm
|
||||
// SUBS XZR, Xn, #imm ==> CMP Xn, #imm
|
||||
if ((Opcode == ARM64::SUBSWri && MI->getOperand(0).getReg() == ARM64::WZR) ||
|
||||
(Opcode == ARM64::SUBSXri && MI->getOperand(0).getReg() == ARM64::XZR)) {
|
||||
O << "\tcmp\t" << getRegisterName(MI->getOperand(1).getReg()) << ", ";
|
||||
printAddSubImm(MI, 2, O);
|
||||
return;
|
||||
}
|
||||
// SUBS WZR, Wn, Wm{, lshift #imm} ==> CMP Wn, Wm{, lshift #imm}
|
||||
// SUBS XZR, Xn, Xm{, lshift #imm} ==> CMP Xn, Xm{, lshift #imm}
|
||||
if ((Opcode == ARM64::SUBSWrs && MI->getOperand(0).getReg() == ARM64::WZR) ||
|
||||
|
@ -272,14 +264,6 @@ void ARM64InstPrinter::printInst(const MCInst *MI, raw_ostream &O,
|
|||
return;
|
||||
}
|
||||
|
||||
// ADDS WZR, Wn, #imm ==> CMN Wn, #imm
|
||||
// ADDS XZR, Xn, #imm ==> CMN Xn, #imm
|
||||
if ((Opcode == ARM64::ADDSWri && MI->getOperand(0).getReg() == ARM64::WZR) ||
|
||||
(Opcode == ARM64::ADDSXri && MI->getOperand(0).getReg() == ARM64::XZR)) {
|
||||
O << "\tcmn\t" << getRegisterName(MI->getOperand(1).getReg()) << ", ";
|
||||
printAddSubImm(MI, 2, O);
|
||||
return;
|
||||
}
|
||||
// ADDS WZR, Wn, Wm{, lshift #imm} ==> CMN Wn, Wm{, lshift #imm}
|
||||
// ADDS XZR, Xn, Xm{, lshift #imm} ==> CMN Xn, Xm{, lshift #imm}
|
||||
if ((Opcode == ARM64::ADDSWrs && MI->getOperand(0).getReg() == ARM64::WZR) ||
|
||||
|
|
|
@ -2638,21 +2638,21 @@ def : InstAlias<"fnstsw" , (FNSTSW16r)>;
|
|||
|
||||
// lcall and ljmp aliases. This seems to be an odd mapping in 64-bit mode, but
|
||||
// this is compatible with what GAS does.
|
||||
def : InstAlias<"lcall $seg, $off", (FARCALL32i i32imm:$off, i16imm:$seg)>, Requires<[Not16BitMode]>;
|
||||
def : InstAlias<"ljmp $seg, $off", (FARJMP32i i32imm:$off, i16imm:$seg)>, Requires<[Not16BitMode]>;
|
||||
def : InstAlias<"lcall *$dst", (FARCALL32m opaque48mem:$dst)>, Requires<[Not16BitMode]>;
|
||||
def : InstAlias<"ljmp *$dst", (FARJMP32m opaque48mem:$dst)>, Requires<[Not16BitMode]>;
|
||||
def : InstAlias<"lcall $seg, $off", (FARCALL16i i16imm:$off, i16imm:$seg)>, Requires<[In16BitMode]>;
|
||||
def : InstAlias<"ljmp $seg, $off", (FARJMP16i i16imm:$off, i16imm:$seg)>, Requires<[In16BitMode]>;
|
||||
def : InstAlias<"lcall *$dst", (FARCALL16m opaque32mem:$dst)>, Requires<[In16BitMode]>;
|
||||
def : InstAlias<"ljmp *$dst", (FARJMP16m opaque32mem:$dst)>, Requires<[In16BitMode]>;
|
||||
def : InstAlias<"lcall $seg, $off", (FARCALL32i i32imm:$off, i16imm:$seg), 0>, Requires<[Not16BitMode]>;
|
||||
def : InstAlias<"ljmp $seg, $off", (FARJMP32i i32imm:$off, i16imm:$seg), 0>, Requires<[Not16BitMode]>;
|
||||
def : InstAlias<"lcall *$dst", (FARCALL32m opaque48mem:$dst), 0>, Requires<[Not16BitMode]>;
|
||||
def : InstAlias<"ljmp *$dst", (FARJMP32m opaque48mem:$dst), 0>, Requires<[Not16BitMode]>;
|
||||
def : InstAlias<"lcall $seg, $off", (FARCALL16i i16imm:$off, i16imm:$seg), 0>, Requires<[In16BitMode]>;
|
||||
def : InstAlias<"ljmp $seg, $off", (FARJMP16i i16imm:$off, i16imm:$seg), 0>, Requires<[In16BitMode]>;
|
||||
def : InstAlias<"lcall *$dst", (FARCALL16m opaque32mem:$dst), 0>, Requires<[In16BitMode]>;
|
||||
def : InstAlias<"ljmp *$dst", (FARJMP16m opaque32mem:$dst), 0>, Requires<[In16BitMode]>;
|
||||
|
||||
def : InstAlias<"call *$dst", (CALL64m i16mem:$dst)>, Requires<[In64BitMode]>;
|
||||
def : InstAlias<"jmp *$dst", (JMP64m i16mem:$dst)>, Requires<[In64BitMode]>;
|
||||
def : InstAlias<"call *$dst", (CALL32m i16mem:$dst)>, Requires<[In32BitMode]>;
|
||||
def : InstAlias<"jmp *$dst", (JMP32m i16mem:$dst)>, Requires<[In32BitMode]>;
|
||||
def : InstAlias<"call *$dst", (CALL16m i16mem:$dst)>, Requires<[In16BitMode]>;
|
||||
def : InstAlias<"jmp *$dst", (JMP16m i16mem:$dst)>, Requires<[In16BitMode]>;
|
||||
def : InstAlias<"call *$dst", (CALL64m i16mem:$dst), 0>, Requires<[In64BitMode]>;
|
||||
def : InstAlias<"jmp *$dst", (JMP64m i16mem:$dst), 0>, Requires<[In64BitMode]>;
|
||||
def : InstAlias<"call *$dst", (CALL32m i16mem:$dst), 0>, Requires<[In32BitMode]>;
|
||||
def : InstAlias<"jmp *$dst", (JMP32m i16mem:$dst), 0>, Requires<[In32BitMode]>;
|
||||
def : InstAlias<"call *$dst", (CALL16m i16mem:$dst), 0>, Requires<[In16BitMode]>;
|
||||
def : InstAlias<"jmp *$dst", (JMP16m i16mem:$dst), 0>, Requires<[In16BitMode]>;
|
||||
|
||||
|
||||
// "imul <imm>, B" is an alias for "imul <imm>, B, B".
|
||||
|
@ -2726,7 +2726,7 @@ def : InstAlias<"outl\t$port", (OUT32ir i8imm:$port), 0>;
|
|||
// 'sldt <mem>' can be encoded with either sldtw or sldtq with the same
|
||||
// effect (both store to a 16-bit mem). Force to sldtw to avoid ambiguity
|
||||
// errors, since its encoding is the most compact.
|
||||
def : InstAlias<"sldt $mem", (SLDT16m i16mem:$mem)>;
|
||||
def : InstAlias<"sldt $mem", (SLDT16m i16mem:$mem), 0>;
|
||||
|
||||
// shld/shrd op,op -> shld op, op, CL
|
||||
def : InstAlias<"shld{w}\t{$r2, $r1|$r1, $r2}", (SHLD16rrCL GR16:$r1, GR16:$r2), 0>;
|
||||
|
|
|
@ -1561,9 +1561,9 @@ defm VCVTSI2SD64 : sse12_vcvt_avx<0x2A, GR64, FR64, i64mem, "cvtsi2sd{q}">,
|
|||
|
||||
let Predicates = [UseAVX] in {
|
||||
def : InstAlias<"vcvtsi2ss\t{$src, $src1, $dst|$dst, $src1, $src}",
|
||||
(VCVTSI2SSrm FR64:$dst, FR64:$src1, i32mem:$src)>;
|
||||
(VCVTSI2SSrm FR64:$dst, FR64:$src1, i32mem:$src), 0>;
|
||||
def : InstAlias<"vcvtsi2sd\t{$src, $src1, $dst|$dst, $src1, $src}",
|
||||
(VCVTSI2SDrm FR64:$dst, FR64:$src1, i32mem:$src)>;
|
||||
(VCVTSI2SDrm FR64:$dst, FR64:$src1, i32mem:$src), 0>;
|
||||
|
||||
def : Pat<(f32 (sint_to_fp (loadi32 addr:$src))),
|
||||
(VCVTSI2SSrm (f32 (IMPLICIT_DEF)), addr:$src)>;
|
||||
|
@ -1627,9 +1627,9 @@ def : InstAlias<"cvttsd2si{q}\t{$src, $dst|$dst, $src}",
|
|||
(CVTTSD2SI64rm GR64:$dst, f64mem:$src), 0>;
|
||||
|
||||
def : InstAlias<"cvtsi2ss\t{$src, $dst|$dst, $src}",
|
||||
(CVTSI2SSrm FR64:$dst, i32mem:$src)>;
|
||||
(CVTSI2SSrm FR64:$dst, i32mem:$src), 0>;
|
||||
def : InstAlias<"cvtsi2sd\t{$src, $dst|$dst, $src}",
|
||||
(CVTSI2SDrm FR64:$dst, i32mem:$src)>;
|
||||
(CVTSI2SDrm FR64:$dst, i32mem:$src), 0>;
|
||||
|
||||
// Conversion Instructions Intrinsics - Match intrinsics which expect MM
|
||||
// and/or XMM operand(s).
|
||||
|
|
|
@ -827,12 +827,17 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
|
|||
IAPrinter *IAP = new IAPrinter(CGA->Result->getAsString(),
|
||||
CGA->AsmString);
|
||||
|
||||
unsigned NumMIOps = 0;
|
||||
for (auto &Operand : CGA->ResultOperands)
|
||||
NumMIOps += Operand.getMINumOperands();
|
||||
|
||||
std::string Cond;
|
||||
Cond = std::string("MI->getNumOperands() == ") + llvm::utostr(LastOpNo);
|
||||
Cond = std::string("MI->getNumOperands() == ") + llvm::utostr(NumMIOps);
|
||||
IAP->addCond(Cond);
|
||||
|
||||
bool CantHandle = false;
|
||||
|
||||
unsigned MIOpNum = 0;
|
||||
for (unsigned i = 0, e = LastOpNo; i != e; ++i) {
|
||||
const CodeGenInstAlias::ResultOperand &RO = CGA->ResultOperands[i];
|
||||
|
||||
|
@ -860,34 +865,36 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
|
|||
if (Rec->isSubClassOf("RegisterOperand"))
|
||||
Rec = Rec->getValueAsDef("RegClass");
|
||||
if (Rec->isSubClassOf("RegisterClass")) {
|
||||
Cond = std::string("MI->getOperand(")+llvm::utostr(i)+").isReg()";
|
||||
Cond = std::string("MI->getOperand(") + llvm::utostr(MIOpNum) +
|
||||
").isReg()";
|
||||
IAP->addCond(Cond);
|
||||
|
||||
if (!IAP->isOpMapped(ROName)) {
|
||||
IAP->addOperand(ROName, i, PrintMethodIdx);
|
||||
IAP->addOperand(ROName, MIOpNum, PrintMethodIdx);
|
||||
Record *R = CGA->ResultOperands[i].getRecord();
|
||||
if (R->isSubClassOf("RegisterOperand"))
|
||||
R = R->getValueAsDef("RegClass");
|
||||
Cond = std::string("MRI.getRegClass(") + Target.getName() + "::" +
|
||||
R->getName() + "RegClassID)"
|
||||
".contains(MI->getOperand(" + llvm::utostr(i) + ").getReg())";
|
||||
R->getName() + "RegClassID)"
|
||||
".contains(MI->getOperand(" +
|
||||
llvm::utostr(MIOpNum) + ").getReg())";
|
||||
IAP->addCond(Cond);
|
||||
} else {
|
||||
Cond = std::string("MI->getOperand(") +
|
||||
llvm::utostr(i) + ").getReg() == MI->getOperand(" +
|
||||
llvm::utostr(MIOpNum) + ").getReg() == MI->getOperand(" +
|
||||
llvm::utostr(IAP->getOpIndex(ROName)) + ").getReg()";
|
||||
IAP->addCond(Cond);
|
||||
}
|
||||
} else {
|
||||
// Assume all printable operands are desired for now. This can be
|
||||
// overridden in the InstAlias instantiation if necessary.
|
||||
IAP->addOperand(ROName, i, PrintMethodIdx);
|
||||
IAP->addOperand(ROName, MIOpNum, PrintMethodIdx);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case CodeGenInstAlias::ResultOperand::K_Imm: {
|
||||
std::string Op = "MI->getOperand(" + llvm::utostr(i) + ")";
|
||||
std::string Op = "MI->getOperand(" + llvm::utostr(MIOpNum) + ")";
|
||||
|
||||
// Just because the alias has an immediate result, doesn't mean the
|
||||
// MCInst will. An MCExpr could be present, for example.
|
||||
|
@ -907,13 +914,14 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
|
|||
}
|
||||
|
||||
Cond = std::string("MI->getOperand(") +
|
||||
llvm::utostr(i) + ").getReg() == " + Target.getName() +
|
||||
llvm::utostr(MIOpNum) + ").getReg() == " + Target.getName() +
|
||||
"::" + CGA->ResultOperands[i].getRegister()->getName();
|
||||
IAP->addCond(Cond);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!IAP) break;
|
||||
MIOpNum += RO.getMINumOperands();
|
||||
}
|
||||
|
||||
if (CantHandle) continue;
|
||||
|
|
|
@ -536,6 +536,23 @@ bool CodeGenInstAlias::tryAliasOpMatch(DagInit *Result, unsigned AliasOpNo,
|
|||
return false;
|
||||
}
|
||||
|
||||
unsigned CodeGenInstAlias::ResultOperand::getMINumOperands() const {
|
||||
if (!isRecord())
|
||||
return 1;
|
||||
|
||||
Record *Rec = getRecord();
|
||||
if (!Rec->isSubClassOf("Operand"))
|
||||
return 1;
|
||||
|
||||
DagInit *MIOpInfo = Rec->getValueAsDag("MIOperandInfo");
|
||||
if (MIOpInfo->getNumArgs() == 0) {
|
||||
// Unspecified, so it defaults to 1
|
||||
return 1;
|
||||
}
|
||||
|
||||
return MIOpInfo->getNumArgs();
|
||||
}
|
||||
|
||||
CodeGenInstAlias::CodeGenInstAlias(Record *R, unsigned Variant,
|
||||
CodeGenTarget &T)
|
||||
: TheDef(R) {
|
||||
|
|
|
@ -324,6 +324,8 @@ namespace llvm {
|
|||
Record *getRecord() const { assert(isRecord()); return R; }
|
||||
int64_t getImm() const { assert(isImm()); return Imm; }
|
||||
Record *getRegister() const { assert(isReg()); return R; }
|
||||
|
||||
unsigned getMINumOperands() const;
|
||||
};
|
||||
|
||||
/// ResultOperands - The decoded operands for the result instruction.
|
||||
|
|
Loading…
Reference in New Issue