diff options
Diffstat (limited to 'contrib/llvm/patches/patch-r262261-llvm-r198909-sparc.diff')
-rw-r--r-- | contrib/llvm/patches/patch-r262261-llvm-r198909-sparc.diff | 229 |
1 files changed, 229 insertions, 0 deletions
diff --git a/contrib/llvm/patches/patch-r262261-llvm-r198909-sparc.diff b/contrib/llvm/patches/patch-r262261-llvm-r198909-sparc.diff new file mode 100644 index 0000000..e4fb0f3 --- /dev/null +++ b/contrib/llvm/patches/patch-r262261-llvm-r198909-sparc.diff @@ -0,0 +1,229 @@ +Pull in r198909 from upstream llvm trunk (by Venkatraman Govindaraju): + + [Sparc] Add support for parsing jmpl instruction and make indirect call and jmp instructions as aliases to jmpl. + +Introduced here: http://svn.freebsd.org/changeset/base/262261 + +Index: lib/Target/Sparc/AsmParser/SparcAsmParser.cpp +=================================================================== +--- lib/Target/Sparc/AsmParser/SparcAsmParser.cpp ++++ lib/Target/Sparc/AsmParser/SparcAsmParser.cpp +@@ -453,6 +453,7 @@ parseMEMOperand(SmallVectorImpl<MCParsedAsmOperand + switch (getLexer().getKind()) { + default: return MatchOperand_NoMatch; + ++ case AsmToken::Comma: + case AsmToken::RBrac: + case AsmToken::EndOfStatement: + Operands.push_back(SparcOperand::CreateMEMri(BaseReg, 0, S, E)); +Index: lib/Target/Sparc/SparcInstrAliases.td +=================================================================== +--- lib/Target/Sparc/SparcInstrAliases.td ++++ lib/Target/Sparc/SparcInstrAliases.td +@@ -117,3 +117,14 @@ defm : fp_cond_alias<"uge", 0b1100>; + defm : fp_cond_alias<"le", 0b1101>; + defm : fp_cond_alias<"ule", 0b1110>; + defm : fp_cond_alias<"o", 0b1111>; ++ ++ ++// Instruction aliases for JMPL. ++ ++// jmp addr -> jmpl addr, %g0 ++def : InstAlias<"jmp $addr", (JMPLrr G0, MEMrr:$addr)>; ++def : InstAlias<"jmp $addr", (JMPLri G0, MEMri:$addr)>; ++ ++// call addr -> jmpl addr, %o7 ++def : InstAlias<"call $addr", (JMPLrr O7, MEMrr:$addr)>; ++def : InstAlias<"call $addr", (JMPLri O7, MEMri:$addr)>; +Index: lib/Target/Sparc/InstPrinter/SparcInstPrinter.cpp +=================================================================== +--- lib/Target/Sparc/InstPrinter/SparcInstPrinter.cpp ++++ lib/Target/Sparc/InstPrinter/SparcInstPrinter.cpp +@@ -23,6 +23,7 @@ + using namespace llvm; + + #define GET_INSTRUCTION_NAME ++#define PRINT_ALIAS_INSTR + #include "SparcGenAsmWriter.inc" + + void SparcInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const +@@ -33,10 +34,34 @@ void SparcInstPrinter::printRegName(raw_ostream &O + void SparcInstPrinter::printInst(const MCInst *MI, raw_ostream &O, + StringRef Annot) + { +- printInstruction(MI, O); ++ if (!printAliasInstr(MI, O) && !printSparcAliasInstr(MI, O)) ++ printInstruction(MI, O); + printAnnotation(O, Annot); + } + ++bool SparcInstPrinter::printSparcAliasInstr(const MCInst *MI, raw_ostream &O) ++{ ++ switch (MI->getOpcode()) { ++ default: return false; ++ case SP::JMPLrr: ++ case SP::JMPLri: { ++ if (MI->getNumOperands() != 3) ++ return false; ++ if (!MI->getOperand(0).isReg()) ++ return false; ++ switch (MI->getOperand(0).getReg()) { ++ default: return false; ++ case SP::G0: // jmp $addr ++ O << "\tjmp "; printMemOperand(MI, 1, O); ++ return true; ++ case SP::O7: // call $addr ++ O << "\tcall "; printMemOperand(MI, 1, O); ++ return true; ++ } ++ } ++ } ++} ++ + void SparcInstPrinter::printOperand(const MCInst *MI, int opNum, + raw_ostream &O) + { +Index: lib/Target/Sparc/InstPrinter/SparcInstPrinter.h +=================================================================== +--- lib/Target/Sparc/InstPrinter/SparcInstPrinter.h ++++ lib/Target/Sparc/InstPrinter/SparcInstPrinter.h +@@ -29,9 +29,11 @@ class SparcInstPrinter : public MCInstPrinter { + + virtual void printRegName(raw_ostream &OS, unsigned RegNo) const; + virtual void printInst(const MCInst *MI, raw_ostream &O, StringRef Annot); ++ bool printSparcAliasInstr(const MCInst *MI, raw_ostream &OS); + + // Autogenerated by tblgen. + void printInstruction(const MCInst *MI, raw_ostream &O); ++ bool printAliasInstr(const MCInst *MI, raw_ostream &O); + static const char *getRegisterName(unsigned RegNo); + + void printOperand(const MCInst *MI, int opNum, raw_ostream &OS); +Index: lib/Target/Sparc/SparcInstrInfo.td +=================================================================== +--- lib/Target/Sparc/SparcInstrInfo.td ++++ lib/Target/Sparc/SparcInstrInfo.td +@@ -362,10 +362,18 @@ let usesCustomInserter = 1, Uses = [FCC] in { + [(set f128:$dst, (SPselectfcc f128:$T, f128:$F, imm:$Cond))]>; + } + ++// JMPL Instruction. ++let isTerminator = 1, hasDelaySlot = 1, isBarrier = 1 in { ++ def JMPLrr: F3_1<2, 0b111000, (outs IntRegs:$dst), (ins MEMrr:$addr), ++ "jmpl $addr, $dst", []>; ++ def JMPLri: F3_2<2, 0b111000, (outs IntRegs:$dst), (ins MEMri:$addr), ++ "jmpl $addr, $dst", []>; ++} + + // Section A.3 - Synthetic Instructions, p. 85 + // special cases of JMPL: +-let isReturn = 1, isTerminator = 1, hasDelaySlot = 1, isBarrier = 1 in { ++let isReturn = 1, isTerminator = 1, hasDelaySlot = 1, isBarrier = 1, ++ isCodeGenOnly = 1 in { + let rd = 0, rs1 = 15 in + def RETL: F3_2<2, 0b111000, (outs), (ins i32imm:$val), + "jmp %o7+$val", [(retflag simm13:$val)]>; +@@ -519,9 +527,8 @@ class BranchSP<dag ins, string asmstr, list<dag> p + } + + // Indirect branch instructions. +-let isTerminator = 1, isBarrier = 1, +- hasDelaySlot = 1, isBranch =1, +- isIndirectBranch = 1, rd = 0 in { ++let isTerminator = 1, isBarrier = 1, hasDelaySlot = 1, isBranch =1, ++ isIndirectBranch = 1, rd = 0, isCodeGenOnly = 1 in { + def BINDrr : F3_1<2, 0b111000, + (outs), (ins MEMrr:$ptr), + "jmp $ptr", +@@ -564,15 +571,17 @@ let Uses = [O6], + let Inst{29-0} = disp; + } + +- // indirect calls +- def JMPLrr : F3_1<2, 0b111000, +- (outs), (ins MEMrr:$ptr, variable_ops), +- "call $ptr", +- [(call ADDRrr:$ptr)]> { let rd = 15; } +- def JMPLri : F3_2<2, 0b111000, +- (outs), (ins MEMri:$ptr, variable_ops), +- "call $ptr", +- [(call ADDRri:$ptr)]> { let rd = 15; } ++ // indirect calls: special cases of JMPL. ++ let isCodeGenOnly = 1, rd = 15 in { ++ def CALLrr : F3_1<2, 0b111000, ++ (outs), (ins MEMrr:$ptr, variable_ops), ++ "call $ptr", ++ [(call ADDRrr:$ptr)]>; ++ def CALLri : F3_2<2, 0b111000, ++ (outs), (ins MEMri:$ptr, variable_ops), ++ "call $ptr", ++ [(call ADDRri:$ptr)]>; ++ } + } + + // Section B.28 - Read State Register Instructions +Index: lib/Target/Sparc/DelaySlotFiller.cpp +=================================================================== +--- lib/Target/Sparc/DelaySlotFiller.cpp ++++ lib/Target/Sparc/DelaySlotFiller.cpp +@@ -278,19 +278,19 @@ void Filler::insertCallDefsUses(MachineBasicBlock: + switch(MI->getOpcode()) { + default: llvm_unreachable("Unknown opcode."); + case SP::CALL: break; +- case SP::JMPLrr: +- case SP::JMPLri: ++ case SP::CALLrr: ++ case SP::CALLri: + assert(MI->getNumOperands() >= 2); + const MachineOperand &Reg = MI->getOperand(0); +- assert(Reg.isReg() && "JMPL first operand is not a register."); +- assert(Reg.isUse() && "JMPL first operand is not a use."); ++ assert(Reg.isReg() && "CALL first operand is not a register."); ++ assert(Reg.isUse() && "CALL first operand is not a use."); + RegUses.insert(Reg.getReg()); + + const MachineOperand &RegOrImm = MI->getOperand(1); + if (RegOrImm.isImm()) + break; +- assert(RegOrImm.isReg() && "JMPLrr second operand is not a register."); +- assert(RegOrImm.isUse() && "JMPLrr second operand is not a use."); ++ assert(RegOrImm.isReg() && "CALLrr second operand is not a register."); ++ assert(RegOrImm.isUse() && "CALLrr second operand is not a use."); + RegUses.insert(RegOrImm.getReg()); + break; + } +@@ -353,8 +353,8 @@ bool Filler::needsUnimp(MachineBasicBlock::iterato + switch (I->getOpcode()) { + default: llvm_unreachable("Unknown call opcode."); + case SP::CALL: structSizeOpNum = 1; break; +- case SP::JMPLrr: +- case SP::JMPLri: structSizeOpNum = 2; break; ++ case SP::CALLrr: ++ case SP::CALLri: structSizeOpNum = 2; break; + case SP::TLS_CALL: return false; + } + +Index: test/MC/Sparc/sparc-ctrl-instructions.s +=================================================================== +--- test/MC/Sparc/sparc-ctrl-instructions.s ++++ test/MC/Sparc/sparc-ctrl-instructions.s +@@ -31,6 +31,19 @@ + ! CHECK-NEXT: ! fixup A - offset: 0, value: %lo(sym), kind: fixup_sparc_lo10 + jmp %g1+%lo(sym) + ++ ! CHECK: jmpl %g1+%i2, %g2 ! encoding: [0x85,0xc0,0x40,0x1a] ++ jmpl %g1 + %i2, %g2 ++ ++ ! CHECK: jmpl %o1+8, %g2 ! encoding: [0x85,0xc2,0x60,0x08] ++ jmpl %o1 + 8, %g2 ++ ++ ! CHECK: jmpl %g1, %g2 ! encoding: [0x85,0xc0,0x60,0x00] ++ jmpl %g1, %g2 ++ ++ ! CHECK: jmpl %g1+%lo(sym), %g2 ! encoding: [0x85,0xc0,0b011000AA,A] ++ ! CHECK-NEXT: ! fixup A - offset: 0, value: %lo(sym), kind: fixup_sparc_lo10 ++ jmpl %g1+%lo(sym), %g2 ++ + ! CHECK: ba .BB0 ! encoding: [0x10,0b10AAAAAA,A,A] + ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br22 + ba .BB0 |