From 796975d3117e12fbf86c050d8be6d87a0c178da3 Mon Sep 17 00:00:00 2001 From: Jacques Pienaar Date: Sun, 3 Apr 2016 00:49:27 +0000 Subject: [PATCH] [lanai] Fix for LanaiDelaySlotFiller and LanaiMCInstLower.cpp Summary: * Fix to stop delay slot filler from inserting SP modifying instructions in the newly expanded call/return instructions. * In LowerSymbol the outermost type was not LanaiMCExpr if there was a binary expression * Remove printExpr in LanaiInstPrinter Subscribers: joker.eph, llvm-commits Differential Revision: http://reviews.llvm.org/D18734 llvm-svn: 265251 --- .../Lanai/InstPrinter/LanaiInstPrinter.cpp | 179 ++++++++---------- .../lib/Target/Lanai/LanaiDelaySlotFiller.cpp | 7 + llvm/lib/Target/Lanai/LanaiMCInstLower.cpp | 5 +- 3 files changed, 87 insertions(+), 104 deletions(-) diff --git a/llvm/lib/Target/Lanai/InstPrinter/LanaiInstPrinter.cpp b/llvm/lib/Target/Lanai/InstPrinter/LanaiInstPrinter.cpp index 6460b88d142a..2185517e499b 100644 --- a/llvm/lib/Target/Lanai/InstPrinter/LanaiInstPrinter.cpp +++ b/llvm/lib/Target/Lanai/InstPrinter/LanaiInstPrinter.cpp @@ -29,18 +29,17 @@ using namespace llvm; #define PRINT_ALIAS_INSTR #include "LanaiGenAsmWriter.inc" -void LanaiInstPrinter::printRegName(raw_ostream &Ostream, - unsigned RegNo) const { - Ostream << StringRef(getRegisterName(RegNo)).lower(); +void LanaiInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const { + OS << StringRef(getRegisterName(RegNo)).lower(); } -bool LanaiInstPrinter::printInst(const MCInst *MI, raw_ostream &Ostream, +bool LanaiInstPrinter::printInst(const MCInst *MI, raw_ostream &OS, StringRef Alias, unsigned OpNo0, unsigned OpNo1) { - Ostream << "\t" << Alias << " "; - printOperand(MI, OpNo0, Ostream); - Ostream << ", "; - printOperand(MI, OpNo1, Ostream); + OS << "\t" << Alias << " "; + printOperand(MI, OpNo0, OS); + OS << ", "; + printOperand(MI, OpNo1, OS); return true; } @@ -68,191 +67,169 @@ static StringRef decIncOperator(const MCInst *MI) { } bool LanaiInstPrinter::printMemoryLoadIncrement(const MCInst *MI, - raw_ostream &Ostream, + raw_ostream &OS, StringRef Opcode, int AddOffset) { if (isPreIncrementForm(MI, AddOffset)) { - Ostream << "\t" << Opcode << "\t[" << decIncOperator(MI) << "%" - << getRegisterName(MI->getOperand(1).getReg()) << "], %" - << getRegisterName(MI->getOperand(0).getReg()); + OS << "\t" << Opcode << "\t[" << decIncOperator(MI) << "%" + << getRegisterName(MI->getOperand(1).getReg()) << "], %" + << getRegisterName(MI->getOperand(0).getReg()); return true; } if (isPostIncrementForm(MI, AddOffset)) { - Ostream << "\t" << Opcode << "\t[%" - << getRegisterName(MI->getOperand(1).getReg()) << decIncOperator(MI) - << "], %" << getRegisterName(MI->getOperand(0).getReg()); + OS << "\t" << Opcode << "\t[%" + << getRegisterName(MI->getOperand(1).getReg()) << decIncOperator(MI) + << "], %" << getRegisterName(MI->getOperand(0).getReg()); return true; } return false; } bool LanaiInstPrinter::printMemoryStoreIncrement(const MCInst *MI, - raw_ostream &Ostream, + raw_ostream &OS, StringRef Opcode, int AddOffset) { if (isPreIncrementForm(MI, AddOffset)) { - Ostream << "\t" << Opcode << "\t%" - << getRegisterName(MI->getOperand(0).getReg()) << ", [" - << decIncOperator(MI) << "%" - << getRegisterName(MI->getOperand(1).getReg()) << "]"; + OS << "\t" << Opcode << "\t%" << getRegisterName(MI->getOperand(0).getReg()) + << ", [" << decIncOperator(MI) << "%" + << getRegisterName(MI->getOperand(1).getReg()) << "]"; return true; } if (isPostIncrementForm(MI, AddOffset)) { - Ostream << "\t" << Opcode << "\t%" - << getRegisterName(MI->getOperand(0).getReg()) << ", [%" - << getRegisterName(MI->getOperand(1).getReg()) << decIncOperator(MI) - << "]"; + OS << "\t" << Opcode << "\t%" << getRegisterName(MI->getOperand(0).getReg()) + << ", [%" << getRegisterName(MI->getOperand(1).getReg()) + << decIncOperator(MI) << "]"; return true; } return false; } -bool LanaiInstPrinter::printAlias(const MCInst *MI, raw_ostream &Ostream) { +bool LanaiInstPrinter::printAlias(const MCInst *MI, raw_ostream &OS) { switch (MI->getOpcode()) { case Lanai::LDW_RI: // ld 4[*%rN], %rX => ld [++imm], %rX // ld -4[*%rN], %rX => ld [--imm], %rX // ld 4[%rN*], %rX => ld [imm++], %rX // ld -4[%rN*], %rX => ld [imm--], %rX - return printMemoryLoadIncrement(MI, Ostream, "ld", 4); + return printMemoryLoadIncrement(MI, OS, "ld", 4); case Lanai::LDHs_RI: - return printMemoryLoadIncrement(MI, Ostream, "ld.h", 2); + return printMemoryLoadIncrement(MI, OS, "ld.h", 2); case Lanai::LDHz_RI: - return printMemoryLoadIncrement(MI, Ostream, "uld.h", 2); + return printMemoryLoadIncrement(MI, OS, "uld.h", 2); case Lanai::LDBs_RI: - return printMemoryLoadIncrement(MI, Ostream, "ld.b", 1); + return printMemoryLoadIncrement(MI, OS, "ld.b", 1); case Lanai::LDBz_RI: - return printMemoryLoadIncrement(MI, Ostream, "uld.b", 1); + return printMemoryLoadIncrement(MI, OS, "uld.b", 1); case Lanai::SW_RI: // st %rX, 4[*%rN] => st %rX, [++imm] // st %rX, -4[*%rN] => st %rX, [--imm] // st %rX, 4[%rN*] => st %rX, [imm++] // st %rX, -4[%rN*] => st %rX, [imm--] - return printMemoryStoreIncrement(MI, Ostream, "st", 4); + return printMemoryStoreIncrement(MI, OS, "st", 4); case Lanai::STH_RI: - return printMemoryStoreIncrement(MI, Ostream, "st.h", 2); + return printMemoryStoreIncrement(MI, OS, "st.h", 2); case Lanai::STB_RI: - return printMemoryStoreIncrement(MI, Ostream, "st.b", 1); + return printMemoryStoreIncrement(MI, OS, "st.b", 1); default: return false; } } -void LanaiInstPrinter::printInst(const MCInst *MI, raw_ostream &Ostream, +void LanaiInstPrinter::printInst(const MCInst *MI, raw_ostream &OS, StringRef Annotation, const MCSubtargetInfo &STI) { - if (!printAlias(MI, Ostream) && !printAliasInstr(MI, Ostream)) - printInstruction(MI, Ostream); - printAnnotation(Ostream, Annotation); -} - -static void printExpr(const MCAsmInfo &MAI, const MCExpr &Expr, - raw_ostream &Ostream) { - const MCExpr *SRE; - - if (const MCBinaryExpr *BE = dyn_cast(&Expr)) - SRE = dyn_cast(BE->getLHS()); - else if (isa(&Expr)) { - SRE = dyn_cast(&Expr); - } else { - SRE = dyn_cast(&Expr); - } - assert(SRE && "Unexpected MCExpr type."); - - SRE->print(Ostream, &MAI); + if (!printAlias(MI, OS) && !printAliasInstr(MI, OS)) printInstruction(MI, OS); + printAnnotation(OS, Annotation); } void LanaiInstPrinter::printOperand(const MCInst *MI, unsigned OpNo, - raw_ostream &Ostream, - const char *Modifier) { + raw_ostream &OS, const char *Modifier) { assert((Modifier == 0 || Modifier[0] == 0) && "No modifiers supported"); const MCOperand &Op = MI->getOperand(OpNo); if (Op.isReg()) - Ostream << "%" << getRegisterName(Op.getReg()); + OS << "%" << getRegisterName(Op.getReg()); else if (Op.isImm()) - Ostream << formatHex(Op.getImm()); + OS << formatHex(Op.getImm()); else { assert(Op.isExpr() && "Expected an expression"); - printExpr(MAI, *Op.getExpr(), Ostream); + Op.getExpr()->print(OS, &MAI); } } void LanaiInstPrinter::printMemImmOperand(const MCInst *MI, unsigned OpNo, - raw_ostream &Ostream) { + raw_ostream &OS) { const MCOperand &Op = MI->getOperand(OpNo); if (Op.isImm()) { - Ostream << '[' << formatHex(Op.getImm()) << ']'; + OS << '[' << formatHex(Op.getImm()) << ']'; } else { // Symbolic operand will be lowered to immediate value by linker assert(Op.isExpr() && "Expected an expression"); - Ostream << '['; - printExpr(MAI, *Op.getExpr(), Ostream); - Ostream << ']'; + OS << '['; + Op.getExpr()->print(OS, &MAI); + OS << ']'; } } void LanaiInstPrinter::printHi16ImmOperand(const MCInst *MI, unsigned OpNo, - raw_ostream &Ostream) { + raw_ostream &OS) { const MCOperand &Op = MI->getOperand(OpNo); if (Op.isImm()) { - Ostream << formatHex(Op.getImm() << 16); + OS << formatHex(Op.getImm() << 16); } else { // Symbolic operand will be lowered to immediate value by linker assert(Op.isExpr() && "Expected an expression"); - printExpr(MAI, *Op.getExpr(), Ostream); + Op.getExpr()->print(OS, &MAI); } } void LanaiInstPrinter::printHi16AndImmOperand(const MCInst *MI, unsigned OpNo, - raw_ostream &Ostream) { + raw_ostream &OS) { const MCOperand &Op = MI->getOperand(OpNo); if (Op.isImm()) { - Ostream << formatHex((Op.getImm() << 16) | 0xffff); + OS << formatHex((Op.getImm() << 16) | 0xffff); } else { // Symbolic operand will be lowered to immediate value by linker assert(Op.isExpr() && "Expected an expression"); - printExpr(MAI, *Op.getExpr(), Ostream); + Op.getExpr()->print(OS, &MAI); } } void LanaiInstPrinter::printLo16AndImmOperand(const MCInst *MI, unsigned OpNo, - raw_ostream &Ostream) { + raw_ostream &OS) { const MCOperand &Op = MI->getOperand(OpNo); if (Op.isImm()) { - Ostream << formatHex(0xffff0000 | Op.getImm()); + OS << formatHex(0xffff0000 | Op.getImm()); } else { // Symbolic operand will be lowered to immediate value by linker assert(Op.isExpr() && "Expected an expression"); - printExpr(MAI, *Op.getExpr(), Ostream); + Op.getExpr()->print(OS, &MAI); } } -static void printMemoryBaseRegister(raw_ostream &Ostream, const unsigned AluCode, - const MCOperand &RegOp) { +static void printMemoryBaseRegister(raw_ostream &OS, const unsigned AluCode, + const MCOperand &RegOp) { assert(RegOp.isReg() && "Register operand expected"); - Ostream << "["; - if (LPAC::isPreOp(AluCode)) - Ostream << "*"; - Ostream << "%" << LanaiInstPrinter::getRegisterName(RegOp.getReg()); - if (LPAC::isPostOp(AluCode)) - Ostream << "*"; - Ostream << "]"; + OS << "["; + if (LPAC::isPreOp(AluCode)) OS << "*"; + OS << "%" << LanaiInstPrinter::getRegisterName(RegOp.getReg()); + if (LPAC::isPostOp(AluCode)) OS << "*"; + OS << "]"; } template static void printMemoryImmediateOffset(const MCAsmInfo &MAI, const MCOperand &OffsetOp, - raw_ostream &Ostream) { + raw_ostream &OS) { assert((OffsetOp.isImm() || OffsetOp.isExpr()) && "Immediate expected"); if (OffsetOp.isImm()) { assert(isInt(OffsetOp.getImm()) && "Constant value truncated"); - Ostream << OffsetOp.getImm(); + OS << OffsetOp.getImm(); } else - printExpr(MAI, *OffsetOp.getExpr(), Ostream); + OffsetOp.getExpr()->print(OS, &MAI); } void LanaiInstPrinter::printMemRiOperand(const MCInst *MI, int OpNo, - raw_ostream &Ostream, + raw_ostream &OS, const char *Modifier) { const MCOperand &RegOp = MI->getOperand(OpNo); const MCOperand &OffsetOp = MI->getOperand(OpNo + 1); @@ -260,14 +237,14 @@ void LanaiInstPrinter::printMemRiOperand(const MCInst *MI, int OpNo, const unsigned AluCode = AluOp.getImm(); // Offset - printMemoryImmediateOffset<16>(MAI, OffsetOp, Ostream); + printMemoryImmediateOffset<16>(MAI, OffsetOp, OS); // Register - printMemoryBaseRegister(Ostream, AluCode, RegOp); + printMemoryBaseRegister(OS, AluCode, RegOp); } void LanaiInstPrinter::printMemRrOperand(const MCInst *MI, int OpNo, - raw_ostream &Ostream, + raw_ostream &OS, const char *Modifier) { const MCOperand &RegOp = MI->getOperand(OpNo); const MCOperand &OffsetOp = MI->getOperand(OpNo + 1); @@ -276,19 +253,17 @@ void LanaiInstPrinter::printMemRrOperand(const MCInst *MI, int OpNo, assert(OffsetOp.isReg() && RegOp.isReg() && "Registers expected."); // [ Base OP Offset ] - Ostream << "["; - if (LPAC::isPreOp(AluCode)) - Ostream << "*"; - Ostream << "%" << getRegisterName(RegOp.getReg()); - if (LPAC::isPostOp(AluCode)) - Ostream << "*"; - Ostream << " " << LPAC::lanaiAluCodeToString(AluCode) << " "; - Ostream << "%" << getRegisterName(OffsetOp.getReg()); - Ostream << "]"; + OS << "["; + if (LPAC::isPreOp(AluCode)) OS << "*"; + OS << "%" << getRegisterName(RegOp.getReg()); + if (LPAC::isPostOp(AluCode)) OS << "*"; + OS << " " << LPAC::lanaiAluCodeToString(AluCode) << " "; + OS << "%" << getRegisterName(OffsetOp.getReg()); + OS << "]"; } void LanaiInstPrinter::printMemSplsOperand(const MCInst *MI, int OpNo, - raw_ostream &Ostream, + raw_ostream &OS, const char *Modifier) { const MCOperand &RegOp = MI->getOperand(OpNo); const MCOperand &OffsetOp = MI->getOperand(OpNo + 1); @@ -296,14 +271,14 @@ void LanaiInstPrinter::printMemSplsOperand(const MCInst *MI, int OpNo, const unsigned AluCode = AluOp.getImm(); // Offset - printMemoryImmediateOffset<10>(MAI, OffsetOp, Ostream); + printMemoryImmediateOffset<10>(MAI, OffsetOp, OS); // Register - printMemoryBaseRegister(Ostream, AluCode, RegOp); + printMemoryBaseRegister(OS, AluCode, RegOp); } void LanaiInstPrinter::printCCOperand(const MCInst *MI, int OpNo, - raw_ostream &Ostream) { + raw_ostream &OS) { const int CC = static_cast(MI->getOperand(OpNo).getImm()); - Ostream << lanaiCondCodeToString(static_cast(CC)); + OS << lanaiCondCodeToString(static_cast(CC)); } diff --git a/llvm/lib/Target/Lanai/LanaiDelaySlotFiller.cpp b/llvm/lib/Target/Lanai/LanaiDelaySlotFiller.cpp index 4154b9cc9c91..c391b166488f 100644 --- a/llvm/lib/Target/Lanai/LanaiDelaySlotFiller.cpp +++ b/llvm/lib/Target/Lanai/LanaiDelaySlotFiller.cpp @@ -238,6 +238,13 @@ void Filler::insertDefsUses(MachineBasicBlock::instr_iterator MI, else if (MO.isUse()) RegUses.insert(Reg); } + + // Call & return instructions defines SP implicitly. Implicit defines are not + // included in the RegDefs set of calls but instructions modifying SP cannot + // be inserted in the delay slot of a call/return as these instructions are + // expanded to multiple instructions with SP modified before the branch that + // has the delay slot. + if (MI->isCall() || MI->isReturn()) RegDefs.insert(Lanai::SP); } // Returns true if the Reg or its alias is in the RegSet. diff --git a/llvm/lib/Target/Lanai/LanaiMCInstLower.cpp b/llvm/lib/Target/Lanai/LanaiMCInstLower.cpp index 98c5447d270b..6c809b43f7ed 100644 --- a/llvm/lib/Target/Lanai/LanaiMCInstLower.cpp +++ b/llvm/lib/Target/Lanai/LanaiMCInstLower.cpp @@ -83,11 +83,12 @@ MCOperand LanaiMCInstLower::LowerSymbolOperand(const MachineOperand &MO, llvm_unreachable("Unknown target flag on GV operand"); } - const MCSymbolRefExpr *Symbol = MCSymbolRefExpr::create(Sym, Ctx); - const MCExpr *Expr = LanaiMCExpr::create(Kind, Symbol, Ctx); + const MCExpr *Expr = + MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, Ctx); if (!MO.isJTI() && MO.getOffset()) Expr = MCBinaryExpr::createAdd( Expr, MCConstantExpr::create(MO.getOffset(), Ctx), Ctx); + Expr = LanaiMCExpr::create(Kind, Expr, Ctx); return MCOperand::createExpr(Expr); }