diff options
| author | Chris Lattner <sabre@nondot.org> | 2009-06-20 00:49:26 +0000 | 
|---|---|---|
| committer | Chris Lattner <sabre@nondot.org> | 2009-06-20 00:49:26 +0000 | 
| commit | 4682015e615baeee3d4841e5926fc347d1a32d2e (patch) | |
| tree | c555c79f344fb356f07bd0dd95ca360bbd5c1b69 /llvm/lib/Target/X86/AsmPrinter/X86ATTInstPrinter.cpp | |
| parent | 367274280146ba88a451c28c5764e70beb257342 (diff) | |
| download | bcm5719-llvm-4682015e615baeee3d4841e5926fc347d1a32d2e.tar.gz bcm5719-llvm-4682015e615baeee3d4841e5926fc347d1a32d2e.zip | |
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.
llvm-svn: 73810
Diffstat (limited to 'llvm/lib/Target/X86/AsmPrinter/X86ATTInstPrinter.cpp')
| -rw-r--r-- | llvm/lib/Target/X86/AsmPrinter/X86ATTInstPrinter.cpp | 356 | 
1 files changed, 348 insertions, 8 deletions
| diff --git a/llvm/lib/Target/X86/AsmPrinter/X86ATTInstPrinter.cpp b/llvm/lib/Target/X86/AsmPrinter/X86ATTInstPrinter.cpp index 934e45aa815..e46f7a3c74f 100644 --- a/llvm/lib/Target/X86/AsmPrinter/X86ATTInstPrinter.cpp +++ b/llvm/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 << "<<UNKNOWN OPERAND KIND>>"; +   +   +#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<GlobalVariable>(GV); +      if (!GVar) { +        // If GV is an alias then use the aliasee for determining +        // thread-localness. +        if (const GlobalAlias *GA = dyn_cast<GlobalAlias>(GV)) +          GVar = dyn_cast_or_null<GlobalVariable>(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<Function>(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 << "<unknown operand type>"; 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  } | 

