Index: lib/Target/XCore/XCoreAsmPrinter.cpp =================================================================== --- lib/Target/XCore/XCoreAsmPrinter.cpp +++ lib/Target/XCore/XCoreAsmPrinter.cpp @@ -78,6 +78,7 @@ void emitArrayBound(MCSymbol *Sym, const GlobalVariable *GV); void EmitGlobalVariable(const GlobalVariable *GV) override; + void EmitConstantPool() override; void EmitFunctionEntryLabel() override; void EmitInstruction(const MachineInstr *MI) override; @@ -123,7 +124,6 @@ MCSymbol *GVSym = getSymbol(GV); const Constant *C = GV->getInitializer(); - unsigned Align = (unsigned)TD->getPreferredTypeAlignmentShift(C->getType()); // Mark the start of the global getTargetStreamer().emitCCTopData(GVSym->getName()); @@ -152,7 +152,9 @@ llvm_unreachable("Unknown linkage type!"); } - EmitAlignment(Align > 2 ? Align : 2, GV); + // Word alignment is the minimum requirement for global variables. + // This will be rounded up to meet the GV's specifications. + EmitAlignment(2,GV); if (GV->isThreadLocal()) { report_fatal_error("TLS is not supported by this target!"); @@ -174,6 +176,54 @@ getTargetStreamer().emitCCBottomData(GVSym->getName()); } +/// EmitConstantPool - XCore version differs from the default as it calls +/// emitCCTopData & emitCCBottomData for each constant. +/// +void XCoreAsmPrinter::EmitConstantPool() { + const MachineConstantPool *MCP = MF->getConstantPool(); + const std::vector &CP = MCP->getConstants(); + if (CP.empty()) return; + + const MCSection *CurSection = nullptr; + for (unsigned i = 0, e = CP.size(); i != e; ++i) { + MachineConstantPoolEntry CPE = CP[i]; + MCSymbol *Sym = GetCPISymbol(i); + if (!Sym->isUndefined()) + continue; + + // Switch sections as needed. + SectionKind Kind = CPE.getSectionKind(TM.getDataLayout()); + const Constant *C = nullptr; + if (!CPE.isMachineConstantPoolEntry()) + C = CPE.Val.ConstVal; + const MCSection *S = getObjFileLowering().getSectionForConstant(Kind, C); + if (CurSection != S) { + OutStreamer.SwitchSection(S); + CurSection = S; + } + + getTargetStreamer().emitCCTopData(Sym->getName()); + + // We expect this to be 4, but it will be verified by the linker. + EmitAlignment(Log2_32(CPE.getAlignment())); + + if (MAI->hasDotTypeDotSizeDirective()) { + OutStreamer.EmitSymbolAttribute(Sym, MCSA_ELF_TypeObject); + unsigned Size = TM.getDataLayout()->getTypeAllocSize(CPE.getType()); + OutStreamer.EmitELFSize(Sym, MCConstantExpr::Create(Size, OutContext)); + } + + OutStreamer.EmitLabel(Sym); + + if (CPE.isMachineConstantPoolEntry()) + EmitMachineConstantPoolValue(CPE.Val.MachineCPVal); + else + EmitGlobalConstant(CPE.Val.ConstVal); + + getTargetStreamer().emitCCBottomData(Sym->getName()); + } +} + void XCoreAsmPrinter::EmitFunctionBodyStart() { MCInstLowering.Initialize(Mang, &MF->getContext()); } Index: test/CodeGen/XCore/codemodel.ll =================================================================== --- test/CodeGen/XCore/codemodel.ll +++ test/CodeGen/XCore/codemodel.ll @@ -122,11 +122,11 @@ ; CHECK-NEXT: retsp 0 ; ; LARGE: .section .cp.rodata,"ac",@progbits -; LARGE: .LCPI{{[0-9_]*}} -; LARGE-NEXT: .long NoSize -; LARGE-NEXT: .text +; LARGE: .LCPI[[CNST0:[0-9_]+]]: +; LARGE-NEXT: .long NoSize+40 +; LARGE-NEXT: .cc_bottom ; LARGE-LABEL: UnknownSize: -; LARGE: ldw r0, cp[.LCPI{{[0-9_]*}}] +; LARGE: ldw r0, cp[.LCPI[[CNST0]]] ; LARGE-NEXT: ldw r0, r0[0] ; LARGE-NEXT: retsp 0 @NoSize = external global [0 x i32] @@ -142,11 +142,11 @@ ; CHECK-NEXT: retsp 0 ; ; LARGE: .section .cp.rodata,"ac",@progbits -; LARGE: .LCPI{{[0-9_]*}} +; LARGE: .LCPI[[CNST1:[0-9_]+]]: ; LARGE-NEXT: .long Unknown -; LARGE-NEXT: .text +; LARGE-NEXT: .cc_bottom ; LARGE-LABEL: UnknownStruct: -; LARGE: ldw r0, cp[.LCPI{{[0-9_]*}}] +; LARGE: ldw r0, cp[.LCPI[[CNST1]]] ; LARGE-NEXT: retsp 0 %Struct = type opaque @Unknown = external global %Struct Index: test/CodeGen/XCore/constants.ll =================================================================== --- test/CodeGen/XCore/constants.ll +++ test/CodeGen/XCore/constants.ll @@ -17,3 +17,57 @@ ; CHECK: retsp 0 ret i32 1; } + + +; Rules governing how .align directives are calculated. + +; section & align: use align. +@cg1 = constant i32 0, section ".NAMEDSECT", align 2 +; CHECK: .section .NAMEDSECT,"ad",@progbits +; CHECK: .globl cg1 +; CHECK: .align 2 +; CHECK: size cg1, 4 + +; section & no align: use max of type alignment & 4. +@cg2 = constant i64 0, section ".NAMEDSECT" +; CHECK: .globl cg2 +; CHECK: .align 4 +; CHECK: size cg2, 8 + +; section & no align: use max of type alignment & 4. +@cg3 = constant i8 0, section ".NAMEDSECT" +; CHECK: .globl cg3 +; CHECK: .align 4 +; CHECK: size cg3, 1 + +; align: use max of align, type alignment & 4. +@cg4 = constant i8 0, align 2 +; CHECK: .section .dp.rodata,"awd",@progbits +; CHECK: .globl cg4 +; CHECK: .align 4 +; CHECK: .size cg4, 1 + +; align: use max of align, type alignment & 4. +@cg5 = constant i8 0, align 8 +; CHECK: .globl cg5 +; CHECK: .align 8 +; CHECK: .size cg5, 1 + +; align: use max of align, type alignment & 4. +@cg6 = constant i64 0, align 2 +; CHECK: .globl cg6 +; CHECK: .align 4 +; CHECK: .size cg6, 8 + +; : use max of type alignment & 4. +@cg7 = constant i64 0, align 2 +; CHECK: .globl cg7 +; CHECK: .align 4 +; CHECK: .size cg7, 8 + +; : use max of type alignment & 4. +@cg8 = constant i8 0, align 2 +; CHECK: .globl cg8 +; CHECK: .align 4 +; CHECK: .size cg8, 1 + Index: test/CodeGen/XCore/epilogue_prologue.ll =================================================================== --- test/CodeGen/XCore/epilogue_prologue.ll +++ test/CodeGen/XCore/epilogue_prologue.ll @@ -101,11 +101,20 @@ ; FP + large frame: spill FP+SR+R4+LR = entsp 3 + 200000 + extsp 1 ; CHECKFP: .section .cp.rodata.cst4,"aMc",@progbits,4 +; CHECKFP-NEXT: .cc_top .LCPI[[CNST0:[0-9_]+]].data,.LCPI[[CNST0]] ; CHECKFP-NEXT: .align 4 -; CHECKFP-NEXT: .LCPI[[CNST0:[0-9_]+]]: +; CHECKFP-NEXT: .type .LCPI[[CNST0]],@object +; CHECKFP-NEXT: .size .LCPI[[CNST0]], 4 +; CHECKFP-NEXT: .LCPI[[CNST0]]: ; CHECKFP-NEXT: .long 200002 -; CHECKFP-NEXT: .LCPI[[CNST1:[0-9_]+]]: +; CHECKFP-NEXT: .cc_bottom .LCPI[[CNST0]].data +; CHECKFP-NEXT: .cc_top .LCPI[[CNST1:[0-9_]+]].data,.LCPI[[CNST1]] +; CHECKFP-NEXT: .align 4 +; CHECKFP-NEXT: .type .LCPI[[CNST1]],@object +; CHECKFP-NEXT: .size .LCPI[[CNST1]], 4 +; CHECKFP-NEXT: .LCPI[[CNST1]]: ; CHECKFP-NEXT: .long 200001 +; CHECKFP-NEXT: .cc_bottom .LCPI[[CNST1]].data ; CHECKFP-NEXT: .text ; CHECKFP-LABEL: f6 ; CHECKFP: entsp 65535 @@ -154,11 +163,20 @@ ; ; !FP + large frame: spill SR+SR+R4+LR = entsp 4 + 200000 ; CHECK: .section .cp.rodata.cst4,"aMc",@progbits,4 +; CHECK-NEXT: .cc_top .LCPI[[CNST0:[0-9_]+]].data,.LCPI[[CNST0]] ; CHECK-NEXT: .align 4 -; CHECK-NEXT: .LCPI[[CNST0:[0-9_]+]]: +; CHECK-NEXT: .type .LCPI[[CNST0]],@object +; CHECK-NEXT: .size .LCPI[[CNST0]], 4 +; CHECK-NEXT: .LCPI[[CNST0]]: ; CHECK-NEXT: .long 200003 -; CHECK-NEXT: .LCPI[[CNST1:[0-9_]+]]: +; CHECK-NEXT: .cc_bottom .LCPI[[CNST0]].data +; CHECK-NEXT: .cc_top .LCPI[[CNST1:[0-9_]+]].data,.LCPI[[CNST1]] +; CHECK-NEXT: .align 4 +; CHECK-NEXT: .type .LCPI[[CNST1]],@object +; CHECK-NEXT: .size .LCPI[[CNST1]], 4 +; CHECK-NEXT: .LCPI[[CNST1]]: ; CHECK-NEXT: .long 200002 +; CHECK-NEXT: .cc_bottom .LCPI[[CNST1]].data ; CHECK-NEXT: .text ; CHECK-LABEL: f6 ; CHECK: entsp 65535