1 //===-- EmitAssembly.cpp - Emit Sparc Specific .s File ---------------------==//
3 // This file implements all of the stuff neccesary to output a .s file from
4 // LLVM. The code in this file assumes that the specified module has already
5 // been compiled into the internal data structures of the Module.
7 // The entry point of this file is the UltraSparc::emitAssembly method.
9 //===----------------------------------------------------------------------===//
11 #include "SparcInternals.h"
12 #include "llvm/Analysis/SlotCalculator.h"
13 #include "llvm/CodeGen/MachineInstr.h"
14 #include "llvm/CodeGen/MachineCodeForMethod.h"
15 #include "llvm/GlobalVariable.h"
16 #include "llvm/ConstantVals.h"
17 #include "llvm/DerivedTypes.h"
18 #include "llvm/BasicBlock.h"
19 #include "llvm/Method.h"
20 #include "llvm/Module.h"
21 #include "Support/StringExtras.h"
22 #include "Support/HashExtras.h"
28 class SparcAsmPrinter {
29 typedef std::hash_map<const Value*, int> ValIdMap;
30 typedef ValIdMap:: iterator ValIdMapIterator;
31 typedef ValIdMap::const_iterator ValIdMapConstIterator;
34 SlotCalculator Table; // map anonymous values to unique integer IDs
35 ValIdMap valToIdMap; // used for values not handled by SlotCalculator
36 const UltraSparc &Target;
47 inline SparcAsmPrinter(std::ostream &o, const Module *M, const UltraSparc &t)
48 : toAsm(o), Table(SlotCalculator(M, true)), Target(t), CurSection(Unknown) {
51 void emitMethod(const Method *M);
52 void emitGlobalsAndConstants(const Module *M);
54 void emitBasicBlock(const BasicBlock *BB);
55 void emitMachineInst(const MachineInstr *MI);
57 void printGlobalVariable( const GlobalVariable* GV);
58 void printSingleConstant( const Constant* CV);
59 void printConstantValueOnly(const Constant* CV);
60 void printConstant( const Constant* CV, std::string valID = "");
62 unsigned int printOperands(const MachineInstr *MI, unsigned int opNum);
63 void printOneOperand(const MachineOperand &Op);
65 bool OpIsBranchTargetLabel(const MachineInstr *MI, unsigned int opNum);
66 bool OpIsMemoryAddressBase(const MachineInstr *MI, unsigned int opNum);
68 // enterSection - Use this method to enter a different section of the output
69 // executable. This is used to only output neccesary section transitions.
71 void enterSection(enum Sections S) {
72 if (S == CurSection) return; // Only switch section if neccesary
75 toAsm << "\n\t.section ";
78 default: assert(0 && "Bad section name!");
79 case Text: toAsm << "\".text\""; break;
80 case ReadOnlyData: toAsm << "\".rodata\",#alloc"; break;
81 case InitRWData: toAsm << "\".data\",#alloc,#write"; break;
82 case UninitRWData: toAsm << "\".bss\",#alloc,#write\nBbss.bss:"; break;
87 std::string getValidSymbolName(const string &S) {
90 // Symbol names in Sparc assembly language have these rules:
91 // (a) Must match { letter | _ | . | $ } { letter | _ | . | $ | digit }*
92 // (b) A name beginning in "." is treated as a local name.
93 // (c) Names beginning with "_" are reserved by ANSI C and shd not be used.
95 if (S[0] == '_' || isdigit(S[0]))
98 for (unsigned i = 0; i < S.size(); ++i)
101 if (C == '_' || C == '.' || C == '$' || isalpha(C) || isdigit(C))
106 Result += char('0' + ((unsigned char)C >> 4));
107 Result += char('0' + (C & 0xF));
113 // getID - Return a valid identifier for the specified value. Base it on
114 // the name of the identifier if possible, use a numbered value based on
115 // prefix otherwise. FPrefix is always prepended to the output identifier.
117 string getID(const Value *V, const char *Prefix, const char *FPrefix = 0) {
119 string FP(FPrefix ? FPrefix : ""); // "Forced prefix"
121 Result = FP + V->getName();
123 int valId = Table.getValSlot(V);
125 ValIdMapConstIterator I = valToIdMap.find(V);
126 valId = (I == valToIdMap.end())? (valToIdMap[V] = valToIdMap.size())
129 Result = FP + string(Prefix) + itostr(valId);
131 return getValidSymbolName(Result);
134 // getID Wrappers - Ensure consistent usage...
135 string getID(const Module *M) {
136 return getID(M, "LLVMModule_");
138 string getID(const Method *M) {
139 return getID(M, "LLVMMethod_");
141 string getID(const BasicBlock *BB) {
142 return getID(BB, "LL", (".L_"+getID(BB->getParent())+"_").c_str());
144 string getID(const GlobalVariable *GV) {
145 return getID(GV, "LLVMGlobal_", ".G_");
147 string getID(const Constant *CV) {
148 return getID(CV, "LLVMConst_", ".C_");
151 unsigned getOperandMask(unsigned Opcode) {
153 case SUBcc: return 1 << 3; // Remove CC argument
154 case BA: return 1 << 0; // Remove Arg #0, which is always null or xcc
155 default: return 0; // By default, don't hack operands...
161 // Can we treat the specified array as a string? Only if it is an array of
162 // ubytes or non-negative sbytes.
164 static bool isStringCompatible(ConstantArray *CPA) {
165 const Type *ETy = cast<ArrayType>(CPA->getType())->getElementType();
166 if (ETy == Type::UByteTy) return true;
167 if (ETy != Type::SByteTy) return false;
169 for (unsigned i = 0; i < CPA->getNumOperands(); ++i)
170 if (cast<ConstantSInt>(CPA->getOperand(i))->getValue() < 0)
176 // toOctal - Convert the low order bits of X into an octal letter
177 static inline char toOctal(int X) {
181 // getAsCString - Return the specified array as a C compatible string, only if
182 // the predicate isStringCompatible is true.
184 static string getAsCString(ConstantArray *CPA) {
185 if (isStringCompatible(CPA)) {
187 const Type *ETy = cast<ArrayType>(CPA->getType())->getElementType();
189 for (unsigned i = 0; i < CPA->getNumOperands(); ++i) {
190 unsigned char C = (ETy == Type::SByteTy) ?
191 (unsigned char)cast<ConstantSInt>(CPA->getOperand(i))->getValue() :
192 (unsigned char)cast<ConstantUInt>(CPA->getOperand(i))->getValue();
198 case '\a': Result += "\\a"; break;
199 case '\b': Result += "\\b"; break;
200 case '\f': Result += "\\f"; break;
201 case '\n': Result += "\\n"; break;
202 case '\r': Result += "\\r"; break;
203 case '\t': Result += "\\t"; break;
204 case '\v': Result += "\\v"; break;
207 Result += toOctal(C >> 6);
208 Result += toOctal(C >> 3);
209 Result += toOctal(C >> 0);
218 return CPA->getStrValue();
224 SparcAsmPrinter::OpIsBranchTargetLabel(const MachineInstr *MI,
225 unsigned int opNum) {
226 switch (MI->getOpCode()) {
228 case JMPLRET: return (opNum == 0);
229 default: return false;
235 SparcAsmPrinter::OpIsMemoryAddressBase(const MachineInstr *MI,
236 unsigned int opNum) {
237 if (Target.getInstrInfo().isLoad(MI->getOpCode()))
239 else if (Target.getInstrInfo().isStore(MI->getOpCode()))
246 #define PrintOp1PlusOp2(Op1, Op2) \
247 printOneOperand(Op1); \
249 printOneOperand(Op2);
252 SparcAsmPrinter::printOperands(const MachineInstr *MI,
255 const MachineOperand& Op = MI->getOperand(opNum);
257 if (OpIsBranchTargetLabel(MI, opNum))
259 PrintOp1PlusOp2(Op, MI->getOperand(opNum+1));
262 else if (OpIsMemoryAddressBase(MI, opNum))
265 PrintOp1PlusOp2(Op, MI->getOperand(opNum+1));
278 SparcAsmPrinter::printOneOperand(const MachineOperand &op)
280 switch (op.getOperandType())
282 case MachineOperand::MO_VirtualRegister:
283 case MachineOperand::MO_CCRegister:
284 case MachineOperand::MO_MachineRegister:
286 int RegNum = (int)op.getAllocatedRegNum();
288 // ****this code is temporary till NULL Values are fixed
289 if (RegNum == Target.getRegInfo().getInvalidRegNum()) {
290 toAsm << "<NULL VALUE>";
292 toAsm << "%" << Target.getRegInfo().getUnifiedRegName(RegNum);
297 case MachineOperand::MO_PCRelativeDisp:
299 const Value *Val = op.getVRegValue();
301 toAsm << "\t<*NULL Value*>";
302 else if (const BasicBlock *BB = dyn_cast<const BasicBlock>(Val))
304 else if (const Method *M = dyn_cast<const Method>(Val))
306 else if (const GlobalVariable *GV=dyn_cast<const GlobalVariable>(Val))
308 else if (const Constant *CV = dyn_cast<const Constant>(Val))
311 toAsm << "<unknown value=" << Val << ">";
315 case MachineOperand::MO_SignExtendedImmed:
316 case MachineOperand::MO_UnextendedImmed:
317 toAsm << (long)op.getImmedValue();
321 toAsm << op; // use dump field
328 SparcAsmPrinter::emitMachineInst(const MachineInstr *MI)
330 unsigned Opcode = MI->getOpCode();
332 if (TargetInstrDescriptors[Opcode].iclass & M_DUMMY_PHI_FLAG)
333 return; // IGNORE PHI NODES
335 toAsm << "\t" << TargetInstrDescriptors[Opcode].opCodeString << "\t";
337 unsigned Mask = getOperandMask(Opcode);
339 bool NeedComma = false;
341 for (unsigned OpNum = 0; OpNum < MI->getNumOperands(); OpNum += N)
342 if (! ((1 << OpNum) & Mask)) { // Ignore this operand?
343 if (NeedComma) toAsm << ", "; // Handle comma outputing
345 N = printOperands(MI, OpNum);
354 SparcAsmPrinter::emitBasicBlock(const BasicBlock *BB)
356 // Emit a label for the basic block
357 toAsm << getID(BB) << ":\n";
359 // Get the vector of machine instructions corresponding to this bb.
360 const MachineCodeForBasicBlock &MIs = BB->getMachineInstrVec();
361 MachineCodeForBasicBlock::const_iterator MII = MIs.begin(), MIE = MIs.end();
363 // Loop over all of the instructions in the basic block...
364 for (; MII != MIE; ++MII)
365 emitMachineInst(*MII);
366 toAsm << "\n"; // Seperate BB's with newlines
370 SparcAsmPrinter::emitMethod(const Method *M)
372 if (M->isExternal()) return;
374 // Make sure the slot table has information about this method...
375 Table.incorporateMethod(M);
377 string methName = getID(M);
378 toAsm << "!****** Outputing Method: " << methName << " ******\n";
380 toAsm << "\t.align\t4\n\t.global\t" << methName << "\n";
381 //toAsm << "\t.type\t" << methName << ",#function\n";
382 toAsm << "\t.type\t" << methName << ", 2\n";
383 toAsm << methName << ":\n";
385 // Output code for all of the basic blocks in the method...
386 for (Method::const_iterator I = M->begin(), E = M->end(); I != E; ++I)
389 // Output a .size directive so the debugger knows the extents of the function
390 toAsm << ".EndOf_" << methName << ":\n\t.size "
391 << methName << ", .EndOf_"
392 << methName << "-" << methName << "\n";
394 // Put some spaces between the methods
397 // Forget all about M.
402 ArrayTypeIsString(ArrayType* arrayType)
404 return (arrayType->getElementType() == Type::UByteTy ||
405 arrayType->getElementType() == Type::SByteTy);
409 TypeToDataDirective(const Type* type)
411 switch(type->getPrimitiveID())
413 case Type::BoolTyID: case Type::UByteTyID: case Type::SByteTyID:
415 case Type::UShortTyID: case Type::ShortTyID:
417 case Type::UIntTyID: case Type::IntTyID:
419 case Type::ULongTyID: case Type::LongTyID: case Type::PointerTyID:
421 case Type::FloatTyID:
423 case Type::DoubleTyID:
425 case Type::ArrayTyID:
426 if (ArrayTypeIsString((ArrayType*) type))
429 return "<InvaliDataTypeForPrinting>";
431 return "<InvaliDataTypeForPrinting>";
435 // Get the size of the constant for the given target.
436 // If this is an unsized array, return 0.
439 ConstantToSize(const Constant* CV, const TargetMachine& target)
441 if (ConstantArray* CPA = dyn_cast<ConstantArray>(CV))
443 ArrayType *aty = cast<ArrayType>(CPA->getType());
444 if (ArrayTypeIsString(aty))
445 return 1 + CPA->getNumOperands();
448 return target.findOptimalStorageSize(CV->getType());
453 // Align data larger than one L1 cache line on L1 cache line boundaries.
454 // Align all smaller data on the next higher 2^x boundary (4, 8, ...).
457 SizeToAlignment(unsigned int size, const TargetMachine& target)
459 unsigned short cacheLineSize = target.getCacheInfo().getCacheLineSize(1);
460 if (size > (unsigned) cacheLineSize / 2)
461 return cacheLineSize;
463 for (unsigned sz=1; /*no condition*/; sz *= 2)
468 // Get the size of the type and then use SizeToAlignment.
471 TypeToAlignment(const Type* type, const TargetMachine& target)
473 return SizeToAlignment(target.findOptimalStorageSize(type), target);
476 // Get the size of the constant and then use SizeToAlignment.
477 // Handles strings as a special case;
479 ConstantToAlignment(const Constant* CV, const TargetMachine& target)
481 if (ConstantArray* CPA = dyn_cast<ConstantArray>(CV))
482 if (ArrayTypeIsString(cast<ArrayType>(CPA->getType())))
483 return SizeToAlignment(1 + CPA->getNumOperands(), target);
485 return TypeToAlignment(CV->getType(), target);
489 // Print a single constant value.
491 SparcAsmPrinter::printSingleConstant(const Constant* CV)
493 assert(CV->getType() != Type::VoidTy &&
494 CV->getType() != Type::TypeTy &&
495 CV->getType() != Type::LabelTy &&
496 "Unexpected type for Constant");
498 assert((! isa<ConstantArray>( CV) && ! isa<ConstantStruct>(CV))
499 && "Collective types should be handled outside this function");
502 << TypeToDataDirective(CV->getType()) << "\t";
504 if (CV->getType()->isPrimitiveType())
506 if (CV->getType() == Type::FloatTy || CV->getType() == Type::DoubleTy)
507 toAsm << "0r"; // FP constants must have this prefix
508 toAsm << CV->getStrValue() << "\n";
510 else if (ConstantPointer* CPP = dyn_cast<ConstantPointer>(CV))
512 assert(CPP->isNullValue() &&
513 "Cannot yet print non-null pointer constants to assembly");
516 else if (isa<ConstantPointerRef>(CV))
518 assert(0 && "Cannot yet initialize pointer refs in assembly");
522 assert(0 && "Unknown elementary type for constant");
526 // Print a constant value or values (it may be an aggregate).
527 // Uses printSingleConstant() to print each individual value.
529 SparcAsmPrinter::printConstantValueOnly(const Constant* CV)
531 ConstantArray *CPA = dyn_cast<ConstantArray>(CV);
533 if (CPA && isStringCompatible(CPA))
534 { // print the string alone and return
535 toAsm << "\t" << ".ascii" << "\t" << getAsCString(CPA) << "\n";
538 { // Not a string. Print the values in successive locations
539 const std::vector<Use> &constValues = CPA->getValues();
540 for (unsigned i=1; i < constValues.size(); i++)
541 this->printConstantValueOnly(cast<Constant>(constValues[i].get()));
543 else if (ConstantStruct *CPS = dyn_cast<ConstantStruct>(CV))
544 { // Print the fields in successive locations
545 const std::vector<Use>& constValues = CPS->getValues();
546 for (unsigned i=1; i < constValues.size(); i++)
547 this->printConstantValueOnly(cast<Constant>(constValues[i].get()));
550 this->printSingleConstant(CV);
553 // Print a constant (which may be an aggregate) prefixed by all the
554 // appropriate directives. Uses printConstantValueOnly() to print the
557 SparcAsmPrinter::printConstant(const Constant* CV, string valID)
559 if (valID.length() == 0)
562 toAsm << "\t.align\t" << ConstantToAlignment(CV, Target)
565 // Print .size and .type only if it is not a string.
566 ConstantArray *CPA = dyn_cast<ConstantArray>(CV);
567 if (CPA && isStringCompatible(CPA))
568 { // print it as a string and return
569 toAsm << valID << ":\n";
570 toAsm << "\t" << ".ascii" << "\t" << getAsCString(CPA) << "\n";
574 toAsm << "\t.type" << "\t" << valID << ",#object\n";
576 unsigned int constSize = ConstantToSize(CV, Target);
578 toAsm << "\t.size" << "\t" << valID << ","
579 << constSize << "\n";
581 toAsm << valID << ":\n";
583 this->printConstantValueOnly(CV);
588 SparcAsmPrinter::printGlobalVariable(const GlobalVariable* GV)
590 toAsm << "\t.global\t" << getID(GV) << "\n";
592 if (GV->hasInitializer())
593 printConstant(GV->getInitializer(), getID(GV));
595 toAsm << "\t.align\t"
596 << TypeToAlignment(GV->getType()->getElementType(), Target) << "\n";
597 toAsm << "\t.type\t" << getID(GV) << ",#object\n";
598 toAsm << "\t.reserve\t" << getID(GV) << ","
599 << Target.findOptimalStorageSize(GV->getType()->getElementType())
606 FoldConstants(const Module *M,
607 std::hash_set<const Constant*>& moduleConstants)
609 for (Module::const_iterator I = M->begin(), E = M->end(); I != E; ++I)
610 if (! (*I)->isExternal())
612 const std::hash_set<const Constant*>& pool =
613 MachineCodeForMethod::get(*I).getConstantPoolValues();
614 moduleConstants.insert(pool.begin(), pool.end());
620 SparcAsmPrinter::emitGlobalsAndConstants(const Module *M)
622 // First, get the constants there were marked by the code generator for
623 // inclusion in the assembly code data area and fold them all into a
624 // single constant pool since there may be lots of duplicates. Also,
625 // lets force these constants into the slot table so that we can get
626 // unique names for unnamed constants also.
628 std::hash_set<const Constant*> moduleConstants;
629 FoldConstants(M, moduleConstants);
631 // Now, emit the three data sections separately; the cost of I/O should
632 // make up for the cost of extra passes over the globals list!
634 // Read-only data section (implies initialized)
635 for (Module::const_giterator GI=M->gbegin(), GE=M->gend(); GI != GE; ++GI)
637 const GlobalVariable* GV = *GI;
638 if (GV->hasInitializer() && GV->isConstant())
640 if (GI == M->gbegin())
641 enterSection(ReadOnlyData);
642 printGlobalVariable(GV);
646 for (std::hash_set<const Constant*>::const_iterator
647 I = moduleConstants.begin(),
648 E = moduleConstants.end(); I != E; ++I)
651 // Initialized read-write data section
652 for (Module::const_giterator GI=M->gbegin(), GE=M->gend(); GI != GE; ++GI)
654 const GlobalVariable* GV = *GI;
655 if (GV->hasInitializer() && ! GV->isConstant())
657 if (GI == M->gbegin())
658 enterSection(InitRWData);
659 printGlobalVariable(GV);
663 // Uninitialized read-write data section
664 for (Module::const_giterator GI=M->gbegin(), GE=M->gend(); GI != GE; ++GI)
666 const GlobalVariable* GV = *GI;
667 if (! GV->hasInitializer())
669 if (GI == M->gbegin())
670 enterSection(UninitRWData);
671 printGlobalVariable(GV);
678 } // End anonymous namespace
682 // emitAssembly - Output assembly language code (a .s file) for global
683 // components of the specified module. This assumes that methods have been
684 // previously output.
687 UltraSparc::emitAssembly(const Method *M, std::ostream &OutStr) const
689 SparcAsmPrinter Print(OutStr, M->getParent(), *this);
694 // emitAssembly - Output assembly language code (a .s file) for the specified
695 // method. The specified method must have been compiled before this may be
699 UltraSparc::emitAssembly(const Module *M, std::ostream &OutStr) const
701 SparcAsmPrinter Print(OutStr, M, *this);
702 Print.emitGlobalsAndConstants(M);