Skip to content

Commit 1c8ac8f

Browse files
committed
There are two reasons why we might want to use
foo = a - b .long foo instead of just .long a - b First, on darwin9 64 bits the assembler produces the wrong result. Second, if "a" is the end of the section all darwin assemblers (9, 10 and mc) will not consider a - b to be a constant but will if the dummy foo is created. Split how we handle these cases. The first one is something MC should take care of. The second one has to be handled by the caller. llvm-svn: 120889
1 parent 4fb115d commit 1c8ac8f

File tree

13 files changed

+66
-18
lines changed

13 files changed

+66
-18
lines changed

llvm/include/llvm/MC/MCAsmInfo.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,13 @@ namespace llvm {
197197
/// HasSetDirective - True if the assembler supports the .set directive.
198198
bool HasSetDirective; // Defaults to true.
199199

200+
/// NeedsSetToChangeDiffSize - True if the assembler requires that we do
201+
/// Lc = a - b
202+
/// .long Lc
203+
/// instead of doing
204+
/// .long a - b
205+
bool NeedsSetToChangeDiffSize; // Defaults to false.
206+
200207
/// HasLCOMMDirective - This is true if the target supports the .lcomm
201208
/// directive.
202209
bool HasLCOMMDirective; // Defaults to false.
@@ -400,6 +407,7 @@ namespace llvm {
400407
return ExternDirective;
401408
}
402409
bool hasSetDirective() const { return HasSetDirective; }
410+
bool needsSetToChangeDiffSize() const { return NeedsSetToChangeDiffSize; }
403411
bool hasLCOMMDirective() const { return HasLCOMMDirective; }
404412
bool hasDotTypeDotSizeDirective() const {return HasDotTypeDotSizeDirective;}
405413
bool getCOMMDirectiveAlignmentIsInBytes() const {

llvm/include/llvm/MC/MCObjectStreamer.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,7 @@ class MCObjectStreamer : public MCStreamer {
6060
/// @{
6161

6262
virtual void EmitLabel(MCSymbol *Symbol);
63-
virtual void EmitValue(const MCExpr *Value, unsigned Size,unsigned AddrSpace,
64-
bool UseSet = false);
63+
virtual void EmitValue(const MCExpr *Value, unsigned Size,unsigned AddrSpace);
6564
virtual void EmitULEB128Value(const MCExpr *Value, unsigned AddrSpace = 0);
6665
virtual void EmitSLEB128Value(const MCExpr *Value, unsigned AddrSpace = 0);
6766
virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol);

llvm/include/llvm/MC/MCStreamer.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ namespace llvm {
242242
/// @param Size - The size of the integer (in bytes) to emit. This must
243243
/// match a native machine width.
244244
virtual void EmitValue(const MCExpr *Value, unsigned Size,
245-
unsigned AddrSpace = 0, bool UseSet = false) = 0;
245+
unsigned AddrSpace = 0) = 0;
246246

247247
/// EmitIntValue - Special case of EmitValue that avoids the client having
248248
/// to pass in a MCExpr for constant integers.

llvm/lib/MC/MCAsmInfo.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ MCAsmInfo::MCAsmInfo() {
5454
GPRel32Directive = 0;
5555
GlobalDirective = "\t.globl\t";
5656
HasSetDirective = true;
57+
NeedsSetToChangeDiffSize = false;
5758
HasLCOMMDirective = false;
5859
COMMDirectiveAlignmentIsInBytes = true;
5960
HasDotTypeDotSizeDirective = true;

llvm/lib/MC/MCAsmStreamer.cpp

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ class MCAsmStreamer : public MCStreamer {
4444
unsigned IsVerboseAsm : 1;
4545
unsigned ShowInst : 1;
4646

47+
bool needsSet(const MCExpr *Value);
48+
4749
public:
4850
MCAsmStreamer(MCContext &Context, formatted_raw_ostream &os,
4951
bool isLittleEndian, bool isVerboseAsm,
@@ -150,8 +152,7 @@ class MCAsmStreamer : public MCStreamer {
150152

151153
virtual void EmitBytes(StringRef Data, unsigned AddrSpace);
152154

153-
virtual void EmitValue(const MCExpr *Value, unsigned Size,unsigned AddrSpace,
154-
bool UseSet = false);
155+
virtual void EmitValue(const MCExpr *Value, unsigned Size,unsigned AddrSpace);
155156
virtual void EmitIntValue(uint64_t Value, unsigned Size,
156157
unsigned AddrSpace = 0);
157158

@@ -511,8 +512,34 @@ void MCAsmStreamer::EmitIntValue(uint64_t Value, unsigned Size,
511512
EmitValue(MCConstantExpr::Create(Value, getContext()), Size, AddrSpace);
512513
}
513514

515+
static bool hasSymbolDifference(const MCExpr *Value) {
516+
switch (Value->getKind()) {
517+
case MCExpr::Target: llvm_unreachable("Can't handle target exprs yet!");
518+
case MCExpr::Constant:
519+
case MCExpr::SymbolRef:
520+
return false;
521+
case MCExpr::Unary:
522+
return hasSymbolDifference(cast<MCUnaryExpr>(Value)->getSubExpr());
523+
case MCExpr::Binary: {
524+
const MCBinaryExpr *BE = cast<MCBinaryExpr>(Value);
525+
if (BE->getOpcode() == MCBinaryExpr::Sub &&
526+
BE->getLHS()->getKind() == MCExpr::SymbolRef &&
527+
BE->getRHS()->getKind() == MCExpr::SymbolRef)
528+
return true;
529+
return hasSymbolDifference(BE->getLHS()) ||
530+
hasSymbolDifference(BE->getRHS());
531+
}
532+
}
533+
llvm_unreachable("Switch covers all cases");
534+
}
535+
536+
bool MCAsmStreamer::needsSet(const MCExpr *Value) {
537+
return getContext().getAsmInfo().needsSetToChangeDiffSize() &&
538+
hasSymbolDifference(Value);
539+
}
540+
514541
void MCAsmStreamer::EmitValue(const MCExpr *Value, unsigned Size,
515-
unsigned AddrSpace, bool UseSet) {
542+
unsigned AddrSpace) {
516543
assert(CurSection && "Cannot emit contents before setting section!");
517544
const char *Directive = 0;
518545
switch (Size) {
@@ -538,7 +565,7 @@ void MCAsmStreamer::EmitValue(const MCExpr *Value, unsigned Size,
538565
}
539566

540567
assert(Directive && "Invalid size for machine code value!");
541-
if (UseSet && MAI.hasSetDirective()) {
568+
if (needsSet(Value)) {
542569
MCSymbol *SetLabel = getContext().CreateTempSymbol();
543570
EmitAssignment(SetLabel, Value);
544571
OS << Directive << *SetLabel;

llvm/lib/MC/MCDwarf.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -213,8 +213,15 @@ void MCDwarfFileTable::Emit(MCStreamer *MCOS,
213213

214214
// The first 4 bytes is the total length of the information for this
215215
// compilation unit (not including these 4 bytes for the length).
216-
MCOS->EmitValue(MakeStartMinusEndExpr(MCOS, LineStartSym, LineEndSym, 4),
217-
4, 0, true /*UseSet*/);
216+
// FIXME: We create the dummy TotalLength variable because LineEndSym points
217+
// to the end of the section and the darwin assembler doesn't consider that
218+
// difference an assembly time constant. It might be better for this to be
219+
// proected by a flag.
220+
MCSymbol *TotalLength = MCOS->getContext().CreateTempSymbol();
221+
MCOS->EmitAssignment(TotalLength,
222+
MakeStartMinusEndExpr(MCOS, LineStartSym, LineEndSym,
223+
4));
224+
MCOS->EmitSymbolValue(TotalLength, 4, 0);
218225

219226
// Next 2 bytes is the Version, which is Dwarf 2.
220227
MCOS->EmitIntValue(2, 2);
@@ -228,7 +235,7 @@ void MCDwarfFileTable::Emit(MCStreamer *MCOS,
228235
// length of the prologue.
229236
MCOS->EmitValue(MakeStartMinusEndExpr(MCOS, LineStartSym, ProEndSym,
230237
(4 + 2 + 4)),
231-
4, 0, true /*UseSet*/);
238+
4, 0);
232239

233240
// Parameters of the state machine, are next.
234241
MCOS->EmitIntValue(DWARF2_LINE_MIN_INSN_LENGTH, 1);

llvm/lib/MC/MCLoggingStreamer.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -154,8 +154,7 @@ class MCLoggingStreamer : public MCStreamer {
154154
return Child->EmitBytes(Data, AddrSpace);
155155
}
156156

157-
virtual void EmitValue(const MCExpr *Value, unsigned Size,unsigned AddrSpace,
158-
bool UseSet = false){
157+
virtual void EmitValue(const MCExpr *Value, unsigned Size,unsigned AddrSpace){
159158
LogCall("EmitValue");
160159
return Child->EmitValue(Value, Size, AddrSpace);
161160
}

llvm/lib/MC/MCNullStreamer.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ namespace {
6969
virtual void EmitBytes(StringRef Data, unsigned AddrSpace) {}
7070

7171
virtual void EmitValue(const MCExpr *Value, unsigned Size,
72-
unsigned AddrSpace, bool UseSet = false) {}
72+
unsigned AddrSpace) {}
7373
virtual void EmitULEB128Value(const MCExpr *Value,
7474
unsigned AddrSpace = 0) {}
7575
virtual void EmitSLEB128Value(const MCExpr *Value,

llvm/lib/MC/MCObjectStreamer.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ const MCExpr *MCObjectStreamer::AddValueSymbols(const MCExpr *Value) {
7777
}
7878

7979
void MCObjectStreamer::EmitValue(const MCExpr *Value, unsigned Size,
80-
unsigned AddrSpace, bool UseSet) {
80+
unsigned AddrSpace) {
8181
assert(AddrSpace == 0 && "Address space must be 0!");
8282
MCDataFragment *DF = getOrCreateDataFragment();
8383

llvm/lib/Target/PTX/PTXMCAsmStreamer.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -147,8 +147,7 @@ class PTXMCAsmStreamer : public MCStreamer {
147147

148148
virtual void EmitBytes(StringRef Data, unsigned AddrSpace);
149149

150-
virtual void EmitValue(const MCExpr *Value, unsigned Size,unsigned AddrSpace,
151-
bool UseSet = false);
150+
virtual void EmitValue(const MCExpr *Value, unsigned Size,unsigned AddrSpace);
152151
virtual void EmitULEB128Value(const MCExpr *Value, unsigned AddrSpace = 0);
153152
virtual void EmitSLEB128Value(const MCExpr *Value, unsigned AddrSpace = 0);
154153
virtual void EmitGPRel32Value(const MCExpr *Value);
@@ -361,7 +360,7 @@ void PTXMCAsmStreamer::EmitBytes(StringRef Data, unsigned AddrSpace) {
361360
}
362361

363362
void PTXMCAsmStreamer::EmitValue(const MCExpr *Value, unsigned Size,
364-
unsigned AddrSpace, bool UseSet) {
363+
unsigned AddrSpace) {
365364
assert(CurSection && "Cannot emit contents before setting section!");
366365
const char *Directive = 0;
367366
switch (Size) {

llvm/lib/Target/PowerPC/PPCMCAsmInfo.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ PPCMCAsmInfoDarwin::PPCMCAsmInfoDarwin(bool is64Bit) {
2121

2222
if (!is64Bit)
2323
Data64bitsDirective = 0; // We can't emit a 64-bit unit in PPC32 mode.
24+
25+
if (is64Bit)
26+
NeedsSetToChangeDiffSize = true;
27+
2428
AssemblerDialect = 1; // New-Style mnemonics.
2529
SupportsDebugInformation= true; // Debug information.
2630
}

llvm/lib/Target/X86/X86MCAsmInfo.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,10 @@ X86MCAsmInfoDarwin::X86MCAsmInfoDarwin(const Triple &Triple) {
5656
if (!is64Bit)
5757
Data64bitsDirective = 0; // we can't emit a 64-bit unit
5858

59+
// FIXME: Darwin 10 doesn't need this.
60+
if (is64Bit)
61+
NeedsSetToChangeDiffSize = true;
62+
5963
// Use ## as a comment string so that .s files generated by llvm can go
6064
// through the GCC preprocessor without causing an error. This is needed
6165
// because "clang foo.s" runs the C preprocessor, which is usually reserved

llvm/test/MC/MachO/empty-dwarf-lines.s

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ _c:
1717
// CHECK-NEXT: ('offset', 452)
1818
// CHECK-NEXT: ('alignment', 0)
1919
// CHECK-NEXT: ('reloc_offset', 496)
20-
// CHECK-NEXT: ('num_reloc', 4)
20+
// CHECK-NEXT: ('num_reloc', 2)
2121
// CHECK-NEXT: ('flags', 0x2000000)
2222
// CHECK-NEXT: ('reserved1', 0)
2323
// CHECK-NEXT: ('reserved2', 0)

0 commit comments

Comments
 (0)