From 60091cfeb9c827187d8877aaef600bdea3d5c17d Mon Sep 17 00:00:00 2001 From: Tim Northover Date: Thu, 15 May 2014 13:36:01 +0000 Subject: [PATCH] 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 --- .../ARM64/InstPrinter/ARM64InstPrinter.cpp | 16 ---------- llvm/lib/Target/X86/X86InstrInfo.td | 30 +++++++++---------- llvm/lib/Target/X86/X86InstrSSE.td | 8 ++--- llvm/utils/TableGen/AsmWriterEmitter.cpp | 26 ++++++++++------ llvm/utils/TableGen/CodeGenInstruction.cpp | 17 +++++++++++ llvm/utils/TableGen/CodeGenInstruction.h | 2 ++ 6 files changed, 55 insertions(+), 44 deletions(-) diff --git a/llvm/lib/Target/ARM64/InstPrinter/ARM64InstPrinter.cpp b/llvm/lib/Target/ARM64/InstPrinter/ARM64InstPrinter.cpp index f7b358d4f427..9ca8ce45cb75 100644 --- a/llvm/lib/Target/ARM64/InstPrinter/ARM64InstPrinter.cpp +++ b/llvm/lib/Target/ARM64/InstPrinter/ARM64InstPrinter.cpp @@ -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) || diff --git a/llvm/lib/Target/X86/X86InstrInfo.td b/llvm/lib/Target/X86/X86InstrInfo.td index d1da18372502..ac7805f1cccb 100644 --- a/llvm/lib/Target/X86/X86InstrInfo.td +++ b/llvm/lib/Target/X86/X86InstrInfo.td @@ -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 , B" is an alias for "imul , B, B". @@ -2726,7 +2726,7 @@ def : InstAlias<"outl\t$port", (OUT32ir i8imm:$port), 0>; // 'sldt ' 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>; diff --git a/llvm/lib/Target/X86/X86InstrSSE.td b/llvm/lib/Target/X86/X86InstrSSE.td index feccf1bde370..ac28d07cc683 100644 --- a/llvm/lib/Target/X86/X86InstrSSE.td +++ b/llvm/lib/Target/X86/X86InstrSSE.td @@ -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). diff --git a/llvm/utils/TableGen/AsmWriterEmitter.cpp b/llvm/utils/TableGen/AsmWriterEmitter.cpp index 77d92c3cb40c..617aa827376a 100644 --- a/llvm/utils/TableGen/AsmWriterEmitter.cpp +++ b/llvm/utils/TableGen/AsmWriterEmitter.cpp @@ -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; diff --git a/llvm/utils/TableGen/CodeGenInstruction.cpp b/llvm/utils/TableGen/CodeGenInstruction.cpp index c924ce8d836b..2577ad4d919d 100644 --- a/llvm/utils/TableGen/CodeGenInstruction.cpp +++ b/llvm/utils/TableGen/CodeGenInstruction.cpp @@ -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) { diff --git a/llvm/utils/TableGen/CodeGenInstruction.h b/llvm/utils/TableGen/CodeGenInstruction.h index 818d0e1d36d2..f143875131b4 100644 --- a/llvm/utils/TableGen/CodeGenInstruction.h +++ b/llvm/utils/TableGen/CodeGenInstruction.h @@ -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.