From: Chris Lattner Date: Sat, 20 Jun 2009 00:49:26 +0000 (+0000) Subject: Start implementing translation of MachineInstr to MCInst. Next X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=f38c03af2a142db2777ce839026706969f3aeaa9;p=oota-llvm.git Start implementing translation of MachineInstr to MCInst. Next step is to make tblgen generate something more appropriate for MCInst, and generate calls to operand translation routines where needed. This includes a bunch of #if 0 code which will slowly be refactored into something sensible. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@73810 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp b/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp index 7e48855e08d..44d817de022 100644 --- a/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp +++ b/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp @@ -771,6 +771,29 @@ void X86ATTAsmPrinter::printMachineInstruction(const MachineInstr *MI) { if (NewAsmPrinter) { O << "NEW: "; MCInst TmpInst; + + TmpInst.setOpcode(MI->getOpcode()); + + for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { + const MachineOperand &MO = MI->getOperand(i); + + MCOperand MCOp; + if (MO.isReg()) { + MCOp.MakeReg(MO.getReg()); + } else if (MO.isImm()) { + MCOp.MakeImm(MO.getImm()); + } else { + assert(0 && "Unimp"); + } + + TmpInst.addOperand(MCOp); + } + + if (MI->getOpcode() == X86::LEA64_32r) { + // Should handle the 'subreg rewriting' for the lea64_32mem operand. + + } + // FIXME: Convert TmpInst. printInstruction(&TmpInst); O << "OLD: "; diff --git a/lib/Target/X86/AsmPrinter/X86ATTInstPrinter.cpp b/lib/Target/X86/AsmPrinter/X86ATTInstPrinter.cpp index 934e45aa815..e46f7a3c74f 100644 --- a/lib/Target/X86/AsmPrinter/X86ATTInstPrinter.cpp +++ b/lib/Target/X86/AsmPrinter/X86ATTInstPrinter.cpp @@ -28,14 +28,14 @@ void X86ATTAsmPrinter::printSSECC(const MCInst *MI, unsigned Op) { unsigned char value = MI->getOperand(Op).getImm(); assert(value <= 7 && "Invalid ssecc argument!"); switch (value) { - case 0: O << "eq"; break; - case 1: O << "lt"; break; - case 2: O << "le"; break; - case 3: O << "unord"; break; - case 4: O << "neq"; break; - case 5: O << "nlt"; break; - case 6: O << "nle"; break; - case 7: O << "ord"; break; + case 0: O << "eq"; break; + case 1: O << "lt"; break; + case 2: O << "le"; break; + case 3: O << "unord"; break; + case 4: O << "neq"; break; + case 5: O << "nlt"; break; + case 6: O << "nle"; break; + case 7: O << "ord"; break; } } @@ -48,13 +48,353 @@ void X86ATTAsmPrinter::printPICLabel(const MCInst *MI, unsigned Op) { void X86ATTAsmPrinter::printOperand(const MCInst *MI, unsigned OpNo, const char *Modifier, bool NotRIPRel) { + //assert(Modifier == 0 && "Modifiers should not be used"); + + const MCOperand &Op = MI->getOperand(OpNo); + if (Op.isReg()) { + O << '%'; + unsigned Reg = Op.getReg(); +#if 0 + if (Modifier && strncmp(Modifier, "subreg", strlen("subreg")) == 0) { + MVT VT = (strcmp(Modifier+6,"64") == 0) ? + MVT::i64 : ((strcmp(Modifier+6, "32") == 0) ? MVT::i32 : + ((strcmp(Modifier+6,"16") == 0) ? MVT::i16 : MVT::i8)); + Reg = getX86SubSuperRegister(Reg, VT); + } +#endif + O << TRI->getAsmName(Reg); + return; + } else if (Op.isImm()) { + //if (!Modifier || (strcmp(Modifier, "debug") && strcmp(Modifier, "mem") && + // strcmp(Modifier, "call"))) + O << '$'; + O << Op.getImm(); + return; + } + + O << "<>"; + + +#if 0 + const MachineOperand &MO = MI->getOperand(OpNo); + switch (MO.getType()) { + case MachineOperand::MO_Register: { + assert(TargetRegisterInfo::isPhysicalRegister(MO.getReg()) && + "Virtual registers should not make it this far!"); + O << '%'; + unsigned Reg = MO.getReg(); + if (Modifier && strncmp(Modifier, "subreg", strlen("subreg")) == 0) { + MVT VT = (strcmp(Modifier+6,"64") == 0) ? + MVT::i64 : ((strcmp(Modifier+6, "32") == 0) ? MVT::i32 : + ((strcmp(Modifier+6,"16") == 0) ? MVT::i16 : MVT::i8)); + Reg = getX86SubSuperRegister(Reg, VT); + } + O << TRI->getAsmName(Reg); + return; + } + + case MachineOperand::MO_Immediate: + if (!Modifier || (strcmp(Modifier, "debug") && + strcmp(Modifier, "mem") && + strcmp(Modifier, "call"))) + O << '$'; + O << MO.getImm(); + return; + case MachineOperand::MO_MachineBasicBlock: + printBasicBlockLabel(MO.getMBB(), false, false, VerboseAsm); + return; + case MachineOperand::MO_JumpTableIndex: { + bool isMemOp = Modifier && !strcmp(Modifier, "mem"); + if (!isMemOp) O << '$'; + O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() << '_' + << MO.getIndex(); + + if (TM.getRelocationModel() == Reloc::PIC_) { + if (Subtarget->isPICStyleStub()) + O << "-\"" << TAI->getPrivateGlobalPrefix() << getFunctionNumber() + << "$pb\""; + else if (Subtarget->isPICStyleGOT()) + O << "@GOTOFF"; + } + + if (isMemOp && Subtarget->isPICStyleRIPRel() && !NotRIPRel) + O << "(%rip)"; + return; + } + case MachineOperand::MO_ConstantPoolIndex: { + bool isMemOp = Modifier && !strcmp(Modifier, "mem"); + if (!isMemOp) O << '$'; + O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << '_' + << MO.getIndex(); + + if (TM.getRelocationModel() == Reloc::PIC_) { + if (Subtarget->isPICStyleStub()) + O << "-\"" << TAI->getPrivateGlobalPrefix() << getFunctionNumber() + << "$pb\""; + else if (Subtarget->isPICStyleGOT()) + O << "@GOTOFF"; + } + + printOffset(MO.getOffset()); + + if (isMemOp && Subtarget->isPICStyleRIPRel() && !NotRIPRel) + O << "(%rip)"; + return; + } + case MachineOperand::MO_GlobalAddress: { + bool isCallOp = Modifier && !strcmp(Modifier, "call"); + bool isMemOp = Modifier && !strcmp(Modifier, "mem"); + bool needCloseParen = false; + + const GlobalValue *GV = MO.getGlobal(); + const GlobalVariable *GVar = dyn_cast(GV); + if (!GVar) { + // If GV is an alias then use the aliasee for determining + // thread-localness. + if (const GlobalAlias *GA = dyn_cast(GV)) + GVar = dyn_cast_or_null(GA->resolveAliasedGlobal(false)); + } + + bool isThreadLocal = GVar && GVar->isThreadLocal(); + + std::string Name = Mang->getValueName(GV); + decorateName(Name, GV); + + if (!isMemOp && !isCallOp) + 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; + } + + if (shouldPrintStub(TM, Subtarget)) { + // Link-once, declaration, or Weakly-linked global variables need + // non-lazily-resolved stubs + if (GV->isDeclaration() || GV->isWeakForLinker()) { + // Dynamically-resolved functions need a stub for the function. + if (isCallOp && isa(GV)) { + // Function stubs are no longer needed for Mac OS X 10.5 and up. + if (Subtarget->isTargetDarwin() && Subtarget->getDarwinVers() >= 9) { + O << Name; + } else { + FnStubs.insert(Name); + printSuffixedName(Name, "$stub"); + } + } else if (GV->hasHiddenVisibility()) { + if (!GV->isDeclaration() && !GV->hasCommonLinkage()) + // Definition is not definitely in the current translation unit. + O << Name; + else { + HiddenGVStubs.insert(Name); + printSuffixedName(Name, "$non_lazy_ptr"); + } + } else { + GVStubs.insert(Name); + printSuffixedName(Name, "$non_lazy_ptr"); + } + } else { + if (GV->hasDLLImportLinkage()) + O << "__imp_"; + O << Name; + } + + if (!isCallOp && TM.getRelocationModel() == Reloc::PIC_) + O << '-' << getPICLabelString(getFunctionNumber(), TAI, Subtarget); + } else { + if (GV->hasDLLImportLinkage()) { + O << "__imp_"; + } + O << Name; + + if (isCallOp) { + if (shouldPrintPLT(TM, Subtarget)) { + // Assemble call via PLT for externally visible symbols + if (!GV->hasHiddenVisibility() && !GV->hasProtectedVisibility() && + !GV->hasLocalLinkage()) + O << "@PLT"; + } + if (Subtarget->isTargetCygMing() && GV->isDeclaration()) + // Save function name for later type emission + FnStubs.insert(Name); + } + } + + if (GV->hasExternalWeakLinkage()) + ExtWeakSymbols.insert(GV); + + printOffset(MO.getOffset()); + + 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(%rip)"; + } else { + O << "@INDNTPOFF"; + } + break; + case TLSModel::LocalExec: + if (Subtarget->is64Bit()) + O << "@TPOFF"; + else + O << "@NTPOFF"; + break; + default: + assert (0 && "Unknown TLS model"); + } + } else if (isMemOp) { + if (shouldPrintGOT(TM, Subtarget)) { + if (Subtarget->GVRequiresExtraLoad(GV, TM, false)) + O << "@GOT"; + else + O << "@GOTOFF"; + } else if (Subtarget->isPICStyleRIPRel() && !NotRIPRel) { + if (TM.getRelocationModel() != Reloc::Static) { + if (Subtarget->GVRequiresExtraLoad(GV, TM, false)) + O << "@GOTPCREL"; + + if (needCloseParen) { + needCloseParen = false; + O << ')'; + } + } + + // 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 + O << "(%rip)"; + } + } + + if (needCloseParen) + O << ')'; + + return; + } + case MachineOperand::MO_ExternalSymbol: { + bool isCallOp = Modifier && !strcmp(Modifier, "call"); + 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 (isCallOp && shouldPrintStub(TM, Subtarget) && + !(Subtarget->isTargetDarwin() && Subtarget->getDarwinVers() >= 9)) { + FnStubs.insert(Name); + printSuffixedName(Name, "$stub"); + return; + } + if (!isMemOp && !isCallOp) + 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; + + if (shouldPrintPLT(TM, Subtarget)) { + std::string GOTName(TAI->getGlobalPrefix()); + GOTName+="_GLOBAL_OFFSET_TABLE_"; + if (Name == GOTName) + // HACK! Emit extra offset to PC during printing GOT offset to + // compensate for the size of popl instruction. The resulting code + // should look like: + // call .piclabel + // piclabel: + // popl %some_register + // addl $_GLOBAL_ADDRESS_TABLE_ + [.-piclabel], %some_register + O << " + [.-" + << getPICLabelString(getFunctionNumber(), TAI, Subtarget) << ']'; + + if (isCallOp) + O << "@PLT"; + } + + if (needCloseParen) + O << ')'; + + if (!isCallOp && Subtarget->isPICStyleRIPRel()) + O << "(%rip)"; + + return; + } + default: + O << ""; return; + } +#endif } void X86ATTAsmPrinter::printLeaMemReference(const MCInst *MI, unsigned Op, const char *Modifier, bool NotRIPRel) { + const MCOperand &BaseReg = MI->getOperand(Op); + const MCOperand &IndexReg = MI->getOperand(Op+2); + const MCOperand &DispSpec = MI->getOperand(Op+3); + + NotRIPRel |= IndexReg.getReg() || BaseReg.getReg(); + if (DispSpec.isImm()) { + int64_t DispVal = DispSpec.getImm(); + if (DispVal || (!IndexReg.getReg() && !BaseReg.getReg())) + O << DispVal; + } else { + abort(); + //assert(DispSpec.isGlobal() || DispSpec.isCPI() || + // DispSpec.isJTI() || DispSpec.isSymbol()); + //printOperand(MI, Op+3, "mem", NotRIPRel); + } + + if (IndexReg.getReg() || BaseReg.getReg()) { + unsigned ScaleVal = MI->getOperand(Op+1).getImm(); + unsigned BaseRegOperand = 0, IndexRegOperand = 2; + + // There are cases where we can end up with ESP/RSP in the indexreg slot. + // If this happens, swap the base/index register to support assemblers that + // don't work when the index is *SP. + // FIXME: REMOVE THIS. + if (IndexReg.getReg() == X86::ESP || IndexReg.getReg() == X86::RSP) { + assert(ScaleVal == 1 && "Scale not supported for stack pointer!"); + abort(); + //std::swap(BaseReg, IndexReg); + //std::swap(BaseRegOperand, IndexRegOperand); + } + + O << '('; + if (BaseReg.getReg()) + printOperand(MI, Op+BaseRegOperand, Modifier); + + if (IndexReg.getReg()) { + O << ','; + printOperand(MI, Op+IndexRegOperand, Modifier); + if (ScaleVal != 1) + O << ',' << ScaleVal; + } + O << ')'; + } } void X86ATTAsmPrinter::printMemReference(const MCInst *MI, unsigned Op, const char *Modifier, bool NotRIPRel){ +#if 0 + 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); +#endif }