opnsense-src/contrib/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp

224 lines
7.2 KiB
C++
Raw Normal View History

2009-10-14 13:57:32 -04:00
//===-- SystemZAsmPrinter.cpp - SystemZ LLVM assembly writer ---------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains a printer that converts from our internal representation
// of machine-dependent LLVM code to the SystemZ assembly language.
//
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "asm-printer"
#include "SystemZ.h"
#include "SystemZInstrInfo.h"
#include "SystemZTargetMachine.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Module.h"
#include "llvm/Assembly/Writer.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCSymbol.h"
2010-03-16 12:51:38 -04:00
#include "llvm/Target/Mangler.h"
2009-10-14 13:57:32 -04:00
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetRegistry.h"
2010-04-06 11:52:58 -04:00
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/raw_ostream.h"
2009-10-14 13:57:32 -04:00
using namespace llvm;
namespace {
2009-11-04 09:58:56 -05:00
class SystemZAsmPrinter : public AsmPrinter {
2009-10-14 13:57:32 -04:00
public:
2010-04-06 11:52:58 -04:00
SystemZAsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
: AsmPrinter(TM, Streamer) {}
2009-10-14 13:57:32 -04:00
virtual const char *getPassName() const {
return "SystemZ Assembly Printer";
}
2010-04-06 11:52:58 -04:00
void printOperand(const MachineInstr *MI, int OpNum, raw_ostream &O,
2009-10-14 13:57:32 -04:00
const char* Modifier = 0);
2010-04-06 11:52:58 -04:00
void printPCRelImmOperand(const MachineInstr *MI, int OpNum, raw_ostream &O);
void printRIAddrOperand(const MachineInstr *MI, int OpNum, raw_ostream &O,
2009-10-14 13:57:32 -04:00
const char* Modifier = 0);
2010-04-06 11:52:58 -04:00
void printRRIAddrOperand(const MachineInstr *MI, int OpNum, raw_ostream &O,
2009-10-14 13:57:32 -04:00
const char* Modifier = 0);
2010-04-06 11:52:58 -04:00
void printS16ImmOperand(const MachineInstr *MI, int OpNum, raw_ostream &O) {
2009-10-14 13:57:32 -04:00
O << (int16_t)MI->getOperand(OpNum).getImm();
}
void printU16ImmOperand(const MachineInstr *MI, int OpNum, raw_ostream &O) {
O << (uint16_t)MI->getOperand(OpNum).getImm();
}
2010-04-06 11:52:58 -04:00
void printS32ImmOperand(const MachineInstr *MI, int OpNum, raw_ostream &O) {
2009-10-14 13:57:32 -04:00
O << (int32_t)MI->getOperand(OpNum).getImm();
}
void printU32ImmOperand(const MachineInstr *MI, int OpNum, raw_ostream &O) {
O << (uint32_t)MI->getOperand(OpNum).getImm();
}
2009-10-14 13:57:32 -04:00
2010-04-06 11:52:58 -04:00
void printInstruction(const MachineInstr *MI, raw_ostream &O);
2009-10-14 13:57:32 -04:00
static const char *getRegisterName(unsigned RegNo);
2010-02-16 04:30:23 -05:00
void EmitInstruction(const MachineInstr *MI);
2009-10-14 13:57:32 -04:00
};
} // end of anonymous namespace
#include "SystemZGenAsmWriter.inc"
2010-02-16 04:30:23 -05:00
void SystemZAsmPrinter::EmitInstruction(const MachineInstr *MI) {
2010-04-06 11:52:58 -04:00
SmallString<128> Str;
raw_svector_ostream OS(Str);
printInstruction(MI, OS);
OutStreamer.EmitRawText(OS.str());
2009-10-14 13:57:32 -04:00
}
2010-04-06 11:52:58 -04:00
void SystemZAsmPrinter::printPCRelImmOperand(const MachineInstr *MI, int OpNum,
raw_ostream &O) {
2009-10-14 13:57:32 -04:00
const MachineOperand &MO = MI->getOperand(OpNum);
switch (MO.getType()) {
case MachineOperand::MO_Immediate:
O << MO.getImm();
return;
case MachineOperand::MO_MachineBasicBlock:
2010-03-16 12:51:38 -04:00
O << *MO.getMBB()->getSymbol();
2009-10-14 13:57:32 -04:00
return;
case MachineOperand::MO_GlobalAddress: {
const GlobalValue *GV = MO.getGlobal();
2010-03-16 12:51:38 -04:00
O << *Mang->getSymbol(GV);
2009-10-14 13:57:32 -04:00
// Assemble calls via PLT for externally visible symbols if PIC.
if (TM.getRelocationModel() == Reloc::PIC_ &&
!GV->hasHiddenVisibility() && !GV->hasProtectedVisibility() &&
!GV->hasLocalLinkage())
O << "@PLT";
2010-04-06 11:52:58 -04:00
printOffset(MO.getOffset(), O);
2009-10-14 13:57:32 -04:00
return;
}
case MachineOperand::MO_ExternalSymbol: {
std::string Name(MAI->getGlobalPrefix());
Name += MO.getSymbolName();
O << Name;
if (TM.getRelocationModel() == Reloc::PIC_)
O << "@PLT";
return;
}
default:
assert(0 && "Not implemented yet!");
}
}
void SystemZAsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
2010-04-06 11:52:58 -04:00
raw_ostream &O, const char *Modifier) {
2009-10-14 13:57:32 -04:00
const MachineOperand &MO = MI->getOperand(OpNum);
switch (MO.getType()) {
case MachineOperand::MO_Register: {
assert (TargetRegisterInfo::isPhysicalRegister(MO.getReg()) &&
"Virtual registers should be already mapped!");
unsigned Reg = MO.getReg();
if (Modifier && strncmp(Modifier, "subreg", 6) == 0) {
if (strncmp(Modifier + 7, "even", 4) == 0)
2010-07-13 13:19:57 -04:00
Reg = TM.getRegisterInfo()->getSubReg(Reg, SystemZ::subreg_32bit);
2009-10-14 13:57:32 -04:00
else if (strncmp(Modifier + 7, "odd", 3) == 0)
2010-05-27 11:15:58 -04:00
Reg = TM.getRegisterInfo()->getSubReg(Reg, SystemZ::subreg_odd32);
2009-10-14 13:57:32 -04:00
else
assert(0 && "Invalid subreg modifier");
}
O << '%' << getRegisterName(Reg);
return;
}
case MachineOperand::MO_Immediate:
O << MO.getImm();
return;
case MachineOperand::MO_MachineBasicBlock:
2010-03-16 12:51:38 -04:00
O << *MO.getMBB()->getSymbol();
2009-10-14 13:57:32 -04:00
return;
case MachineOperand::MO_JumpTableIndex:
O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() << '_'
<< MO.getIndex();
return;
case MachineOperand::MO_ConstantPoolIndex:
O << MAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << '_'
<< MO.getIndex();
2010-04-06 11:52:58 -04:00
printOffset(MO.getOffset(), O);
2009-10-14 13:57:32 -04:00
break;
2010-01-23 06:09:33 -05:00
case MachineOperand::MO_GlobalAddress:
2010-03-16 12:51:38 -04:00
O << *Mang->getSymbol(MO.getGlobal());
2009-10-14 13:57:32 -04:00
break;
case MachineOperand::MO_ExternalSymbol: {
2010-01-23 06:09:33 -05:00
O << *GetExternalSymbolSymbol(MO.getSymbolName());
2009-10-14 13:57:32 -04:00
break;
}
default:
assert(0 && "Not implemented yet!");
}
switch (MO.getTargetFlags()) {
2010-04-06 11:52:58 -04:00
default: assert(0 && "Unknown target flag on GV operand");
2009-10-14 13:57:32 -04:00
case SystemZII::MO_NO_FLAG:
break;
case SystemZII::MO_GOTENT: O << "@GOTENT"; break;
case SystemZII::MO_PLT: O << "@PLT"; break;
}
2010-04-06 11:52:58 -04:00
printOffset(MO.getOffset(), O);
2009-10-14 13:57:32 -04:00
}
void SystemZAsmPrinter::printRIAddrOperand(const MachineInstr *MI, int OpNum,
2010-04-06 11:52:58 -04:00
raw_ostream &O,
const char *Modifier) {
2009-10-14 13:57:32 -04:00
const MachineOperand &Base = MI->getOperand(OpNum);
// Print displacement operand.
2010-04-06 11:52:58 -04:00
printOperand(MI, OpNum+1, O);
2009-10-14 13:57:32 -04:00
// Print base operand (if any)
if (Base.getReg()) {
O << '(';
2010-04-06 11:52:58 -04:00
printOperand(MI, OpNum, O);
2009-10-14 13:57:32 -04:00
O << ')';
}
}
void SystemZAsmPrinter::printRRIAddrOperand(const MachineInstr *MI, int OpNum,
2010-04-06 11:52:58 -04:00
raw_ostream &O,
const char *Modifier) {
2009-10-14 13:57:32 -04:00
const MachineOperand &Base = MI->getOperand(OpNum);
const MachineOperand &Index = MI->getOperand(OpNum+2);
// Print displacement operand.
2010-04-06 11:52:58 -04:00
printOperand(MI, OpNum+1, O);
2009-10-14 13:57:32 -04:00
// Print base operand (if any)
if (Base.getReg()) {
O << '(';
2010-04-06 11:52:58 -04:00
printOperand(MI, OpNum, O);
2009-10-14 13:57:32 -04:00
if (Index.getReg()) {
O << ',';
2010-04-06 11:52:58 -04:00
printOperand(MI, OpNum+2, O);
2009-10-14 13:57:32 -04:00
}
O << ')';
} else
assert(!Index.getReg() && "Should allocate base register first!");
}
// Force static initialization.
extern "C" void LLVMInitializeSystemZAsmPrinter() {
RegisterAsmPrinter<SystemZAsmPrinter> X(TheSystemZTarget);
}