New "TargetObjInfo" class. This holds information that the object writers will
[oota-llvm.git] / lib / Target / PowerPC / PPCTargetObjInfo.h
1 //===-- PPCTargetObjInfo.h - Object File Info --------------------*- C++ -*-==//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file was developed by Bill Wendling and is distributed under the
6 // University of Illinois Open Source License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines target object file properties for PowerPC.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #ifndef PPCTARGETOBJINFO_H
15 #define PPCTARGETOBJINFO_H
16
17 #include "llvm/Target/TargetObjInfo.h"
18
19 namespace llvm {
20
21   class TargetMachine;
22
23   struct MachOTargetObjInfo : public TargetObjInfo {
24     MachOTargetObjInfo(const TargetMachine &PPC_TM);
25
26     // align - Emit padding into the file until the current output position is
27     // aligned to the specified power of two boundary.
28     virtual void align(DataBuffer &Output, unsigned Boundary) const {
29       assert(Boundary && (Boundary & (Boundary-1)) == 0 &&
30              "Must align to 2^k boundary");
31       size_t Size = Output.size();
32
33       if (Size & (Boundary-1)) {
34         // Add padding to get alignment to the correct place.
35         size_t Pad = Boundary - (Size & (Boundary - 1));
36         Output.resize(Size + Pad);
37       }
38     }
39
40     //===------------------------------------------------------------------===//
41     // Out Functions - Output the specified value to the data buffer.
42
43     virtual void outbyte(DataBuffer &Output, unsigned char X) const {
44       Output.push_back(X);
45     }
46     virtual void outhalf(DataBuffer &Output, unsigned short X) const {
47       if (isLittleEndian) {
48         Output.push_back(X & 255);
49         Output.push_back(X >> 8);
50       } else {
51         Output.push_back(X >> 8);
52         Output.push_back(X & 255);
53       }
54     }
55     virtual void outword(DataBuffer &Output, unsigned X) const {
56       if (isLittleEndian) {
57         Output.push_back((X >>  0) & 255);
58         Output.push_back((X >>  8) & 255);
59         Output.push_back((X >> 16) & 255);
60         Output.push_back((X >> 24) & 255);
61       } else {
62         Output.push_back((X >> 24) & 255);
63         Output.push_back((X >> 16) & 255);
64         Output.push_back((X >>  8) & 255);
65         Output.push_back((X >>  0) & 255);
66       }
67     }
68     virtual void outxword(DataBuffer &Output, uint64_t X) const {
69       if (isLittleEndian) {
70         Output.push_back(unsigned(X >>  0) & 255);
71         Output.push_back(unsigned(X >>  8) & 255);
72         Output.push_back(unsigned(X >> 16) & 255);
73         Output.push_back(unsigned(X >> 24) & 255);
74         Output.push_back(unsigned(X >> 32) & 255);
75         Output.push_back(unsigned(X >> 40) & 255);
76         Output.push_back(unsigned(X >> 48) & 255);
77         Output.push_back(unsigned(X >> 56) & 255);
78       } else {
79         Output.push_back(unsigned(X >> 56) & 255);
80         Output.push_back(unsigned(X >> 48) & 255);
81         Output.push_back(unsigned(X >> 40) & 255);
82         Output.push_back(unsigned(X >> 32) & 255);
83         Output.push_back(unsigned(X >> 24) & 255);
84         Output.push_back(unsigned(X >> 16) & 255);
85         Output.push_back(unsigned(X >>  8) & 255);
86         Output.push_back(unsigned(X >>  0) & 255);
87       }
88     }
89     virtual void outaddr32(DataBuffer &Output, unsigned X) const {
90       outword(Output, X);
91     }
92     virtual void outaddr64(DataBuffer &Output, uint64_t X) const {
93       outxword(Output, X);
94     }
95     virtual void outaddr(DataBuffer &Output, uint64_t X) const {
96       if (!is64Bit)
97         outword(Output, (unsigned)X);
98       else
99         outxword(Output, X);
100     }
101     virtual void outstring(DataBuffer &Output, std::string &S,
102                            unsigned Length) const {
103       unsigned len_to_copy = S.length() < Length ? S.length() : Length;
104       unsigned len_to_fill = S.length() < Length ? Length-S.length() : 0;
105
106       for (unsigned i = 0; i < len_to_copy; ++i)
107         outbyte(Output, S[i]);
108
109       for (unsigned i = 0; i < len_to_fill; ++i)
110         outbyte(Output, 0);
111     }
112
113     //===------------------------------------------------------------------===//
114     // Fix Functions - Replace an existing entry at an offset.
115
116     virtual void fixhalf(DataBuffer &Output, unsigned short X,
117                          unsigned Offset) const {
118       unsigned char *P = &Output[Offset];
119       P[0] = (X >> (isLittleEndian ?  0 : 8)) & 255;
120       P[1] = (X >> (isLittleEndian ?  8 : 0)) & 255;
121     }
122     virtual void fixword(DataBuffer &Output, unsigned X,
123                          unsigned Offset) const {
124       unsigned char *P = &Output[Offset];
125       P[0] = (X >> (isLittleEndian ?  0 : 24)) & 255;
126       P[1] = (X >> (isLittleEndian ?  8 : 16)) & 255;
127       P[2] = (X >> (isLittleEndian ? 16 :  8)) & 255;
128       P[3] = (X >> (isLittleEndian ? 24 :  0)) & 255;
129     }
130     virtual void fixaddr(DataBuffer &Output, uint64_t X,
131                          unsigned Offset) const {
132       // Not implemented
133     }
134   private:
135     /// Target machine description.
136     const TargetMachine &TM;
137
138     /// is64Bit/isLittleEndian - This information is inferred from the target
139     /// machine directly, indicating what header values and flags to set.
140     bool is64Bit, isLittleEndian;
141   };
142
143 } // end llvm namespace
144
145 #endif // PPCTARGETOBJINFO_H