From 7225cd52e70c02479ffc3bdc4dded02a688b8da4 Mon Sep 17 00:00:00 2001 From: Daniel Sanders Date: Fri, 29 Apr 2016 16:16:49 +0000 Subject: [PATCH] [mips][ias] Move createCpRestoreMemOp to MipsTargetStreamer. NFC. Summary: This removes the temporary call to isIntegratedAssemblerRequired() which was added recently. It's effect is now acheived directly in the MipsTargetStreamer hierarchy. Reviewers: sdardis Subscribers: dsanders, sdardis, llvm-commits Differential Revision: http://reviews.llvm.org/D19715 llvm-svn: 268058 --- .../Target/Mips/AsmParser/MipsAsmParser.cpp | 33 +++++------- .../Mips/MCTargetDesc/MipsTargetStreamer.cpp | 52 +++++++++++++------ llvm/lib/Target/Mips/MipsTargetStreamer.h | 10 ++-- llvm/test/MC/Mips/double-expand.s | 24 +++++++-- 4 files changed, 77 insertions(+), 42 deletions(-) diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index 353e679391db..b4feea0e60a3 100644 --- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -1891,8 +1891,7 @@ bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc, STI); // Load the $gp from the stack. - createCpRestoreMemOp(true /*IsLoad*/, CpRestoreOffset /*StackOffset*/, - IDLoc, Out, STI); + TOut.emitGPRestore(CpRestoreOffset, IDLoc, STI); } else Warning(IDLoc, "no .cprestore used in PIC mode"); } @@ -3593,19 +3592,18 @@ void MipsAsmParser::createCpRestoreMemOp(bool IsLoad, int StackOffset, const MCSubtargetInfo *STI) { MipsTargetStreamer &TOut = getTargetStreamer(); - // If the offset can not fit into 16 bits, we need to expand. - if (!isInt<16>(StackOffset)) { - MCInst MemInst; - MemInst.setOpcode(IsLoad ? Mips::LW : Mips::SW); - MemInst.addOperand(MCOperand::createReg(Mips::GP)); - MemInst.addOperand(MCOperand::createReg(Mips::SP)); - MemInst.addOperand(MCOperand::createImm(StackOffset)); - expandMemInst(MemInst, IDLoc, Out, STI, IsLoad, true /*HasImmOpnd*/); + if (IsLoad) { + TOut.emitLoadWithImmOffset(Mips::LW, Mips::GP, Mips::SP, StackOffset, + Mips::GP, IDLoc, STI); return; } - TOut.emitRRI(IsLoad ? Mips::LW : Mips::SW, Mips::GP, Mips::SP, StackOffset, - IDLoc, STI); + unsigned ATReg = getATReg(IDLoc); + if (!ATReg) + return; + + TOut.emitStoreWithImmOffset(Mips::SW, Mips::GP, Mips::SP, StackOffset, ATReg, + IDLoc, STI); } unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) { @@ -5472,14 +5470,11 @@ bool MipsAsmParser::parseDirectiveCpRestore(SMLoc Loc) { return false; } - // Store the $gp on the stack. - if (getStreamer().isIntegratedAssemblerRequired()) { - const MCSubtargetInfo &STI = getSTI(); - createCpRestoreMemOp(false /*IsLoad*/, CpRestoreOffset /*StackOffset*/, Loc, - getStreamer(), &STI); - } + unsigned ATReg = getATReg(Loc); + if (!ATReg) + return true; - getTargetStreamer().emitDirectiveCpRestore(CpRestoreOffset); + getTargetStreamer().emitDirectiveCpRestore(CpRestoreOffset, ATReg, Loc, STI); Parser.Lex(); // Consume the EndOfStatement. return false; } diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp index e63863c2808f..5eec7213b9f4 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp @@ -88,7 +88,9 @@ void MipsTargetStreamer::emitDirectiveSetHardFloat() { void MipsTargetStreamer::emitDirectiveSetDsp() { forbidModuleDirective(); } void MipsTargetStreamer::emitDirectiveSetNoDsp() { forbidModuleDirective(); } void MipsTargetStreamer::emitDirectiveCpLoad(unsigned RegNo) {} -void MipsTargetStreamer::emitDirectiveCpRestore(int Offset) { +void MipsTargetStreamer::emitDirectiveCpRestore(int Offset, unsigned ATReg, + SMLoc IDLoc, + const MCSubtargetInfo *STI) { forbidModuleDirective(); } void MipsTargetStreamer::emitDirectiveCpsetup(unsigned RegNo, int RegOrOffset, @@ -207,12 +209,22 @@ void MipsTargetStreamer::emitNop(SMLoc IDLoc, const MCSubtargetInfo *STI) { emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI); } -/// Emit a store instruction with an immediate offset. The immediate is -/// expected to be out-of-range for a simm16 and will be expanded to -/// appropriate instructions. +/// Emit the $gp restore operation for .cprestore. +void MipsTargetStreamer::emitGPRestore(int Offset, SMLoc IDLoc, + const MCSubtargetInfo *STI) { + emitLoadWithImmOffset(Mips::LW, Mips::GP, Mips::SP, Offset, Mips::GP, IDLoc, + STI); +} + +/// Emit a store instruction with an immediate offset. void MipsTargetStreamer::emitStoreWithImmOffset( unsigned Opcode, unsigned SrcReg, unsigned BaseReg, int64_t Offset, unsigned ATReg, SMLoc IDLoc, const MCSubtargetInfo *STI) { + if (isInt<16>(Offset)) { + emitRRI(Opcode, SrcReg, BaseReg, Offset, IDLoc, STI); + return; + } + // sw $8, offset($8) => lui $at, %hi(offset) // add $at, $at, $8 // sw $8, %lo(offset)($at) @@ -250,16 +262,19 @@ void MipsTargetStreamer::emitStoreWithSymOffset( emitRRX(Opcode, SrcReg, ATReg, LoOperand, IDLoc, STI); } -/// Emit a load instruction with an immediate offset. The immediate is expected -/// to be out-of-range for a simm16 and will be expanded to appropriate -/// instructions. DstReg and TmpReg are permitted to be the same register iff -/// DstReg is distinct from BaseReg and DstReg is a GPR. It is the callers -/// responsibility to identify such cases and pass the appropriate register in -/// TmpReg. +/// Emit a load instruction with an immediate offset. DstReg and TmpReg are +/// permitted to be the same register iff DstReg is distinct from BaseReg and +/// DstReg is a GPR. It is the callers responsibility to identify such cases +/// and pass the appropriate register in TmpReg. void MipsTargetStreamer::emitLoadWithImmOffset(unsigned Opcode, unsigned DstReg, unsigned BaseReg, int64_t Offset, unsigned TmpReg, SMLoc IDLoc, const MCSubtargetInfo *STI) { + if (isInt<16>(Offset)) { + emitRRI(Opcode, DstReg, BaseReg, Offset, IDLoc, STI); + return; + } + // 1) lw $8, offset($9) => lui $8, %hi(offset) // add $8, $8, $9 // lw $8, %lo(offset)($9) @@ -555,8 +570,10 @@ void MipsTargetAsmStreamer::emitDirectiveCpLoad(unsigned RegNo) { forbidModuleDirective(); } -void MipsTargetAsmStreamer::emitDirectiveCpRestore(int Offset) { - MipsTargetStreamer::emitDirectiveCpRestore(Offset); +void MipsTargetAsmStreamer::emitDirectiveCpRestore(int Offset, unsigned ATReg, + SMLoc IDLoc, + const MCSubtargetInfo *STI) { + MipsTargetStreamer::emitDirectiveCpRestore(Offset, ATReg, IDLoc, STI); OS << "\t.cprestore\t" << Offset << "\n"; } @@ -990,8 +1007,10 @@ void MipsTargetELFStreamer::emitDirectiveCpLoad(unsigned RegNo) { forbidModuleDirective(); } -void MipsTargetELFStreamer::emitDirectiveCpRestore(int Offset) { - MipsTargetStreamer::emitDirectiveCpRestore(Offset); +void MipsTargetELFStreamer::emitDirectiveCpRestore(int Offset, unsigned ATReg, + SMLoc IDLoc, + const MCSubtargetInfo *STI) { + MipsTargetStreamer::emitDirectiveCpRestore(Offset, ATReg, IDLoc, STI); // .cprestore offset // When PIC mode is enabled and the O32 ABI is used, this directive expands // to: @@ -1003,8 +1022,9 @@ void MipsTargetELFStreamer::emitDirectiveCpRestore(int Offset) { if (!Pic || (getABI().IsN32() || getABI().IsN64())) return; - // FIXME: MipsAsmParser currently emits the instructions that should be - // emitted here. + // Store the $gp on the stack. + emitStoreWithImmOffset(Mips::SW, Mips::GP, Mips::SP, Offset, ATReg, IDLoc, + STI); } void MipsTargetELFStreamer::emitDirectiveCpsetup(unsigned RegNo, diff --git a/llvm/lib/Target/Mips/MipsTargetStreamer.h b/llvm/lib/Target/Mips/MipsTargetStreamer.h index 6cab226628ef..a60943b8a411 100644 --- a/llvm/lib/Target/Mips/MipsTargetStreamer.h +++ b/llvm/lib/Target/Mips/MipsTargetStreamer.h @@ -78,7 +78,8 @@ public: // PIC support virtual void emitDirectiveCpLoad(unsigned RegNo); - virtual void emitDirectiveCpRestore(int Offset); + virtual void emitDirectiveCpRestore(int Offset, unsigned ATReg, SMLoc IDLoc, + const MCSubtargetInfo *STI); virtual void emitDirectiveCpsetup(unsigned RegNo, int RegOrOffset, const MCSymbol &Sym, bool IsReg); virtual void emitDirectiveCpreturn(unsigned SaveLocation, @@ -130,6 +131,7 @@ public: MCOperand &HiOperand, MCOperand &LoOperand, unsigned ATReg, SMLoc IDLoc, const MCSubtargetInfo *STI); + void emitGPRestore(int Offset, SMLoc IDLoc, const MCSubtargetInfo *STI); void forbidModuleDirective() { ModuleDirectiveAllowed = false; } void reallowModuleDirective() { ModuleDirectiveAllowed = true; } @@ -230,7 +232,8 @@ public: // PIC support void emitDirectiveCpLoad(unsigned RegNo) override; - void emitDirectiveCpRestore(int Offset) override; + void emitDirectiveCpRestore(int Offset, unsigned ATReg, SMLoc IDLoc, + const MCSubtargetInfo *STI) override; void emitDirectiveCpsetup(unsigned RegNo, int RegOrOffset, const MCSymbol &Sym, bool IsReg) override; void emitDirectiveCpreturn(unsigned SaveLocation, @@ -282,7 +285,8 @@ public: // PIC support void emitDirectiveCpLoad(unsigned RegNo) override; - void emitDirectiveCpRestore(int Offset) override; + void emitDirectiveCpRestore(int Offset, unsigned ATReg, SMLoc IDLoc, + const MCSubtargetInfo *STI) override; void emitDirectiveCpsetup(unsigned RegNo, int RegOrOffset, const MCSymbol &Sym, bool IsReg) override; void emitDirectiveCpreturn(unsigned SaveLocation, diff --git a/llvm/test/MC/Mips/double-expand.s b/llvm/test/MC/Mips/double-expand.s index 1c7c6a30721f..ac03a6fa835e 100644 --- a/llvm/test/MC/Mips/double-expand.s +++ b/llvm/test/MC/Mips/double-expand.s @@ -2,9 +2,25 @@ # RUN: llvm-mc -triple=mipsel-unknown-linux < %s | \ # RUN: llvm-mc -triple=mipsel-unknown-linux | FileCheck %s -# CHECK: bnez $2, foo -# CHECK: nop -# CHECK-NOT: nop - .text +branch: bnez $2, foo + +# CHECK-LABEL: branch: +# CHECK: bnez $2, foo +# CHECK: nop +# CHECK-NOT: nop + +cprestore: + .option pic2 + .cprestore 16 + jal foo + +# CHECK-LABEL: cprestore: +# CHECK: .cprestore 16 +# CHECK: lw $25, %call16(foo)($gp) +# CHECK: jalr $25 +# CHECK: nop +# CHECK: lw $gp, 16($sp) +# CHECK-NOT: nop +# CHECK-NOT: lw