]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - contrib/llvm/patches/patch-r262261-llvm-r199775-sparc.diff
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / contrib / llvm / patches / patch-r262261-llvm-r199775-sparc.diff
1 Pull in r199775 from upstream llvm trunk (by Venkatraman Govindaraju):
2
3   [Sparc] Do not add PC to _GLOBAL_OFFSET_TABLE_ address to access GOT in absolute code.
4   Fixes PR#18521
5
6 Introduced here: http://svnweb.freebsd.org/changeset/base/262261
7
8 Index: lib/Target/Sparc/SparcAsmPrinter.cpp
9 ===================================================================
10 --- lib/Target/Sparc/SparcAsmPrinter.cpp
11 +++ lib/Target/Sparc/SparcAsmPrinter.cpp
12 @@ -65,18 +65,24 @@ namespace {
13      bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
14                                 unsigned AsmVariant, const char *ExtraCode,
15                                 raw_ostream &O);
16 +
17 +    void LowerGETPCXAndEmitMCInsts(const MachineInstr *MI);
18 +
19    };
20  } // end of anonymous namespace
21  
22 -static MCOperand createPCXCallOP(MCSymbol *Label,
23 -                                 MCContext &OutContext)
24 -{
25 -  const MCSymbolRefExpr *MCSym = MCSymbolRefExpr::Create(Label,
26 +static MCOperand createSparcMCOperand(SparcMCExpr::VariantKind Kind,
27 +                                      MCSymbol *Sym, MCContext &OutContext) {
28 +  const MCSymbolRefExpr *MCSym = MCSymbolRefExpr::Create(Sym,
29                                                           OutContext);
30 -  const SparcMCExpr *expr = SparcMCExpr::Create(SparcMCExpr::VK_Sparc_None,
31 -                                                MCSym, OutContext);
32 +  const SparcMCExpr *expr = SparcMCExpr::Create(Kind, MCSym, OutContext);
33    return MCOperand::CreateExpr(expr);
34 +
35  }
36 +static MCOperand createPCXCallOP(MCSymbol *Label,
37 +                                 MCContext &OutContext) {
38 +  return createSparcMCOperand(SparcMCExpr::VK_Sparc_None, Label, OutContext);
39 +}
40  
41  static MCOperand createPCXRelExprOp(SparcMCExpr::VariantKind Kind,
42                                      MCSymbol *GOTLabel, MCSymbol *StartLabel,
43 @@ -115,43 +121,101 @@ static void EmitSETHI(MCStreamer &OutStreamer,
44    OutStreamer.EmitInstruction(SETHIInst);
45  }
46  
47 -static void EmitOR(MCStreamer &OutStreamer, MCOperand &RS1,
48 -                   MCOperand &Imm, MCOperand &RD)
49 +static void EmitBinary(MCStreamer &OutStreamer, unsigned Opcode,
50 +                       MCOperand &RS1, MCOperand &Src2, MCOperand &RD)
51  {
52 -  MCInst ORInst;
53 -  ORInst.setOpcode(SP::ORri);
54 -  ORInst.addOperand(RD);
55 -  ORInst.addOperand(RS1);
56 -  ORInst.addOperand(Imm);
57 -  OutStreamer.EmitInstruction(ORInst);
58 +  MCInst Inst;
59 +  Inst.setOpcode(Opcode);
60 +  Inst.addOperand(RD);
61 +  Inst.addOperand(RS1);
62 +  Inst.addOperand(Src2);
63 +  OutStreamer.EmitInstruction(Inst);
64  }
65  
66 +static void EmitOR(MCStreamer &OutStreamer,
67 +                   MCOperand &RS1, MCOperand &Imm, MCOperand &RD) {
68 +  EmitBinary(OutStreamer, SP::ORri, RS1, Imm, RD);
69 +}
70 +
71  static void EmitADD(MCStreamer &OutStreamer,
72 -                    MCOperand &RS1, MCOperand &RS2, MCOperand &RD)
73 -{
74 -  MCInst ADDInst;
75 -  ADDInst.setOpcode(SP::ADDrr);
76 -  ADDInst.addOperand(RD);
77 -  ADDInst.addOperand(RS1);
78 -  ADDInst.addOperand(RS2);
79 -  OutStreamer.EmitInstruction(ADDInst);
80 +                    MCOperand &RS1, MCOperand &RS2, MCOperand &RD) {
81 +  EmitBinary(OutStreamer, SP::ADDrr, RS1, RS2, RD);
82  }
83  
84 -static void LowerGETPCXAndEmitMCInsts(const MachineInstr *MI,
85 -                                      MCStreamer &OutStreamer,
86 -                                      MCContext &OutContext)
87 +static void EmitSHL(MCStreamer &OutStreamer,
88 +                    MCOperand &RS1, MCOperand &Imm, MCOperand &RD) {
89 +  EmitBinary(OutStreamer, SP::SLLri, RS1, Imm, RD);
90 +}
91 +
92 +
93 +static void EmitHiLo(MCStreamer &OutStreamer,  MCSymbol *GOTSym,
94 +                     SparcMCExpr::VariantKind HiKind,
95 +                     SparcMCExpr::VariantKind LoKind,
96 +                     MCOperand &RD,
97 +                     MCContext &OutContext) {
98 +
99 +  MCOperand hi = createSparcMCOperand(HiKind, GOTSym, OutContext);
100 +  MCOperand lo = createSparcMCOperand(LoKind, GOTSym, OutContext);
101 +  EmitSETHI(OutStreamer, hi, RD);
102 +  EmitOR(OutStreamer, RD, lo, RD);
103 +}
104 +
105 +void SparcAsmPrinter::LowerGETPCXAndEmitMCInsts(const MachineInstr *MI)
106  {
107 -  const MachineOperand &MO = MI->getOperand(0);
108 -  MCSymbol *StartLabel = OutContext.CreateTempSymbol();
109 -  MCSymbol *EndLabel   = OutContext.CreateTempSymbol();
110 -  MCSymbol *SethiLabel = OutContext.CreateTempSymbol();
111    MCSymbol *GOTLabel   =
112      OutContext.GetOrCreateSymbol(Twine("_GLOBAL_OFFSET_TABLE_"));
113  
114 +  const MachineOperand &MO = MI->getOperand(0);
115    assert(MO.getReg() != SP::O7 &&
116           "%o7 is assigned as destination for getpcx!");
117  
118    MCOperand MCRegOP = MCOperand::CreateReg(MO.getReg());
119 +
120 +
121 +  if (TM.getRelocationModel() != Reloc::PIC_) {
122 +    // Just load the address of GOT to MCRegOP.
123 +    switch(TM.getCodeModel()) {
124 +    default:
125 +      llvm_unreachable("Unsupported absolute code model");
126 +    case CodeModel::Small:
127 +      EmitHiLo(OutStreamer, GOTLabel,
128 +               SparcMCExpr::VK_Sparc_HI, SparcMCExpr::VK_Sparc_LO,
129 +               MCRegOP, OutContext);
130 +      break;
131 +    case CodeModel::Medium: {
132 +      EmitHiLo(OutStreamer, GOTLabel,
133 +               SparcMCExpr::VK_Sparc_H44, SparcMCExpr::VK_Sparc_M44,
134 +               MCRegOP, OutContext);
135 +      MCOperand imm = MCOperand::CreateExpr(MCConstantExpr::Create(12,
136 +                                                                   OutContext));
137 +      EmitSHL(OutStreamer, MCRegOP, imm, MCRegOP);
138 +      MCOperand lo = createSparcMCOperand(SparcMCExpr::VK_Sparc_L44,
139 +                                          GOTLabel, OutContext);
140 +      EmitOR(OutStreamer, MCRegOP, lo, MCRegOP);
141 +      break;
142 +    }
143 +    case CodeModel::Large: {
144 +      EmitHiLo(OutStreamer, GOTLabel,
145 +               SparcMCExpr::VK_Sparc_HH, SparcMCExpr::VK_Sparc_HM,
146 +               MCRegOP, OutContext);
147 +      MCOperand imm = MCOperand::CreateExpr(MCConstantExpr::Create(32,
148 +                                                                   OutContext));
149 +      EmitSHL(OutStreamer, MCRegOP, imm, MCRegOP);
150 +      // Use register %o7 to load the lower 32 bits.
151 +      MCOperand RegO7 = MCOperand::CreateReg(SP::O7);
152 +      EmitHiLo(OutStreamer, GOTLabel,
153 +               SparcMCExpr::VK_Sparc_HI, SparcMCExpr::VK_Sparc_LO,
154 +               RegO7, OutContext);
155 +      EmitADD(OutStreamer, MCRegOP, RegO7, MCRegOP);
156 +    }
157 +    }
158 +    return;
159 +  }
160 +
161 +  MCSymbol *StartLabel = OutContext.CreateTempSymbol();
162 +  MCSymbol *EndLabel   = OutContext.CreateTempSymbol();
163 +  MCSymbol *SethiLabel = OutContext.CreateTempSymbol();
164 +
165    MCOperand RegO7   = MCOperand::CreateReg(SP::O7);
166  
167    // <StartLabel>:
168 @@ -187,7 +251,7 @@ void SparcAsmPrinter::EmitInstruction(const Machin
169      // FIXME: Debug Value.
170      return;
171    case SP::GETPCX:
172 -    LowerGETPCXAndEmitMCInsts(MI, OutStreamer, OutContext);
173 +    LowerGETPCXAndEmitMCInsts(MI);
174      return;
175    }
176    MachineBasicBlock::const_instr_iterator I = MI;
177 Index: test/CodeGen/SPARC/tls.ll
178 ===================================================================
179 --- test/CodeGen/SPARC/tls.ll
180 +++ test/CodeGen/SPARC/tls.ll
181 @@ -38,8 +38,7 @@ entry:
182  
183  
184  ; v8abs-LABEL:  test_tls_extern
185 -; v8abs:        or     {{%[goli][0-7]}}, %lo(_GLOBAL_OFFSET_TABLE_+{{.+}}), [[PC:%[goli][0-7]]]
186 -; v8abs:        add    [[PC]], %o7, %[[GOTBASE:[goli][0-7]]]
187 +; v8abs:        or     {{%[goli][0-7]}}, %lo(_GLOBAL_OFFSET_TABLE_), %[[GOTBASE:[goli][0-7]]]
188  ; v8abs:        sethi  %tie_hi22(extern_symbol), [[R1:%[goli][0-7]]]
189  ; v8abs:        add    [[R1]], %tie_lo10(extern_symbol), %[[R2:[goli][0-7]]]
190  ; v8abs:        ld     [%[[GOTBASE]]+%[[R2]]], [[R3:%[goli][0-7]]], %tie_ld(extern_symbol)
191 @@ -47,8 +46,7 @@ entry:
192  ; v8abs:        ld     [%[[R4]]]
193  
194  ; v9abs-LABEL:  test_tls_extern
195 -; v9abs:        or     {{%[goli][0-7]}}, %lo(_GLOBAL_OFFSET_TABLE_+{{.+}}), [[PC:%[goli][0-7]]]
196 -; v9abs:        add    [[PC]], %o7, %[[GOTBASE:[goli][0-7]]]
197 +; v9abs:        or     {{%[goli][0-7]}}, %l44(_GLOBAL_OFFSET_TABLE_), %[[GOTBASE:[goli][0-7]]]
198  ; v9abs:        sethi  %tie_hi22(extern_symbol), [[R1:%[goli][0-7]]]
199  ; v9abs:        add    [[R1]], %tie_lo10(extern_symbol), %[[R2:[goli][0-7]]]
200  ; v9abs:        ldx    [%[[GOTBASE]]+%[[R2]]], [[R3:%[goli][0-7]]], %tie_ldx(extern_symbol)