llvm.org GIT mirror llvm / 2c3a464
This patch is needed to make c++ exceptions work for mips16. Mips16 is really a processor decoding mode (ala thumb 1) and in the same program, mips16 and mips32 functions can exist and can call each other. If a jal type instruction encounters an address with the lower bit set, then the processor switches to mips16 mode (if it is not already in it). If the lower bit is not set, then it switches to mips32 mode. The linker knows which functions are mips16 and which are mips32. When relocation is performed on code labels, this lower order bit is set if the code label is a mips16 code label. In general this works just fine, however when creating exception handling tables and dwarf, there are cases where you don't want this lower order bit added in. This has been traditionally distinguished in gas assembly source by using a different syntax for the label. lab1: ; this will cause the lower order bit to be added lab2=. ; this will not cause the lower order bit to be added In some cases, it does not matter because in dwarf and debug tables the difference of two labels is used and in that case the lower order bits subtract each other out. To fix this, I have added to mcstreamer the notion of a debuglabel. The default is for label and debug label to be the same. So calling EmitLabel and EmitDebugLabel produce the same result. For various reasons, there is only one set of labels that needs to be modified for the mips exceptions to work. These are the "$eh_func_beginXXX" labels. Mips overrides the debug label suffix from ":" to "=." . This initial patch fixes exceptions. More changes most likely will be needed to DwarfCFException to make all of this work for actual debugging. These changes will be to emit debug labels in some places where a simple label is emitted now. Some historical discussion on this from gcc can be found at: http://gcc.gnu.org/ml/gcc-patches/2008-08/msg00623.html http://gcc.gnu.org/ml/gcc-patches/2008-11/msg01273.html git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@170279 91177308-0d34-0410-b5e6-96231b3b80d8 Reed Kotler 6 years ago
17 changed file(s) with 145 addition(s) and 4 deletion(s). Raw diff Collapse all Expand all
101101 /// LabelSuffix - This is appended to emitted labels.
102102 const char *LabelSuffix; // Defaults to ":"
103103
104 /// LabelSuffix - This is appended to emitted labels.
105 const char *DebugLabelSuffix; // Defaults to ":"
106
104107 /// GlobalPrefix - If this is set to a non-empty string, it is prepended
105108 /// onto all global symbols. This is often used for "_" or ".".
106109 const char *GlobalPrefix; // Defaults to ""
425428 const char *getLabelSuffix() const {
426429 return LabelSuffix;
427430 }
431
432 const char *getDebugLabelSuffix() const {
433 return DebugLabelSuffix;
434 }
435
428436 const char *getGlobalPrefix() const {
429437 return GlobalPrefix;
430438 }
4646 virtual void InitSections();
4747 virtual void ChangeSection(const MCSection *Section);
4848 virtual void EmitLabel(MCSymbol *Symbol);
49 virtual void EmitDebugLabel(MCSymbol *Symbol);
4950 virtual void EmitAssemblerFlag(MCAssemblerFlag Flag);
5051 virtual void EmitThumbFunc(MCSymbol *Func);
5152 virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol);
6868 /// @{
6969
7070 virtual void EmitLabel(MCSymbol *Symbol);
71 virtual void EmitDebugLabel(MCSymbol *Symbol);
7172 virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value);
7273 virtual void EmitValueImpl(const MCExpr *Value, unsigned Size,
7374 unsigned AddrSpace);
242242 /// emitted as a label once, and symbols emitted as a label should never be
243243 /// used in an assignment.
244244 virtual void EmitLabel(MCSymbol *Symbol);
245
246 virtual void EmitDebugLabel(MCSymbol *Symbol);
245247
246248 virtual void EmitEHSymAttributes(const MCSymbol *Symbol,
247249 MCSymbol *EHSymbol);
121121 const MCSymbol *Sym = TLOF.getCFIPersonalitySymbol(Per, Asm->Mang, MMI);
122122 Asm->OutStreamer.EmitCFIPersonality(Sym, PerEncoding);
123123
124 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("eh_func_begin",
125 Asm->getFunctionNumber()));
124 Asm->OutStreamer.EmitDebugLabel
125 (Asm->GetTempSymbol("eh_func_begin",
126 Asm->getFunctionNumber()));
126127
127128 // Provide LSDA information.
128129 if (!shouldEmitLSDA)
3636 CommentColumn = 40;
3737 CommentString = "#";
3838 LabelSuffix = ":";
39 DebugLabelSuffix = ":";
3940 GlobalPrefix = "";
4041 PrivateGlobalPrefix = ".";
4142 LinkerPrivateGlobalPrefix = "";
134134 }
135135
136136 virtual void EmitLabel(MCSymbol *Symbol);
137 virtual void EmitDebugLabel(MCSymbol *Symbol);
138
137139 virtual void EmitEHSymAttributes(const MCSymbol *Symbol,
138140 MCSymbol *EHSymbol);
139141 virtual void EmitAssemblerFlag(MCAssemblerFlag Flag);
341343 MCStreamer::EmitLabel(Symbol);
342344
343345 OS << *Symbol << MAI.getLabelSuffix();
346 EmitEOL();
347 }
348
349 void MCAsmStreamer::EmitDebugLabel(MCSymbol *Symbol) {
350 assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
351 MCStreamer::EmitDebugLabel(Symbol);
352
353 OS << *Symbol << MAI.getDebugLabelSuffix();
344354 EmitEOL();
345355 }
346356
8383 MCSymbolData &SD = getAssembler().getSymbolData(*Symbol);
8484 if (Section.getFlags() & ELF::SHF_TLS)
8585 MCELF::SetType(SD, ELF::STT_TLS);
86 }
87
88 void MCELFStreamer::EmitDebugLabel(MCSymbol *Symbol) {
89 EmitLabel(Symbol);
8690 }
8791
8892 void MCELFStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {
4242
4343 virtual void InitSections();
4444 virtual void EmitLabel(MCSymbol *Symbol);
45 virtual void EmitDebugLabel(MCSymbol *Symbol);
4546 virtual void EmitEHSymAttributes(const MCSymbol *Symbol,
4647 MCSymbol *EHSymbol);
4748 virtual void EmitAssemblerFlag(MCAssemblerFlag Flag);
129130 SD.setFlags(SD.getFlags() & ~SF_ReferenceTypeMask);
130131 }
131132
133 void MCMachOStreamer::EmitDebugLabel(MCSymbol *Symbol) {
134 EmitLabel(Symbol);
135 }
132136 void MCMachOStreamer::EmitDataRegion(DataRegionData::KindTy Kind) {
133137 if (!getAssembler().getBackend().hasDataInCodeSupport())
134138 return;
3434 assert(getCurrentSection() && "Cannot emit before setting section!");
3535 Symbol->setSection(*getCurrentSection());
3636 }
37
37 virtual void EmitDebugLabel(MCSymbol *Symbol) {
38 EmitLabel(Symbol);
39 }
3840 virtual void EmitAssemblerFlag(MCAssemblerFlag Flag) {}
3941 virtual void EmitThumbFunc(MCSymbol *Func) {}
4042
133133 SD.setOffset(F->getContents().size());
134134 }
135135
136 void MCObjectStreamer::EmitDebugLabel(MCSymbol *Symbol) {
137 EmitLabel(Symbol);
138 }
139
136140 void MCObjectStreamer::EmitULEB128Value(const MCExpr *Value) {
137141 int64_t IntValue;
138142 if (Value->EvaluateAsAbsolute(IntValue, getAssembler())) {
3636
3737 virtual void InitSections();
3838 virtual void EmitLabel(MCSymbol *Symbol);
39 virtual void EmitDebugLabel(MCSymbol *Symbol);
3940 virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0,
4041 uint64_t Size = 0, unsigned ByteAlignment = 0);
4142 virtual void EmitBytes(StringRef Data, unsigned AddrSpace);
133134 SD.setOffset(F->getContents().size());
134135 }
135136
137
136138 void MCPureStreamer::EmitZerofill(const MCSection *Section, MCSymbol *Symbol,
137139 uint64_t Size, unsigned ByteAlignment) {
138140 report_fatal_error("not yet implemented in pure streamer");
194194 LastSymbol = Symbol;
195195 }
196196
197 void MCStreamer::EmitDebugLabel(MCSymbol *Symbol) {
198 assert(!Symbol->isVariable() && "Cannot emit a variable symbol!");
199 assert(getCurrentSection() && "Cannot emit before setting section!");
200 Symbol->setSection(*getCurrentSection());
201 LastSymbol = Symbol;
202 }
203
197204 void MCStreamer::EmitCompactUnwindEncoding(uint32_t CompactUnwindEncoding) {
198205 EnsureValidFrame();
199206 MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
5050
5151 virtual void InitSections();
5252 virtual void EmitLabel(MCSymbol *Symbol);
53 virtual void EmitDebugLabel(MCSymbol *Symbol);
5354 virtual void EmitAssemblerFlag(MCAssemblerFlag Flag);
5455 virtual void EmitThumbFunc(MCSymbol *Func);
5556 virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value);
175176 MCObjectStreamer::EmitLabel(Symbol);
176177 }
177178
179 void WinCOFFStreamer::EmitDebugLabel(MCSymbol *Symbol) {
180 EmitLabel(Symbol);
181 }
178182 void WinCOFFStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {
179183 llvm_unreachable("not implemented");
180184 }
3333 GPRel32Directive = "\t.gpword\t";
3434 GPRel64Directive = "\t.gpdword\t";
3535 WeakRefDirective = "\t.weak\t";
36
36 DebugLabelSuffix = "=.";
3737 SupportsDebugInformation = true;
3838 ExceptionsType = ExceptionHandling::DwarfCFI;
3939 HasLEB128 = true;
0 ; RUN: llc -march=mipsel -mcpu=mips16 -relocation-model=pic -O3 < %s | FileCheck %s -check-prefix=16
1
2 ;16: $eh_func_begin0=.
3 @.str = private unnamed_addr constant [7 x i8] c"hello\0A\00", align 1
4 @_ZTIi = external constant i8*
5 @.str1 = private unnamed_addr constant [15 x i8] c"exception %i \0A\00", align 1
6
7 define i32 @main() {
8 entry:
9 %retval = alloca i32, align 4
10 %exn.slot = alloca i8*
11 %ehselector.slot = alloca i32
12 %e = alloca i32, align 4
13 store i32 0, i32* %retval
14 %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([7 x i8]* @.str, i32 0, i32 0))
15 %exception = call i8* @__cxa_allocate_exception(i32 4) nounwind
16 %0 = bitcast i8* %exception to i32*
17 store i32 20, i32* %0
18 invoke void @__cxa_throw(i8* %exception, i8* bitcast (i8** @_ZTIi to i8*), i8* null) noreturn
19 to label %unreachable unwind label %lpad
20
21 lpad: ; preds = %entry
22 %1 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
23 catch i8* bitcast (i8** @_ZTIi to i8*)
24 %2 = extractvalue { i8*, i32 } %1, 0
25 store i8* %2, i8** %exn.slot
26 %3 = extractvalue { i8*, i32 } %1, 1
27 store i32 %3, i32* %ehselector.slot
28 br label %catch.dispatch
29
30 catch.dispatch: ; preds = %lpad
31 %sel = load i32* %ehselector.slot
32 %4 = call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIi to i8*)) nounwind
33 %matches = icmp eq i32 %sel, %4
34 br i1 %matches, label %catch, label %eh.resume
35
36 catch: ; preds = %catch.dispatch
37 %exn = load i8** %exn.slot
38 %5 = call i8* @__cxa_begin_catch(i8* %exn) nounwind
39 %6 = bitcast i8* %5 to i32*
40 %exn.scalar = load i32* %6
41 store i32 %exn.scalar, i32* %e, align 4
42 %7 = load i32* %e, align 4
43 %call2 = invoke i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([15 x i8]* @.str1, i32 0, i32 0), i32 %7)
44 to label %invoke.cont unwind label %lpad1
45
46 invoke.cont: ; preds = %catch
47 call void @__cxa_end_catch() nounwind
48 br label %try.cont
49
50 try.cont: ; preds = %invoke.cont
51 ret i32 0
52
53 lpad1: ; preds = %catch
54 %8 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
55 cleanup
56 %9 = extractvalue { i8*, i32 } %8, 0
57 store i8* %9, i8** %exn.slot
58 %10 = extractvalue { i8*, i32 } %8, 1
59 store i32 %10, i32* %ehselector.slot
60 call void @__cxa_end_catch() nounwind
61 br label %eh.resume
62
63 eh.resume: ; preds = %lpad1, %catch.dispatch
64 %exn3 = load i8** %exn.slot
65 %sel4 = load i32* %ehselector.slot
66 %lpad.val = insertvalue { i8*, i32 } undef, i8* %exn3, 0
67 %lpad.val5 = insertvalue { i8*, i32 } %lpad.val, i32 %sel4, 1
68 resume { i8*, i32 } %lpad.val5
69
70 unreachable: ; preds = %entry
71 unreachable
72 }
73
74 declare i32 @printf(i8*, ...)
75
76 declare i8* @__cxa_allocate_exception(i32)
77
78 declare i32 @__gxx_personality_v0(...)
79
80 declare void @__cxa_throw(i8*, i8*, i8*)
81
82 declare i32 @llvm.eh.typeid.for(i8*) nounwind readnone
83
84 declare i8* @__cxa_begin_catch(i8*)
85
86 declare void @__cxa_end_catch()
743743 virtual void EmitLabel(MCSymbol *Symbol) {
744744 Symbol->setSection(*getCurrentSection());
745745 markDefined(*Symbol);
746 }
747 virtual void EmitDebugLabel(MCSymbol *Symbol) {
748 EmitLabel(Symbol);
746749 }
747750 virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
748751 // FIXME: should we handle aliases?