summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/patches/patch-r262261-llvm-r198909-sparc.diff
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/patches/patch-r262261-llvm-r198909-sparc.diff')
-rw-r--r--contrib/llvm/patches/patch-r262261-llvm-r198909-sparc.diff229
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
OpenPOWER on IntegriCloud