}
void X86ATTAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
- const char *Modifier, bool NotRIPRel) {
+ const char *Modifier) {
const MachineOperand &MO = MI->getOperand(OpNo);
switch (MO.getType()) {
case MachineOperand::MO_Register: {
O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() << '_'
<< MO.getIndex();
- if (TM.getRelocationModel() == Reloc::PIC_) {
- if (Subtarget->isPICStyleStub()) {
- O << '-';
- PrintPICBaseSymbol();
- } else if (Subtarget->isPICStyleGOT()) {
- O << "@GOTOFF";
+ switch (MO.getTargetFlags()) {
+ default:
+ assert(0 && "Unknown target flag on jump table operand");
+ case X86II::MO_NO_FLAG:
+ // FIXME: REMOVE EVENTUALLY.
+ if (TM.getRelocationModel() == Reloc::PIC_) {
+ assert(!Subtarget->isPICStyleStub() &&
+ !Subtarget->isPICStyleGOT() &&
+ "Should have operand flag!");
}
+
+ break;
+ case X86II::MO_PIC_BASE_OFFSET:
+ O << '-';
+ PrintPICBaseSymbol();
+ break;
+ case X86II::MO_GOTOFF:
+ O << "@GOTOFF";
+ break;
}
- if (isMemOp && Subtarget->isPICStyleRIPRel() && !NotRIPRel)
- O << "(%rip)";
return;
}
case MachineOperand::MO_ConstantPoolIndex: {
O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << '_'
<< MO.getIndex();
- if (TM.getRelocationModel() == Reloc::PIC_) {
- if (Subtarget->isPICStyleStub()) {
- O << '-';
- PrintPICBaseSymbol();
- } else if (Subtarget->isPICStyleGOT())
- O << "@GOTOFF";
- }
-
printOffset(MO.getOffset());
- if (isMemOp && Subtarget->isPICStyleRIPRel() && !NotRIPRel)
- O << "(%rip)";
+ switch (MO.getTargetFlags()) {
+ default:
+ assert(0 && "Unknown target flag on constant pool operand");
+ case X86II::MO_NO_FLAG:
+ // FIXME: REMOVE EVENTUALLY.
+ if (TM.getRelocationModel() == Reloc::PIC_) {
+ assert(!Subtarget->isPICStyleStub() &&
+ !Subtarget->isPICStyleGOT() &&
+ "Should have operand flag!");
+ }
+
+ break;
+ case X86II::MO_PIC_BASE_OFFSET:
+ O << '-';
+ PrintPICBaseSymbol();
+ break;
+ case X86II::MO_GOTOFF:
+ O << "@GOTOFF";
+ break;
+ }
+
return;
}
case MachineOperand::MO_GlobalAddress: {
if (needCloseParen)
O << ')';
- bool isRIPRelative = false;
+ switch (MO.getTargetFlags()) {
+ default:
+ assert(0 && "Unknown target flag on GV operand");
+ case X86II::MO_NO_FLAG:
+ // FIXME: RIP THIS CHECKING CODE OUT EVENTUALLY.
+ if (isThreadLocal)
+ assert(0 && "Not lowered right");
+ break;
+ case X86II::MO_TLSGD:
+ O << "@TLSGD";
+ break;
+ case X86II::MO_GOTTPOFF:
+ O << "@GOTTPOFF";
+ break;
+ case X86II::MO_INDNTPOFF:
+ O << "@INDNTPOFF";
+ break;
+ case X86II::MO_TPOFF:
+ O << "@TPOFF";
+ break;
+ case X86II::MO_NTPOFF:
+ O << "@NTPOFF";
+ break;
+ case X86II::MO_GOTPCREL:
+ O << "@GOTPCREL";
+ break;
+ }
+
if (isThreadLocal) {
- TLSModel::Model model = getTLSModel(GVar, TM.getRelocationModel());
- switch (model) {
- case TLSModel::GeneralDynamic:
- O << "@TLSGD";
- break;
- case TLSModel::LocalDynamic:
- // O << "@TLSLD"; // local dynamic not implemented
- O << "@TLSGD";
- break;
- case TLSModel::InitialExec:
- if (Subtarget->is64Bit()) {
- assert (!NotRIPRel);
- O << "@GOTTPOFF";
- isRIPRelative = true;
- } else {
- O << "@INDNTPOFF";
- }
- break;
- case TLSModel::LocalExec:
- if (Subtarget->is64Bit())
- O << "@TPOFF";
- else
- O << "@NTPOFF";
- break;
- default:
- assert (0 && "Unknown TLS model");
- }
+ // DEAD
} else if (isMemOp) {
if (shouldPrintGOT(TM, Subtarget)) {
if (Subtarget->GVRequiresExtraLoad(GV, TM, false))
O << "@GOT";
else
O << "@GOTOFF";
- } else if (Subtarget->isPICStyleRIPRel() &&
- !NotRIPRel) {
+ } else if (Subtarget->isPICStyleRIPRel()) {
if (TM.getRelocationModel() != Reloc::Static) {
if (Subtarget->GVRequiresExtraLoad(GV, TM, false))
O << "@GOTPCREL";
}
-
- isRIPRelative = true;
}
}
- // Use rip when possible to reduce code size, except when
- // index or base register are also part of the address. e.g.
- // foo(%rip)(%rcx,%rax,4) is not legal.
- if (isRIPRelative)
- O << "(%rip)";
-
return;
}
case MachineOperand::MO_ExternalSymbol: {
- bool isMemOp = Modifier && !strcmp(Modifier, "mem");
- bool needCloseParen = false;
- std::string Name(TAI->getGlobalPrefix());
- Name += MO.getSymbolName();
-
- // Print function stub suffix unless it's Mac OS X 10.5 and up.
- if (!isMemOp)
- O << '$';
- else if (Name[0] == '$') {
- // The name begins with a dollar-sign. In order to avoid having it look
- // like an integer immediate to the assembler, enclose it in parens.
- O << '(';
- needCloseParen = true;
- }
-
- O << Name;
-
+ /// NOTE: MO_ExternalSymbol in a non-pcrel_imm context is *only* generated
+ /// by _GLOBAL_OFFSET_TABLE_ on X86-32. All others are call operands, which
+ /// are pcrel_imm's.
+ assert(!Subtarget->is64Bit() && !Subtarget->isPICStyleRIPRel());
+ // These are never used as memory operands.
+ assert(!(Modifier && !strcmp(Modifier, "mem")));
+
+ O << '$';
+ O << TAI->getGlobalPrefix();
+ O << MO.getSymbolName();
+
if (MO.getTargetFlags() == X86II::MO_GOT_ABSOLUTE_ADDRESS) {
O << " + [.-";
PrintPICBaseSymbol();
O << ']';
+ } else {
+ assert(MO.getTargetFlags() == X86II::MO_NO_FLAG &&
+ "Unknown operand flag for external symbol");
}
-
- if (needCloseParen)
- O << ')';
-
- if (Subtarget->isPICStyleRIPRel())
- O << "(%rip)";
return;
}
default:
}
void X86ATTAsmPrinter::printLeaMemReference(const MachineInstr *MI, unsigned Op,
- const char *Modifier,
- bool NotRIPRel) {
+ const char *Modifier) {
MachineOperand BaseReg = MI->getOperand(Op);
MachineOperand IndexReg = MI->getOperand(Op+2);
const MachineOperand &DispSpec = MI->getOperand(Op+3);
- NotRIPRel |= IndexReg.getReg() || BaseReg.getReg();
if (DispSpec.isGlobal() ||
DispSpec.isCPI() ||
DispSpec.isJTI() ||
DispSpec.isSymbol()) {
- printOperand(MI, Op+3, "mem", NotRIPRel);
+ printOperand(MI, Op+3, "mem");
} else {
int DispVal = DispSpec.getImm();
if (DispVal || (!IndexReg.getReg() && !BaseReg.getReg()))
O << DispVal;
}
- if (IndexReg.getReg() || BaseReg.getReg()) {
+ if ((IndexReg.getReg() || BaseReg.getReg()) &&
+ (Modifier == 0 || strcmp(Modifier, "no-rip"))) {
unsigned ScaleVal = MI->getOperand(Op+1).getImm();
unsigned BaseRegOperand = 0, IndexRegOperand = 2;
}
void X86ATTAsmPrinter::printMemReference(const MachineInstr *MI, unsigned Op,
- const char *Modifier, bool NotRIPRel){
+ const char *Modifier) {
assert(isMem(MI, Op) && "Invalid memory reference!");
MachineOperand Segment = MI->getOperand(Op+4);
if (Segment.getReg()) {
printOperand(MI, Op+4, Modifier);
O << ':';
}
- printLeaMemReference(MI, Op, Modifier, NotRIPRel);
+ printLeaMemReference(MI, Op, Modifier);
}
void X86ATTAsmPrinter::printPICJumpTableSetLabel(unsigned uid,
switch (ExtraCode[0]) {
default: return true; // Unknown modifier.
case 'c': // Don't print "$" before a global var name or constant.
- printOperand(MI, OpNo, "mem", /*NotRIPRel=*/true);
+ printOperand(MI, OpNo, "mem");
return false;
case 'b': // Print QImode register
case 'h': // Print QImode high register
return false;
case 'P': // Don't print @PLT, but do print as memory.
- printOperand(MI, OpNo, "mem", /*NotRIPRel=*/true);
+ printOperand(MI, OpNo, "mem");
return false;
+
+ case 'n': { // Negate the immediate or print a '-' before the operand.
+ // Note: this is a temporary solution. It should be handled target
+ // independently as part of the 'MC' work.
+ const MachineOperand &MO = MI->getOperand(OpNo);
+ if (MO.isImm()) {
+ O << -MO.getImm();
+ return false;
+ }
+ O << '-';
+ }
}
}
// These only apply to registers, ignore on mem.
break;
case 'P': // Don't print @PLT, but do print as memory.
- printMemReference(MI, OpNo, "mem", /*NotRIPRel=*/true);
+ printMemReference(MI, OpNo, "no-rip");
return false;
}
}
std::string name = Mang->getValueName(GVar);
Constant *C = GVar->getInitializer();
- if (isa<MDNode>(C))
+ if (isa<MDNode>(C) || isa<MDString>(C))
return;
const Type *Type = C->getType();
unsigned Size = TD->getTypeAllocSize(Type);