//
// The LLVM Compiler Infrastructure
//
-// This file was developed by Bruno Cardoso Lopes and is distributed under the
-// University of Illinois Open Source License. See LICENSE.TXT for details.
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
#include "llvm/Target/TargetAsmInfo.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetMachine.h"
+#include "llvm/Target/TargetOptions.h"
#include "llvm/Support/Mangler.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/SetVector.h"
//
// Consider the following function prologue:
//
-// .frame $fp,48,$ra
-// .mask 0xc0000000,-8
-// addiu $sp, $sp, -48
-// sw $ra, 40($sp)
-// sw $fp, 36($sp)
+// .frame $fp,48,$ra
+// .mask 0xc0000000,-8
+// addiu $sp, $sp, -48
+// sw $ra, 40($sp)
+// sw $fp, 36($sp)
//
// With a 0xc0000000 mask, the assembler knows the register 31 (RA) and
// 30 (FP) are saved at prologue. As the save order on prologue is from
void MipsAsmPrinter::
emitFrameDirective(MachineFunction &MF)
{
- const MRegisterInfo &RI = *TM.getRegisterInfo();
+ const TargetRegisterInfo &RI = *TM.getRegisterInfo();
unsigned stackReg = RI.getFrameRegister(MF);
unsigned returnReg = RI.getRARegister();
unsigned stackSize = MF.getFrameInfo()->getStackSize();
- O << "\t.frame\t" << "$" << LowercaseString(RI.get(stackReg).Name)
+ O << "\t.frame\t" << "$" << LowercaseString(RI.get(stackReg).AsmName)
<< "," << stackSize << ","
- << "$" << LowercaseString(RI.get(returnReg).Name)
+ << "$" << LowercaseString(RI.get(returnReg).AsmName)
<< "\n";
}
unsigned int MipsAsmPrinter::
getSavedRegsBitmask(bool isFloat, MachineFunction &MF)
{
- const MRegisterInfo &RI = *TM.getRegisterInfo();
+ const TargetRegisterInfo &RI = *TM.getRegisterInfo();
// Float Point Registers, TODO
if (isFloat)
const Function *F = MF.getFunction();
SwitchToTextSection(getSectionForFunction(*F).c_str(), F);
- // On Mips GAS, if .align #n is present, #n means the number of bits
- // to be cleared. So, if we want 4 byte alignment, we must have .align 2
- EmitAlignment(1, F);
+ // 2 bits aligned
+ EmitAlignment(2, F);
O << "\t.globl\t" << CurrentFnName << "\n";
O << "\t.ent\t" << CurrentFnName << "\n";
// Print out constants referenced by the function
EmitConstantPool(MF.getConstantPool());
+ // Print out jump tables referenced by the function
+ EmitJumpTableInfo(MF.getJumpTableInfo(), MF);
+
O << "\n\n";
// What's my mangled name?
// Print a label for the basic block.
if (I != MF.begin()) {
- printBasicBlockLabel(I, true);
+ printBasicBlockLabel(I, true, true);
O << '\n';
}
for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
II != E; ++II) {
// Print the assembly for the instruction.
- O << "\t";
printInstruction(II);
++EmittedInsts;
}
printOperand(const MachineInstr *MI, int opNum)
{
const MachineOperand &MO = MI->getOperand(opNum);
- const MRegisterInfo &RI = *TM.getRegisterInfo();
+ const TargetRegisterInfo &RI = *TM.getRegisterInfo();
bool closeP = false;
bool isPIC = (TM.getRelocationModel() == Reloc::PIC_);
bool isCodeLarge = (TM.getCodeModel() == CodeModel::Large);
switch (MO.getType())
{
case MachineOperand::MO_Register:
- if (MRegisterInfo::isPhysicalRegister(MO.getReg()))
- O << "$" << LowercaseString (RI.get(MO.getReg()).Name);
+ if (TargetRegisterInfo::isPhysicalRegister(MO.getReg()))
+ O << "$" << LowercaseString (RI.get(MO.getReg()).AsmName);
else
O << "$" << MO.getReg();
break;
case MachineOperand::MO_Immediate:
if ((MI->getOpcode() == Mips::SLTiu) || (MI->getOpcode() == Mips::ORi) ||
(MI->getOpcode() == Mips::LUi) || (MI->getOpcode() == Mips::ANDi))
- O << (unsigned short int)MO.getImmedValue();
+ O << (unsigned short int)MO.getImm();
else
- O << (short int)MO.getImmedValue();
+ O << (short int)MO.getImm();
break;
case MachineOperand::MO_MachineBasicBlock:
- printBasicBlockLabel(MO.getMachineBasicBlock());
+ printBasicBlockLabel(MO.getMBB());
return;
case MachineOperand::MO_GlobalAddress:
O << MO.getSymbolName();
break;
+ case MachineOperand::MO_JumpTableIndex:
+ O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
+ << '_' << MO.getIndex();
+ break;
+
// FIXME: Verify correct
case MachineOperand::MO_ConstantPoolIndex:
O << TAI->getPrivateGlobalPrefix() << "CPI"
- << getFunctionNumber() << "_" << MO.getConstantPoolIndex();
+ << getFunctionNumber() << "_" << MO.getIndex();
break;
default:
std::string name = Mang->getValueName(I);
Constant *C = I->getInitializer();
unsigned Size = TD->getABITypeSize(C->getType());
- unsigned Align = TD->getPrefTypeAlignment(C->getType());
+ unsigned Align = TD->getPreferredAlignmentLog(I);
+ // Is this correct ?
if (C->isNullValue() && (I->hasLinkOnceLinkage() ||
- I->hasInternalLinkage() || I->hasWeakLinkage()
- /* FIXME: Verify correct */)) {
-
- SwitchToDataSection(".data", I);
- if (I->hasInternalLinkage())
- O << "\t.local " << name << "\n";
-
- O << "\t.comm " << name << ","
- << TD->getABITypeSize(C->getType())
- << "," << Align << "\n";
+ I->hasInternalLinkage() || I->hasWeakLinkage()))
+ {
+ if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it.
+
+ if (!NoZerosInBSS && TAI->getBSSSection())
+ SwitchToDataSection(TAI->getBSSSection(), I);
+ else
+ SwitchToDataSection(TAI->getDataSection(), I);
+
+ if (I->hasInternalLinkage()) {
+ if (TAI->getLCOMMDirective())
+ O << TAI->getLCOMMDirective() << name << "," << Size;
+ else
+ O << "\t.local\t" << name << "\n";
+ } else {
+ O << TAI->getCOMMDirective() << name << "," << Size;
+ // The .comm alignment in bytes.
+ if (TAI->getCOMMDirectiveTakesAlignment())
+ O << "," << (1 << Align);
+ }
} else {
// something. For now, just emit them as external.
case GlobalValue::ExternalLinkage:
// If external or appending, declare as a global symbol
- O << "\t.globl " << name << "\n";
+ O << TAI->getGlobalDirective() << name << "\n";
+ // Fall Through
case GlobalValue::InternalLinkage:
- if (C->isNullValue())
- SwitchToDataSection(".bss", I);
- else
- SwitchToDataSection(".data", I);
+ // FIXME: special handling for ".ctors" & ".dtors" sections
+ if (I->hasSection() && (I->getSection() == ".ctors" ||
+ I->getSection() == ".dtors")) {
+ std::string SectionName = ".section " + I->getSection();
+ SectionName += ",\"aw\",%progbits";
+ SwitchToDataSection(SectionName.c_str());
+ } else {
+ if (C->isNullValue() && !NoZerosInBSS && TAI->getBSSSection())
+ SwitchToDataSection(TAI->getBSSSection(), I);
+ else if (!I->isConstant())
+ SwitchToDataSection(TAI->getDataSection(), I);
+ else {
+ // Read-only data.
+ if (TAI->getReadOnlySection())
+ SwitchToDataSection(TAI->getReadOnlySection(), I);
+ else
+ SwitchToDataSection(TAI->getDataSection(), I);
+ }
+ }
break;
case GlobalValue::GhostLinkage:
- cerr << "Should not have any"
- << "unmaterialized functions!\n";
+ cerr << "Should not have any unmaterialized functions!\n";
abort();
case GlobalValue::DLLImportLinkage:
- cerr << "DLLImport linkage is"
- << "not supported by this target!\n";
+ cerr << "DLLImport linkage is not supported by this target!\n";
abort();
case GlobalValue::DLLExportLinkage:
- cerr << "DLLExport linkage is"
- << "not supported by this target!\n";
+ cerr << "DLLExport linkage is not supported by this target!\n";
abort();
default:
assert(0 && "Unknown linkage type!");