PowerPC atomic pseudos clobber CR0, they don't read it.
[oota-llvm.git] / lib / Target / PowerPC / PPCAsmBackend.cpp
1 //===-- PPCAsmBackend.cpp - PPC Assembler Backend -------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "llvm/Target/TargetAsmBackend.h"
11 #include "PPC.h"
12 #include "PPCFixupKinds.h"
13 #include "llvm/MC/MCMachObjectWriter.h"
14 #include "llvm/MC/MCSectionMachO.h"
15 #include "llvm/MC/MCObjectWriter.h"
16 #include "llvm/Object/MachOFormat.h"
17 #include "llvm/Target/TargetRegistry.h"
18 using namespace llvm;
19
20 namespace {
21 class PPCMachObjectWriter : public MCMachObjectTargetWriter {
22 public:
23   PPCMachObjectWriter(bool Is64Bit, uint32_t CPUType,
24                       uint32_t CPUSubtype)
25     : MCMachObjectTargetWriter(Is64Bit, CPUType, CPUSubtype) {}
26 };
27
28 class PPCAsmBackend : public TargetAsmBackend {
29 const Target &TheTarget;
30 public:
31   PPCAsmBackend(const Target &T) : TargetAsmBackend(), TheTarget(T) {}
32
33   unsigned getNumFixupKinds() const { return PPC::NumTargetFixupKinds; }
34
35   const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const {
36     const static MCFixupKindInfo Infos[PPC::NumTargetFixupKinds] = {
37       // name                    offset  bits  flags
38       { "fixup_ppc_br24",        6,      24,   MCFixupKindInfo::FKF_IsPCRel },
39       { "fixup_ppc_brcond14",    16,     14,   MCFixupKindInfo::FKF_IsPCRel },
40       { "fixup_ppc_lo16",        16,     16,   0 },
41       { "fixup_ppc_ha16",        16,     16,   0 },
42       { "fixup_ppc_lo14",        16,     14,   0 }
43     };
44   
45     if (Kind < FirstTargetFixupKind)
46       return TargetAsmBackend::getFixupKindInfo(Kind);
47   
48     assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() &&
49            "Invalid kind!");
50     return Infos[Kind - FirstTargetFixupKind];
51   }
52   
53   bool MayNeedRelaxation(const MCInst &Inst) const {
54     // FIXME.
55     return false;
56   }
57   
58   void RelaxInstruction(const MCInst &Inst, MCInst &Res) const {
59     // FIXME.
60     assert(0 && "RelaxInstruction() unimplemented");
61   }
62   
63   bool WriteNopData(uint64_t Count, MCObjectWriter *OW) const {
64     // FIXME: Zero fill for now. That's not right, but at least will get the
65     // section size right.
66     for (uint64_t i = 0; i != Count; ++i)
67       OW->Write8(0);
68     return true;
69   }      
70   
71   unsigned getPointerSize() const {
72     StringRef Name = TheTarget.getName();
73     if (Name == "ppc64") return 8;
74     assert(Name == "ppc32" && "Unknown target name!");
75     return 4;
76   }
77 };
78 } // end anonymous namespace
79
80
81 // FIXME: This should be in a separate file.
82 namespace {
83   class DarwinPPCAsmBackend : public PPCAsmBackend {
84   public:
85     DarwinPPCAsmBackend(const Target &T) : PPCAsmBackend(T) { }
86     
87     void ApplyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize,
88                     uint64_t Value) const {
89       assert(0 && "UNIMP");
90     }
91     
92     MCObjectWriter *createObjectWriter(raw_ostream &OS) const {
93       bool is64 = getPointerSize() == 8;
94       return createMachObjectWriter(new PPCMachObjectWriter(
95                                       /*Is64Bit=*/is64,
96                                       (is64 ? object::mach::CTM_PowerPC64 :
97                                        object::mach::CTM_PowerPC),
98                                       object::mach::CSPPC_ALL),
99                                     OS, /*IsLittleEndian=*/false);
100     }
101     
102     virtual bool doesSectionRequireSymbols(const MCSection &Section) const {
103       return false;
104     }
105   };
106 } // end anonymous namespace
107
108
109
110
111 TargetAsmBackend *llvm::createPPCAsmBackend(const Target &T,
112                                             const std::string &TT) {
113   switch (Triple(TT).getOS()) {
114   case Triple::Darwin:
115     return new DarwinPPCAsmBackend(T);
116   default:
117     return 0;
118   }
119 }