blob: 75cfcd994a569a2927262515bd0fcab13bc60539 [file] [log] [blame]
Chris Lattner72614082002-10-25 22:55:53 +00001//===-- X86/Printer.cpp - Convert X86 code to human readable rep. ---------===//
2//
3// This file contains a printer that converts from our internal representation
4// of LLVM code to a nice human readable form that is suitable for debuggging.
5//
6//===----------------------------------------------------------------------===//
7
8#include "X86.h"
Brian Gaeke6559bb92002-11-14 22:32:30 +00009#include "X86InstrInfo.h"
Brian Gaeke6559bb92002-11-14 22:32:30 +000010#include "llvm/Function.h"
Chris Lattnerb7089442003-01-13 00:35:03 +000011#include "llvm/Constant.h"
Brian Gaeke6559bb92002-11-14 22:32:30 +000012#include "llvm/Target/TargetMachine.h"
Chris Lattner0285a332002-12-28 20:25:38 +000013#include "llvm/CodeGen/MachineFunctionPass.h"
Chris Lattnerb7089442003-01-13 00:35:03 +000014#include "llvm/CodeGen/MachineConstantPool.h"
Chris Lattnerdbb61c62002-11-17 22:53:13 +000015#include "llvm/CodeGen/MachineInstr.h"
Chris Lattner233ad712002-11-21 01:33:44 +000016#include "Support/Statistic.h"
Brian Gaeke01d79ff2003-06-25 18:01:07 +000017#include "Support/hash_map"
18#include "llvm/Type.h"
19#include "llvm/Constants.h"
20#include "llvm/Assembly/Writer.h"
21#include "llvm/DerivedTypes.h"
22#include "llvm/SlotCalculator.h"
23#include "Support/StringExtras.h"
24#include "llvm/Module.h"
Chris Lattner72614082002-10-25 22:55:53 +000025
Chris Lattnerb4f68ed2002-10-29 22:37:54 +000026namespace {
Brian Gaeke5e001572003-06-26 18:02:30 +000027 unsigned fnIndex;
Brian Gaekebc601fe2003-06-25 22:00:39 +000028 std::set<const Value*> MangledGlobals;
Chris Lattner0285a332002-12-28 20:25:38 +000029 struct Printer : public MachineFunctionPass {
Chris Lattnerb4f68ed2002-10-29 22:37:54 +000030 std::ostream &O;
Brian Gaeke5e001572003-06-26 18:02:30 +000031 Printer(std::ostream &o) : O(o) {}
Brian Gaeke01d79ff2003-06-25 18:01:07 +000032 const TargetData *TD;
Chris Lattnerf0eb7be2002-12-15 21:13:40 +000033 virtual const char *getPassName() const {
34 return "X86 Assembly Printer";
35 }
36
Brian Gaeke01d79ff2003-06-25 18:01:07 +000037 void printConstantPool(MachineConstantPool *MCP);
38 bool runOnMachineFunction(MachineFunction &F);
39 std::string ConstantExprToString(const ConstantExpr* CE);
40 std::string valToExprString(const Value* V);
Brian Gaeke9e474c42003-06-19 19:32:32 +000041 bool doInitialization(Module &M);
42 bool doFinalization(Module &M);
Brian Gaeke01d79ff2003-06-25 18:01:07 +000043 void PrintZeroBytesToPad(int numBytes);
44 void printConstantValueOnly(const Constant* CV, int numPadBytesAfter = 0);
45 void printSingleConstantValue(const Constant* CV);
Chris Lattnerb4f68ed2002-10-29 22:37:54 +000046 };
Brian Gaeke01d79ff2003-06-25 18:01:07 +000047 std::map<const Value *, unsigned> NumberForBB;
Chris Lattnerb4f68ed2002-10-29 22:37:54 +000048}
49
Chris Lattnerdbb61c62002-11-17 22:53:13 +000050/// createX86CodePrinterPass - Print out the specified machine code function to
51/// the specified stream. This function should work regardless of whether or
52/// not the function is in SSA form or not.
53///
Chris Lattner0285a332002-12-28 20:25:38 +000054Pass *createX86CodePrinterPass(std::ostream &O) {
55 return new Printer(O);
Chris Lattnerdbb61c62002-11-17 22:53:13 +000056}
57
Brian Gaekebc601fe2003-06-25 22:00:39 +000058// We dont want identifier names with ., space, - in them.
59// So we replace them with _
60static std::string makeNameProper(std::string x) {
61 std::string tmp;
62 for (std::string::iterator sI = x.begin(), sEnd = x.end(); sI != sEnd; sI++)
63 switch (*sI) {
64 case '.': tmp += "d_"; break;
65 case ' ': tmp += "s_"; break;
66 case '-': tmp += "D_"; break;
67 default: tmp += *sI;
68 }
69
70 return tmp;
71}
72
73std::string getValueName(const Value *V) {
74 if (V->hasName()) { // Print out the label if it exists...
75
76 // Name mangling occurs as follows:
77 // - If V is not a global, mangling always occurs.
78 // - Otherwise, mangling occurs when any of the following are true:
79 // 1) V has internal linkage
80 // 2) V's name would collide if it is not mangled.
81 //
82
83 if(const GlobalValue* gv = dyn_cast<GlobalValue>(V)) {
84 if(!gv->hasInternalLinkage() && !MangledGlobals.count(gv)) {
85 // No internal linkage, name will not collide -> no mangling.
86 return makeNameProper(gv->getName());
87 }
88 }
89
90 // Non-global, or global with internal linkage / colliding name -> mangle.
91 return "l" + utostr(V->getType()->getUniqueID()) + "_" +
92 makeNameProper(V->getName());
93 }
94
95 static int Count = 0;
96 Count++;
97 return "ltmp_" + itostr(Count) + "_" + utostr(V->getType()->getUniqueID());
98}
99
100
Brian Gaeke01d79ff2003-06-25 18:01:07 +0000101// valToExprString - Helper function for ConstantExprToString().
102// Appends result to argument string S.
103//
104std::string Printer::valToExprString(const Value* V) {
105 std::string S;
106 bool failed = false;
107 if (const Constant* CV = dyn_cast<Constant>(V)) { // symbolic or known
108 if (const ConstantBool *CB = dyn_cast<ConstantBool>(CV))
109 S += std::string(CB == ConstantBool::True ? "1" : "0");
110 else if (const ConstantSInt *CI = dyn_cast<ConstantSInt>(CV))
111 S += itostr(CI->getValue());
112 else if (const ConstantUInt *CI = dyn_cast<ConstantUInt>(CV))
113 S += utostr(CI->getValue());
114 else if (const ConstantFP *CFP = dyn_cast<ConstantFP>(CV))
115 S += ftostr(CFP->getValue());
116 else if (isa<ConstantPointerNull>(CV))
117 S += "0";
118 else if (const ConstantPointerRef *CPR = dyn_cast<ConstantPointerRef>(CV))
119 S += valToExprString(CPR->getValue());
120 else if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(CV))
121 S += ConstantExprToString(CE);
122 else
123 failed = true;
124 } else if (const GlobalValue* GV = dyn_cast<GlobalValue>(V)) {
Brian Gaekebc601fe2003-06-25 22:00:39 +0000125 S += getValueName(GV);
Brian Gaeke01d79ff2003-06-25 18:01:07 +0000126 }
127 else
128 failed = true;
129
130 if (failed) {
131 assert(0 && "Cannot convert value to string");
132 S += "<illegal-value>";
133 }
134 return S;
135}
136
137// ConstantExprToString() - Convert a ConstantExpr to an asm expression
138// and return this as a string.
139std::string Printer::ConstantExprToString(const ConstantExpr* CE) {
140 std::string S;
141 switch(CE->getOpcode()) {
142 case Instruction::GetElementPtr:
143 { // generate a symbolic expression for the byte address
144 const Value* ptrVal = CE->getOperand(0);
145 std::vector<Value*> idxVec(CE->op_begin()+1, CE->op_end());
146 S += "(" + valToExprString(ptrVal) + ") + ("
147 + utostr(TD->getIndexedOffset(ptrVal->getType(),idxVec)) + ")";
148 break;
149 }
150
151 case Instruction::Cast:
152 // Support only non-converting casts for now, i.e., a no-op.
153 // This assertion is not a complete check.
154 assert(TD->getTypeSize(CE->getType()) ==
155 TD->getTypeSize(CE->getOperand(0)->getType()));
156 S += "(" + valToExprString(CE->getOperand(0)) + ")";
157 break;
158
159 case Instruction::Add:
160 S += "(" + valToExprString(CE->getOperand(0)) + ") + ("
161 + valToExprString(CE->getOperand(1)) + ")";
162 break;
163
164 default:
165 assert(0 && "Unsupported operator in ConstantExprToString()");
166 break;
167 }
168
169 return S;
170}
171
172// Print a single constant value.
173void
174Printer::printSingleConstantValue(const Constant* CV)
175{
176 assert(CV->getType() != Type::VoidTy &&
177 CV->getType() != Type::TypeTy &&
178 CV->getType() != Type::LabelTy &&
179 "Unexpected type for Constant");
180
181 assert((!isa<ConstantArray>(CV) && ! isa<ConstantStruct>(CV))
182 && "Aggregate types should be handled outside this function");
183
184 const Type *type = CV->getType();
185 O << "\t";
186 switch(type->getPrimitiveID())
187 {
188 case Type::BoolTyID: case Type::UByteTyID: case Type::SByteTyID:
189 O << ".byte";
190 break;
191 case Type::UShortTyID: case Type::ShortTyID:
192 O << ".word";
193 break;
194 case Type::UIntTyID: case Type::IntTyID: case Type::PointerTyID:
195 O << ".long";
196 break;
197 case Type::ULongTyID: case Type::LongTyID:
198 O << ".quad";
199 break;
200 case Type::FloatTyID:
201 O << ".long";
202 break;
203 case Type::DoubleTyID:
204 O << ".quad";
205 break;
206 case Type::ArrayTyID:
207 if ((cast<ArrayType>(type)->getElementType() == Type::UByteTy) ||
208 (cast<ArrayType>(type)->getElementType() == Type::SByteTy))
209 O << ".string";
210 else
211 assert (0 && "Can't handle printing this type of array");
212 break;
213 default:
214 assert (0 && "Can't handle printing this type of thing");
215 break;
216 }
217 O << "\t";
218
219 if (type->isPrimitiveType())
220 {
221 if (type->isFloatingPoint()) {
222 // FP Constants are printed as integer constants to avoid losing
223 // precision...
224 double Val = cast<ConstantFP>(CV)->getValue();
225 if (type == Type::FloatTy) {
226 float FVal = (float)Val;
227 char *ProxyPtr = (char*)&FVal; // Abide by C TBAA rules
228 O << *(unsigned int*)ProxyPtr;
229 } else if (type == Type::DoubleTy) {
230 char *ProxyPtr = (char*)&Val; // Abide by C TBAA rules
231 O << *(uint64_t*)ProxyPtr;
232 } else {
233 assert(0 && "Unknown floating point type!");
234 }
235
236 O << "\t# " << type->getDescription() << " value: " << Val << "\n";
237 } else {
238 WriteAsOperand(O, CV, false, false) << "\n";
239 }
240 }
241 else if (const ConstantPointerRef* CPR = dyn_cast<ConstantPointerRef>(CV))
242 {
243 // This is a constant address for a global variable or method.
244 // Use the name of the variable or method as the address value.
Brian Gaekebc601fe2003-06-25 22:00:39 +0000245 O << getValueName(CPR->getValue()) << "\n";
Brian Gaeke01d79ff2003-06-25 18:01:07 +0000246 }
247 else if (isa<ConstantPointerNull>(CV))
248 {
249 // Null pointer value
250 O << "0\n";
251 }
252 else if (const ConstantExpr* CE = dyn_cast<ConstantExpr>(CV))
253 {
254 // Constant expression built from operators, constants, and
255 // symbolic addrs
256 O << ConstantExprToString(CE) << "\n";
257 }
258 else
259 {
260 assert(0 && "Unknown elementary type for constant");
261 }
262}
263
264// Can we treat the specified array as a string? Only if it is an array of
265// ubytes or non-negative sbytes.
266//
267static bool isStringCompatible(const ConstantArray *CVA) {
268 const Type *ETy = cast<ArrayType>(CVA->getType())->getElementType();
269 if (ETy == Type::UByteTy) return true;
270 if (ETy != Type::SByteTy) return false;
271
272 for (unsigned i = 0; i < CVA->getNumOperands(); ++i)
273 if (cast<ConstantSInt>(CVA->getOperand(i))->getValue() < 0)
274 return false;
275
276 return true;
277}
278
279// toOctal - Convert the low order bits of X into an octal letter
280static inline char toOctal(int X) {
281 return (X&7)+'0';
282}
283
284// getAsCString - Return the specified array as a C compatible string, only if
285// the predicate isStringCompatible is true.
286//
287static std::string getAsCString(const ConstantArray *CVA) {
288 assert(isStringCompatible(CVA) && "Array is not string compatible!");
289
290 std::string Result;
291 const Type *ETy = cast<ArrayType>(CVA->getType())->getElementType();
292 Result = "\"";
293 for (unsigned i = 0; i < CVA->getNumOperands(); ++i) {
294 unsigned char C = (ETy == Type::SByteTy) ?
295 (unsigned char)cast<ConstantSInt>(CVA->getOperand(i))->getValue() :
296 (unsigned char)cast<ConstantUInt>(CVA->getOperand(i))->getValue();
297
298 if (C == '"') {
299 Result += "\\\"";
300 } else if (C == '\\') {
301 Result += "\\\\";
302 } else if (isprint(C)) {
303 Result += C;
304 } else {
305 switch(C) {
306 case '\a': Result += "\\a"; break;
307 case '\b': Result += "\\b"; break;
308 case '\f': Result += "\\f"; break;
309 case '\n': Result += "\\n"; break;
310 case '\r': Result += "\\r"; break;
311 case '\t': Result += "\\t"; break;
312 case '\v': Result += "\\v"; break;
313 default:
314 Result += '\\';
315 Result += toOctal(C >> 6);
316 Result += toOctal(C >> 3);
317 Result += toOctal(C >> 0);
318 break;
319 }
320 }
321 }
322 Result += "\"";
323 return Result;
324}
325
326// Print a constant value or values (it may be an aggregate).
327// Uses printSingleConstantValue() to print each individual value.
328void
329Printer::printConstantValueOnly(const Constant* CV,
330 int numPadBytesAfter /* = 0 */)
331{
332 const ConstantArray *CVA = dyn_cast<ConstantArray>(CV);
333
334 if (CVA && isStringCompatible(CVA))
335 { // print the string alone and return
336 O << "\t" << ".string" << "\t" << getAsCString(CVA) << "\n";
337 }
338 else if (CVA)
339 { // Not a string. Print the values in successive locations
340 const std::vector<Use> &constValues = CVA->getValues();
341 for (unsigned i=0; i < constValues.size(); i++)
342 printConstantValueOnly(cast<Constant>(constValues[i].get()));
343 }
344 else if (const ConstantStruct *CVS = dyn_cast<ConstantStruct>(CV))
345 { // Print the fields in successive locations. Pad to align if needed!
346 const StructLayout *cvsLayout =
347 TD->getStructLayout(CVS->getType());
348 const std::vector<Use>& constValues = CVS->getValues();
349 unsigned sizeSoFar = 0;
350 for (unsigned i=0, N = constValues.size(); i < N; i++)
351 {
352 const Constant* field = cast<Constant>(constValues[i].get());
353
354 // Check if padding is needed and insert one or more 0s.
355 unsigned fieldSize = TD->getTypeSize(field->getType());
356 int padSize = ((i == N-1? cvsLayout->StructSize
357 : cvsLayout->MemberOffsets[i+1])
358 - cvsLayout->MemberOffsets[i]) - fieldSize;
359 sizeSoFar += (fieldSize + padSize);
360
361 // Now print the actual field value
362 printConstantValueOnly(field, padSize);
363 }
364 assert(sizeSoFar == cvsLayout->StructSize &&
365 "Layout of constant struct may be incorrect!");
366 }
367 else
368 printSingleConstantValue(CV);
369
370 if (numPadBytesAfter) {
371 unsigned numBytes = numPadBytesAfter;
372 for ( ; numBytes >= 8; numBytes -= 8)
373 printSingleConstantValue(Constant::getNullValue(Type::ULongTy));
374 if (numBytes >= 4)
375 {
376 printSingleConstantValue(Constant::getNullValue(Type::UIntTy));
377 numBytes -= 4;
378 }
379 while (numBytes--)
380 printSingleConstantValue(Constant::getNullValue(Type::UByteTy));
381 }
382}
Chris Lattnerdbb61c62002-11-17 22:53:13 +0000383
Chris Lattnerb7089442003-01-13 00:35:03 +0000384// printConstantPool - Print out any constants which have been spilled to
385// memory...
Brian Gaeke01d79ff2003-06-25 18:01:07 +0000386void Printer::printConstantPool(MachineConstantPool *MCP){
Chris Lattnerb7089442003-01-13 00:35:03 +0000387 const std::vector<Constant*> &CP = MCP->getConstants();
388 if (CP.empty()) return;
389
390 for (unsigned i = 0, e = CP.size(); i != e; ++i) {
391 O << "\t.section .rodata\n";
Brian Gaeke5e001572003-06-26 18:02:30 +0000392 O << "\t.align " << (unsigned)TD->getTypeAlignment(CP[i]->getType())
393 << "\n";
394 O << ".CPI" << fnIndex << "_" << i << ":\t\t\t\t\t#" << *CP[i] << "\n";
Brian Gaeke01d79ff2003-06-25 18:01:07 +0000395 printConstantValueOnly (CP[i]);
Chris Lattnerb7089442003-01-13 00:35:03 +0000396 }
Chris Lattnerb7089442003-01-13 00:35:03 +0000397}
398
Brian Gaeke01d79ff2003-06-25 18:01:07 +0000399/// runOnMachineFunction - This uses the X86InstructionInfo::print method
Brian Gaeke6559bb92002-11-14 22:32:30 +0000400/// to print assembly for each instruction.
Chris Lattner0285a332002-12-28 20:25:38 +0000401bool Printer::runOnMachineFunction(MachineFunction &MF) {
402 static unsigned BBNumber = 0;
403 const TargetMachine &TM = MF.getTarget();
Chris Lattner3501fea2003-01-14 22:00:31 +0000404 const TargetInstrInfo &TII = TM.getInstrInfo();
Brian Gaeke01d79ff2003-06-25 18:01:07 +0000405 TD = &TM.getTargetData();
Brian Gaeke6559bb92002-11-14 22:32:30 +0000406
Chris Lattnerb7089442003-01-13 00:35:03 +0000407 // Print out constants referenced by the function
Brian Gaeke01d79ff2003-06-25 18:01:07 +0000408 printConstantPool(MF.getConstantPool());
Chris Lattnerb7089442003-01-13 00:35:03 +0000409
Brian Gaeke6559bb92002-11-14 22:32:30 +0000410 // Print out labels for the function.
Chris Lattnerb7089442003-01-13 00:35:03 +0000411 O << "\t.text\n";
412 O << "\t.align 16\n";
Brian Gaekebc601fe2003-06-25 22:00:39 +0000413 O << "\t.globl\t" << getValueName(MF.getFunction()) << "\n";
414 O << "\t.type\t" << getValueName(MF.getFunction()) << ", @function\n";
415 O << getValueName(MF.getFunction()) << ":\n";
Brian Gaeke6559bb92002-11-14 22:32:30 +0000416
Brian Gaeke01d79ff2003-06-25 18:01:07 +0000417 NumberForBB.clear();
418 for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
419 I != E; ++I) {
420 NumberForBB[I->getBasicBlock()] = BBNumber++;
421 }
422
Brian Gaeke6559bb92002-11-14 22:32:30 +0000423 // Print out code for the function.
Chris Lattner0285a332002-12-28 20:25:38 +0000424 for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
425 I != E; ++I) {
426 // Print a label for the basic block.
Brian Gaeke01d79ff2003-06-25 18:01:07 +0000427 O << ".BB" << NumberForBB[I->getBasicBlock()] << ":\t# "
428 << I->getBasicBlock()->getName() << "\n";
Chris Lattner0285a332002-12-28 20:25:38 +0000429 for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
430 II != E; ++II) {
431 // Print the assembly for the instruction.
432 O << "\t";
Chris Lattner3501fea2003-01-14 22:00:31 +0000433 TII.print(*II, O, TM);
Brian Gaeke6559bb92002-11-14 22:32:30 +0000434 }
Chris Lattner0285a332002-12-28 20:25:38 +0000435 }
Brian Gaeke6559bb92002-11-14 22:32:30 +0000436
Brian Gaeke5e001572003-06-26 18:02:30 +0000437 fnIndex++;
Brian Gaeke6559bb92002-11-14 22:32:30 +0000438 // We didn't modify anything.
Chris Lattnerb4f68ed2002-10-29 22:37:54 +0000439 return false;
440}
441
Chris Lattner3d3067b2002-11-21 20:44:15 +0000442static bool isScale(const MachineOperand &MO) {
Chris Lattnerd9096832002-12-15 08:01:39 +0000443 return MO.isImmediate() &&
Brian Gaeke01d79ff2003-06-25 18:01:07 +0000444 (MO.getImmedValue() == 1 || MO.getImmedValue() == 2 ||
445 MO.getImmedValue() == 4 || MO.getImmedValue() == 8);
Chris Lattner3d3067b2002-11-21 20:44:15 +0000446}
447
448static bool isMem(const MachineInstr *MI, unsigned Op) {
Chris Lattnerb7089442003-01-13 00:35:03 +0000449 if (MI->getOperand(Op).isFrameIndex()) return true;
450 if (MI->getOperand(Op).isConstantPoolIndex()) return true;
Chris Lattner3d3067b2002-11-21 20:44:15 +0000451 return Op+4 <= MI->getNumOperands() &&
Brian Gaeke01d79ff2003-06-25 18:01:07 +0000452 MI->getOperand(Op ).isRegister() &&isScale(MI->getOperand(Op+1)) &&
453 MI->getOperand(Op+2).isRegister() &&MI->getOperand(Op+3).isImmediate();
Chris Lattner3d3067b2002-11-21 20:44:15 +0000454}
455
Chris Lattnerf9f60882002-11-18 06:56:51 +0000456static void printOp(std::ostream &O, const MachineOperand &MO,
Brian Gaeke01d79ff2003-06-25 18:01:07 +0000457 const MRegisterInfo &RI, bool elideOffsetKeyword = false) {
Chris Lattnerf9f60882002-11-18 06:56:51 +0000458 switch (MO.getType()) {
459 case MachineOperand::MO_VirtualRegister:
Chris Lattnerac573f62002-12-04 17:32:52 +0000460 if (Value *V = MO.getVRegValueOrNull()) {
Chris Lattnerdbf30f72002-12-04 06:45:19 +0000461 O << "<" << V->getName() << ">";
462 return;
463 }
Chris Lattnerb7089442003-01-13 00:35:03 +0000464 // FALLTHROUGH
Misha Brukmane1f0d812002-11-20 18:56:41 +0000465 case MachineOperand::MO_MachineRegister:
Chris Lattnerf9f60882002-11-18 06:56:51 +0000466 if (MO.getReg() < MRegisterInfo::FirstVirtualRegister)
467 O << RI.get(MO.getReg()).Name;
468 else
469 O << "%reg" << MO.getReg();
470 return;
Chris Lattner77875d82002-11-21 02:00:20 +0000471
472 case MachineOperand::MO_SignExtendedImmed:
473 case MachineOperand::MO_UnextendedImmed:
474 O << (int)MO.getImmedValue();
475 return;
Chris Lattnerf8bafe82002-12-01 23:25:59 +0000476 case MachineOperand::MO_PCRelativeDisp:
Brian Gaeke01d79ff2003-06-25 18:01:07 +0000477 O << ".BB" << NumberForBB[MO.getVRegValue()] << " # PC rel: "
478 << MO.getVRegValue()->getName();
Chris Lattnerf8bafe82002-12-01 23:25:59 +0000479 return;
Chris Lattnerb7089442003-01-13 00:35:03 +0000480 case MachineOperand::MO_GlobalAddress:
Brian Gaekebc601fe2003-06-25 22:00:39 +0000481 if (!elideOffsetKeyword) O << "OFFSET "; O << getValueName(MO.getGlobal());
Chris Lattnerb7089442003-01-13 00:35:03 +0000482 return;
483 case MachineOperand::MO_ExternalSymbol:
Brian Gaeke9e474c42003-06-19 19:32:32 +0000484 O << MO.getSymbolName();
Chris Lattnerb7089442003-01-13 00:35:03 +0000485 return;
Chris Lattnerf9f60882002-11-18 06:56:51 +0000486 default:
Brian Gaeke01d79ff2003-06-25 18:01:07 +0000487 O << "<unknown operand type>"; return;
Chris Lattnerf9f60882002-11-18 06:56:51 +0000488 }
489}
490
Chris Lattner3501fea2003-01-14 22:00:31 +0000491static const std::string sizePtr(const TargetInstrDescriptor &Desc) {
Chris Lattnera0f38c82002-12-13 03:51:55 +0000492 switch (Desc.TSFlags & X86II::ArgMask) {
Brian Gaeke01d79ff2003-06-25 18:01:07 +0000493 default: assert(0 && "Unknown arg size!");
494 case X86II::Arg8: return "BYTE PTR";
495 case X86II::Arg16: return "WORD PTR";
496 case X86II::Arg32: return "DWORD PTR";
497 case X86II::Arg64: return "QWORD PTR";
498 case X86II::ArgF32: return "DWORD PTR";
499 case X86II::ArgF64: return "QWORD PTR";
500 case X86II::ArgF80: return "XWORD PTR";
Brian Gaeke86764d72002-12-05 08:30:40 +0000501 }
502}
503
Chris Lattner3d3067b2002-11-21 20:44:15 +0000504static void printMemReference(std::ostream &O, const MachineInstr *MI,
505 unsigned Op, const MRegisterInfo &RI) {
506 assert(isMem(MI, Op) && "Invalid memory reference!");
Chris Lattnerb7089442003-01-13 00:35:03 +0000507
508 if (MI->getOperand(Op).isFrameIndex()) {
509 O << "[frame slot #" << MI->getOperand(Op).getFrameIndex();
510 if (MI->getOperand(Op+3).getImmedValue())
511 O << " + " << MI->getOperand(Op+3).getImmedValue();
512 O << "]";
513 return;
514 } else if (MI->getOperand(Op).isConstantPoolIndex()) {
Brian Gaeke5e001572003-06-26 18:02:30 +0000515 O << "[.CPI" << fnIndex << "_"
516 << MI->getOperand(Op).getConstantPoolIndex();
Chris Lattnerb7089442003-01-13 00:35:03 +0000517 if (MI->getOperand(Op+3).getImmedValue())
518 O << " + " << MI->getOperand(Op+3).getImmedValue();
519 O << "]";
520 return;
521 }
522
Chris Lattner3d3067b2002-11-21 20:44:15 +0000523 const MachineOperand &BaseReg = MI->getOperand(Op);
Chris Lattner0285a332002-12-28 20:25:38 +0000524 int ScaleVal = MI->getOperand(Op+1).getImmedValue();
Chris Lattner3d3067b2002-11-21 20:44:15 +0000525 const MachineOperand &IndexReg = MI->getOperand(Op+2);
Chris Lattner0285a332002-12-28 20:25:38 +0000526 int DispVal = MI->getOperand(Op+3).getImmedValue();
Chris Lattner3d3067b2002-11-21 20:44:15 +0000527
528 O << "[";
529 bool NeedPlus = false;
530 if (BaseReg.getReg()) {
531 printOp(O, BaseReg, RI);
532 NeedPlus = true;
533 }
534
535 if (IndexReg.getReg()) {
536 if (NeedPlus) O << " + ";
Chris Lattner0285a332002-12-28 20:25:38 +0000537 if (ScaleVal != 1)
538 O << ScaleVal << "*";
Chris Lattner3d3067b2002-11-21 20:44:15 +0000539 printOp(O, IndexReg, RI);
540 NeedPlus = true;
541 }
542
Chris Lattner0285a332002-12-28 20:25:38 +0000543 if (DispVal) {
544 if (NeedPlus)
545 if (DispVal > 0)
546 O << " + ";
547 else {
548 O << " - ";
549 DispVal = -DispVal;
550 }
551 O << DispVal;
Chris Lattner3d3067b2002-11-21 20:44:15 +0000552 }
553 O << "]";
554}
555
Chris Lattnerdbb61c62002-11-17 22:53:13 +0000556// print - Print out an x86 instruction in intel syntax
Chris Lattner927dd092002-11-17 23:20:37 +0000557void X86InstrInfo::print(const MachineInstr *MI, std::ostream &O,
558 const TargetMachine &TM) const {
Chris Lattnerf9f60882002-11-18 06:56:51 +0000559 unsigned Opcode = MI->getOpcode();
Chris Lattner3501fea2003-01-14 22:00:31 +0000560 const TargetInstrDescriptor &Desc = get(Opcode);
Chris Lattnerf9f60882002-11-18 06:56:51 +0000561
Chris Lattnereca1f632002-12-25 05:09:01 +0000562 switch (Desc.TSFlags & X86II::FormMask) {
563 case X86II::Pseudo:
Brian Gaeke9e474c42003-06-19 19:32:32 +0000564 // Print pseudo-instructions as comments; either they should have been
565 // turned into real instructions by now, or they don't need to be
566 // seen by the assembler (e.g., IMPLICIT_USEs.)
567 O << "# ";
Chris Lattnereca1f632002-12-25 05:09:01 +0000568 if (Opcode == X86::PHI) {
569 printOp(O, MI->getOperand(0), RI);
570 O << " = phi ";
571 for (unsigned i = 1, e = MI->getNumOperands(); i != e; i+=2) {
572 if (i != 1) O << ", ";
573 O << "[";
574 printOp(O, MI->getOperand(i), RI);
575 O << ", ";
576 printOp(O, MI->getOperand(i+1), RI);
577 O << "]";
578 }
579 } else {
580 unsigned i = 0;
Vikram S. Adve49cab032003-05-27 00:03:17 +0000581 if (MI->getNumOperands() && (MI->getOperand(0).opIsDefOnly() ||
582 MI->getOperand(0).opIsDefAndUse())) {
Chris Lattnereca1f632002-12-25 05:09:01 +0000583 printOp(O, MI->getOperand(0), RI);
584 O << " = ";
585 ++i;
586 }
587 O << getName(MI->getOpcode());
588
589 for (unsigned e = MI->getNumOperands(); i != e; ++i) {
590 O << " ";
Vikram S. Adve49cab032003-05-27 00:03:17 +0000591 if (MI->getOperand(i).opIsDefOnly() ||
592 MI->getOperand(i).opIsDefAndUse()) O << "*";
Chris Lattnereca1f632002-12-25 05:09:01 +0000593 printOp(O, MI->getOperand(i), RI);
Vikram S. Adve49cab032003-05-27 00:03:17 +0000594 if (MI->getOperand(i).opIsDefOnly() ||
595 MI->getOperand(i).opIsDefAndUse()) O << "*";
Chris Lattnereca1f632002-12-25 05:09:01 +0000596 }
Chris Lattner3faae2d2002-12-13 09:59:26 +0000597 }
598 O << "\n";
599 return;
Chris Lattner3faae2d2002-12-13 09:59:26 +0000600
Chris Lattnerf9f60882002-11-18 06:56:51 +0000601 case X86II::RawFrm:
Chris Lattnerf8bafe82002-12-01 23:25:59 +0000602 // The accepted forms of Raw instructions are:
603 // 1. nop - No operand required
604 // 2. jmp foo - PC relative displacement operand
Chris Lattnerb7089442003-01-13 00:35:03 +0000605 // 3. call bar - GlobalAddress Operand or External Symbol Operand
Chris Lattnerf8bafe82002-12-01 23:25:59 +0000606 //
607 assert(MI->getNumOperands() == 0 ||
Chris Lattnerb7089442003-01-13 00:35:03 +0000608 (MI->getNumOperands() == 1 &&
609 (MI->getOperand(0).isPCRelativeDisp() ||
610 MI->getOperand(0).isGlobalAddress() ||
611 MI->getOperand(0).isExternalSymbol())) &&
Chris Lattnerf8bafe82002-12-01 23:25:59 +0000612 "Illegal raw instruction!");
Chris Lattnereca1f632002-12-25 05:09:01 +0000613 O << getName(MI->getOpcode()) << " ";
Chris Lattnerf9f60882002-11-18 06:56:51 +0000614
Chris Lattnerf8bafe82002-12-01 23:25:59 +0000615 if (MI->getNumOperands() == 1) {
Brian Gaeke01d79ff2003-06-25 18:01:07 +0000616 printOp(O, MI->getOperand(0), RI, true); // Don't print "OFFSET"...
Chris Lattnerf9f60882002-11-18 06:56:51 +0000617 }
618 O << "\n";
619 return;
620
Chris Lattner77875d82002-11-21 02:00:20 +0000621 case X86II::AddRegFrm: {
622 // There are currently two forms of acceptable AddRegFrm instructions.
623 // Either the instruction JUST takes a single register (like inc, dec, etc),
624 // or it takes a register and an immediate of the same size as the register
Chris Lattnerdbf30f72002-12-04 06:45:19 +0000625 // (move immediate f.e.). Note that this immediate value might be stored as
626 // an LLVM value, to represent, for example, loading the address of a global
Chris Lattnerfacc9fb2002-12-23 23:46:00 +0000627 // into a register. The initial register might be duplicated if this is a
628 // M_2_ADDR_REG instruction
Chris Lattner77875d82002-11-21 02:00:20 +0000629 //
Chris Lattnerd9096832002-12-15 08:01:39 +0000630 assert(MI->getOperand(0).isRegister() &&
Chris Lattner77875d82002-11-21 02:00:20 +0000631 (MI->getNumOperands() == 1 ||
Chris Lattnerdbf30f72002-12-04 06:45:19 +0000632 (MI->getNumOperands() == 2 &&
Chris Lattner6d669442002-12-04 17:28:40 +0000633 (MI->getOperand(1).getVRegValueOrNull() ||
Chris Lattnerfacc9fb2002-12-23 23:46:00 +0000634 MI->getOperand(1).isImmediate() ||
Chris Lattnerb7089442003-01-13 00:35:03 +0000635 MI->getOperand(1).isRegister() ||
636 MI->getOperand(1).isGlobalAddress() ||
637 MI->getOperand(1).isExternalSymbol()))) &&
Chris Lattner77875d82002-11-21 02:00:20 +0000638 "Illegal form for AddRegFrm instruction!");
Chris Lattnerf9f60882002-11-18 06:56:51 +0000639
Chris Lattner77875d82002-11-21 02:00:20 +0000640 unsigned Reg = MI->getOperand(0).getReg();
Chris Lattner77875d82002-11-21 02:00:20 +0000641
Chris Lattner77875d82002-11-21 02:00:20 +0000642 O << getName(MI->getOpCode()) << " ";
643 printOp(O, MI->getOperand(0), RI);
Chris Lattnerb7089442003-01-13 00:35:03 +0000644 if (MI->getNumOperands() == 2 &&
645 (!MI->getOperand(1).isRegister() ||
646 MI->getOperand(1).getVRegValueOrNull() ||
647 MI->getOperand(1).isGlobalAddress() ||
648 MI->getOperand(1).isExternalSymbol())) {
Chris Lattner77875d82002-11-21 02:00:20 +0000649 O << ", ";
Chris Lattner675dd2c2002-11-21 17:09:01 +0000650 printOp(O, MI->getOperand(1), RI);
Chris Lattner77875d82002-11-21 02:00:20 +0000651 }
652 O << "\n";
653 return;
654 }
Chris Lattner233ad712002-11-21 01:33:44 +0000655 case X86II::MRMDestReg: {
Chris Lattnerb7089442003-01-13 00:35:03 +0000656 // There are two acceptable forms of MRMDestReg instructions, those with 2,
657 // 3 and 4 operands:
658 //
659 // 2 Operands: this is for things like mov that do not read a second input
Chris Lattnerf9f60882002-11-18 06:56:51 +0000660 //
661 // 3 Operands: in this form, the first two registers (the destination, and
662 // the first operand) should be the same, post register allocation. The 3rd
663 // operand is an additional input. This should be for things like add
664 // instructions.
665 //
Chris Lattnerb7089442003-01-13 00:35:03 +0000666 // 4 Operands: This form is for instructions which are 3 operands forms, but
667 // have a constant argument as well.
Chris Lattnerf9f60882002-11-18 06:56:51 +0000668 //
Chris Lattnerb7089442003-01-13 00:35:03 +0000669 bool isTwoAddr = isTwoAddrInstr(Opcode);
Chris Lattnerd9096832002-12-15 08:01:39 +0000670 assert(MI->getOperand(0).isRegister() &&
Chris Lattnerb7089442003-01-13 00:35:03 +0000671 (MI->getNumOperands() == 2 ||
672 (isTwoAddr && MI->getOperand(1).isRegister() &&
673 MI->getOperand(0).getReg() == MI->getOperand(1).getReg() &&
674 (MI->getNumOperands() == 3 ||
675 (MI->getNumOperands() == 4 && MI->getOperand(3).isImmediate()))))
Misha Brukmane1f0d812002-11-20 18:56:41 +0000676 && "Bad format for MRMDestReg!");
Chris Lattnerf9f60882002-11-18 06:56:51 +0000677
Chris Lattnerf9f60882002-11-18 06:56:51 +0000678 O << getName(MI->getOpCode()) << " ";
679 printOp(O, MI->getOperand(0), RI);
680 O << ", ";
Chris Lattnerb7089442003-01-13 00:35:03 +0000681 printOp(O, MI->getOperand(1+isTwoAddr), RI);
682 if (MI->getNumOperands() == 4) {
683 O << ", ";
684 printOp(O, MI->getOperand(3), RI);
685 }
Chris Lattnerf9f60882002-11-18 06:56:51 +0000686 O << "\n";
687 return;
Chris Lattner233ad712002-11-21 01:33:44 +0000688 }
Chris Lattner18042332002-11-21 21:03:39 +0000689
690 case X86II::MRMDestMem: {
691 // These instructions are the same as MRMDestReg, but instead of having a
692 // register reference for the mod/rm field, it's a memory reference.
693 //
694 assert(isMem(MI, 0) && MI->getNumOperands() == 4+1 &&
Chris Lattnerd9096832002-12-15 08:01:39 +0000695 MI->getOperand(4).isRegister() && "Bad format for MRMDestMem!");
Chris Lattner18042332002-11-21 21:03:39 +0000696
Chris Lattnerb7089442003-01-13 00:35:03 +0000697 O << getName(MI->getOpCode()) << " " << sizePtr(Desc) << " ";
Chris Lattner18042332002-11-21 21:03:39 +0000698 printMemReference(O, MI, 0, RI);
699 O << ", ";
700 printOp(O, MI->getOperand(4), RI);
701 O << "\n";
702 return;
703 }
704
Chris Lattner233ad712002-11-21 01:33:44 +0000705 case X86II::MRMSrcReg: {
Chris Lattner644e1ab2002-11-21 00:30:01 +0000706 // There is a two forms that are acceptable for MRMSrcReg instructions,
707 // those with 3 and 2 operands:
708 //
709 // 3 Operands: in this form, the last register (the second input) is the
710 // ModR/M input. The first two operands should be the same, post register
711 // allocation. This is for things like: add r32, r/m32
712 //
713 // 2 Operands: this is for things like mov that do not read a second input
714 //
Chris Lattnerd9096832002-12-15 08:01:39 +0000715 assert(MI->getOperand(0).isRegister() &&
716 MI->getOperand(1).isRegister() &&
Chris Lattner644e1ab2002-11-21 00:30:01 +0000717 (MI->getNumOperands() == 2 ||
Chris Lattnerd9096832002-12-15 08:01:39 +0000718 (MI->getNumOperands() == 3 && MI->getOperand(2).isRegister()))
Chris Lattnerb7089442003-01-13 00:35:03 +0000719 && "Bad format for MRMSrcReg!");
Chris Lattner644e1ab2002-11-21 00:30:01 +0000720 if (MI->getNumOperands() == 3 &&
721 MI->getOperand(0).getReg() != MI->getOperand(1).getReg())
722 O << "**";
723
Chris Lattner644e1ab2002-11-21 00:30:01 +0000724 O << getName(MI->getOpCode()) << " ";
725 printOp(O, MI->getOperand(0), RI);
726 O << ", ";
727 printOp(O, MI->getOperand(MI->getNumOperands()-1), RI);
728 O << "\n";
729 return;
Chris Lattner233ad712002-11-21 01:33:44 +0000730 }
Chris Lattner675dd2c2002-11-21 17:09:01 +0000731
Chris Lattner3d3067b2002-11-21 20:44:15 +0000732 case X86II::MRMSrcMem: {
733 // These instructions are the same as MRMSrcReg, but instead of having a
734 // register reference for the mod/rm field, it's a memory reference.
Chris Lattner18042332002-11-21 21:03:39 +0000735 //
Chris Lattnerd9096832002-12-15 08:01:39 +0000736 assert(MI->getOperand(0).isRegister() &&
Chris Lattner3d3067b2002-11-21 20:44:15 +0000737 (MI->getNumOperands() == 1+4 && isMem(MI, 1)) ||
Chris Lattnerd9096832002-12-15 08:01:39 +0000738 (MI->getNumOperands() == 2+4 && MI->getOperand(1).isRegister() &&
Chris Lattner3d3067b2002-11-21 20:44:15 +0000739 isMem(MI, 2))
740 && "Bad format for MRMDestReg!");
741 if (MI->getNumOperands() == 2+4 &&
742 MI->getOperand(0).getReg() != MI->getOperand(1).getReg())
743 O << "**";
744
Chris Lattner3d3067b2002-11-21 20:44:15 +0000745 O << getName(MI->getOpCode()) << " ";
746 printOp(O, MI->getOperand(0), RI);
Chris Lattnerb7089442003-01-13 00:35:03 +0000747 O << ", " << sizePtr(Desc) << " ";
Chris Lattner3d3067b2002-11-21 20:44:15 +0000748 printMemReference(O, MI, MI->getNumOperands()-4, RI);
749 O << "\n";
750 return;
751 }
752
Chris Lattner675dd2c2002-11-21 17:09:01 +0000753 case X86II::MRMS0r: case X86II::MRMS1r:
754 case X86II::MRMS2r: case X86II::MRMS3r:
755 case X86II::MRMS4r: case X86II::MRMS5r:
756 case X86II::MRMS6r: case X86II::MRMS7r: {
Chris Lattner675dd2c2002-11-21 17:09:01 +0000757 // In this form, the following are valid formats:
758 // 1. sete r
Chris Lattner1d53ce42002-11-21 23:30:00 +0000759 // 2. cmp reg, immediate
Chris Lattner675dd2c2002-11-21 17:09:01 +0000760 // 2. shl rdest, rinput <implicit CL or 1>
761 // 3. sbb rdest, rinput, immediate [rdest = rinput]
762 //
763 assert(MI->getNumOperands() > 0 && MI->getNumOperands() < 4 &&
Chris Lattnerd9096832002-12-15 08:01:39 +0000764 MI->getOperand(0).isRegister() && "Bad MRMSxR format!");
Chris Lattner1d53ce42002-11-21 23:30:00 +0000765 assert((MI->getNumOperands() != 2 ||
Chris Lattnerd9096832002-12-15 08:01:39 +0000766 MI->getOperand(1).isRegister() || MI->getOperand(1).isImmediate())&&
Chris Lattner675dd2c2002-11-21 17:09:01 +0000767 "Bad MRMSxR format!");
Chris Lattner1d53ce42002-11-21 23:30:00 +0000768 assert((MI->getNumOperands() < 3 ||
Brian Gaeke01d79ff2003-06-25 18:01:07 +0000769 (MI->getOperand(1).isRegister() && MI->getOperand(2).isImmediate())) &&
Chris Lattner675dd2c2002-11-21 17:09:01 +0000770 "Bad MRMSxR format!");
771
Chris Lattnerd9096832002-12-15 08:01:39 +0000772 if (MI->getNumOperands() > 1 && MI->getOperand(1).isRegister() &&
Chris Lattner675dd2c2002-11-21 17:09:01 +0000773 MI->getOperand(0).getReg() != MI->getOperand(1).getReg())
774 O << "**";
775
Chris Lattner675dd2c2002-11-21 17:09:01 +0000776 O << getName(MI->getOpCode()) << " ";
777 printOp(O, MI->getOperand(0), RI);
Chris Lattnerd9096832002-12-15 08:01:39 +0000778 if (MI->getOperand(MI->getNumOperands()-1).isImmediate()) {
Chris Lattner675dd2c2002-11-21 17:09:01 +0000779 O << ", ";
Chris Lattner1d53ce42002-11-21 23:30:00 +0000780 printOp(O, MI->getOperand(MI->getNumOperands()-1), RI);
Chris Lattner675dd2c2002-11-21 17:09:01 +0000781 }
782 O << "\n";
783
784 return;
785 }
786
Chris Lattnerb7089442003-01-13 00:35:03 +0000787 case X86II::MRMS0m: case X86II::MRMS1m:
788 case X86II::MRMS2m: case X86II::MRMS3m:
789 case X86II::MRMS4m: case X86II::MRMS5m:
790 case X86II::MRMS6m: case X86II::MRMS7m: {
791 // In this form, the following are valid formats:
792 // 1. sete [m]
793 // 2. cmp [m], immediate
794 // 2. shl [m], rinput <implicit CL or 1>
795 // 3. sbb [m], immediate
796 //
797 assert(MI->getNumOperands() >= 4 && MI->getNumOperands() <= 5 &&
798 isMem(MI, 0) && "Bad MRMSxM format!");
799 assert((MI->getNumOperands() != 5 || MI->getOperand(4).isImmediate()) &&
800 "Bad MRMSxM format!");
801
802 O << getName(MI->getOpCode()) << " ";
803 O << sizePtr(Desc) << " ";
804 printMemReference(O, MI, 0, RI);
805 if (MI->getNumOperands() == 5) {
806 O << ", ";
807 printOp(O, MI->getOperand(4), RI);
808 }
809 O << "\n";
810 return;
811 }
812
Chris Lattnerf9f60882002-11-18 06:56:51 +0000813 default:
Chris Lattnerb7089442003-01-13 00:35:03 +0000814 O << "\tUNKNOWN FORM:\t\t-"; MI->print(O, TM); break;
Chris Lattnerf9f60882002-11-18 06:56:51 +0000815 }
Chris Lattner72614082002-10-25 22:55:53 +0000816}
Brian Gaeke9e474c42003-06-19 19:32:32 +0000817
818bool Printer::doInitialization(Module &M)
819{
820 // Tell gas we are outputting Intel syntax (not AT&T syntax) assembly,
821 // with no % decorations on register names.
822 O << "\t.intel_syntax noprefix\n";
Brian Gaekebc601fe2003-06-25 22:00:39 +0000823
Brian Gaeke5e001572003-06-26 18:02:30 +0000824 // Start function index at 0
825 fnIndex = 0;
826
Brian Gaekebc601fe2003-06-25 22:00:39 +0000827 // Ripped from CWriter:
828 // Calculate which global values have names that will collide when we throw
829 // away type information.
830 { // Scope to delete the FoundNames set when we are done with it...
831 std::set<std::string> FoundNames;
832 for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
833 if (I->hasName()) // If the global has a name...
834 if (FoundNames.count(I->getName())) // And the name is already used
835 MangledGlobals.insert(I); // Mangle the name
836 else
837 FoundNames.insert(I->getName()); // Otherwise, keep track of name
838
839 for (Module::giterator I = M.gbegin(), E = M.gend(); I != E; ++I)
840 if (I->hasName()) // If the global has a name...
841 if (FoundNames.count(I->getName())) // And the name is already used
842 MangledGlobals.insert(I); // Mangle the name
843 else
844 FoundNames.insert(I->getName()); // Otherwise, keep track of name
845 }
846
Brian Gaeke9e474c42003-06-19 19:32:32 +0000847 return false; // success
848}
849
850bool Printer::doFinalization(Module &M)
851{
Brian Gaeke01d79ff2003-06-25 18:01:07 +0000852 // Print out module-level global variables here.
853 for (Module::const_giterator I = M.gbegin(), E = M.gend(); I != E; ++I) {
Brian Gaekebc601fe2003-06-25 22:00:39 +0000854 std::string name(getValueName(I));
Brian Gaeke01d79ff2003-06-25 18:01:07 +0000855 if (I->hasInitializer()) {
856 Constant *C = I->getInitializer();
857 O << "\t.data\n";
Brian Gaekebc601fe2003-06-25 22:00:39 +0000858 O << "\t.globl " << name << "\n";
859 O << "\t.type " << name << ",@object\n";
860 O << "\t.size " << name << ","
Brian Gaeke01d79ff2003-06-25 18:01:07 +0000861 << (unsigned)TD->getTypeSize(I->getType()) << "\n";
862 O << "\t.align " << (unsigned)TD->getTypeAlignment(C->getType()) << "\n";
Brian Gaekebc601fe2003-06-25 22:00:39 +0000863 O << name << ":\t\t\t\t\t#" << *C << "\n";
Brian Gaeke01d79ff2003-06-25 18:01:07 +0000864 printConstantValueOnly (C);
865 } else {
Brian Gaekebc601fe2003-06-25 22:00:39 +0000866 O << "\t.globl " << name << "\n";
867 O << "\t.comm " << name << ", "
Brian Gaeke01d79ff2003-06-25 18:01:07 +0000868 << (unsigned)TD->getTypeSize(I->getType()) << ", "
869 << (unsigned)TD->getTypeAlignment(I->getType()) << "\n";
870 }
871 }
Brian Gaekebc601fe2003-06-25 22:00:39 +0000872 MangledGlobals.clear();
Brian Gaeke9e474c42003-06-19 19:32:32 +0000873 return false; // success
874}