Commit ac0b9301 authored by Pawel Wodnicki's avatar Pawel Wodnicki
Browse files

Merging MIPS JIT/MCJIT changeset into 3.2 release branch.

Merging r169183:

RuntimeDyld: Fix up r169178. MSVC doesn't like "or".

Merging r169178:

Runtime dynamic linker for MCJIT should support MIPS BigEndian architecture.
This small change adds support for that. It will make all MCJIT tests pass
in make-check on BigEndian platforms.

Patch by Petar Jovanovic.

Merging r169177:

Classic JIT is still being supported by MIPS, along with MCJIT.
This change adds endian-awareness to MipsJITInfo and emitWordLE in
MipsCodeEmitter has become emitWord now to support both endianness.

Patch by Petar Jovanovic.

Merging r169174:

Functions in MipsCodeEmitter.cpp that expand unaligned loads/stores are dead
code. Removing it.

Patch by Petar Jovanovic.

llvm-svn: 169296
parent b69f1a10
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -346,7 +346,7 @@ uint8_t *RuntimeDyldImpl::createStubFunction(uint8_t *Addr) {
    uint32_t *StubAddr = (uint32_t*)Addr;
    *StubAddr = 0xe51ff004; // ldr pc,<label>
    return (uint8_t*)++StubAddr;
  } else if (Arch == Triple::mipsel) {
  } else if (Arch == Triple::mipsel || Arch == Triple::mips) {
    uint32_t *StubAddr = (uint32_t*)Addr;
    // 0:   3c190000        lui     t9,%hi(addr).
    // 4:   27390000        addiu   t9,t9,%lo(addr).
+2 −1
Original line number Diff line number Diff line
@@ -676,7 +676,8 @@ void RuntimeDyldELF::processRelocationRef(const ObjRelocationInfo &Rel,
                        RelType, 0);
      Section.StubOffset += getMaxStubSize();
    }
  } else if (Arch == Triple::mipsel && RelType == ELF::R_MIPS_26) {
  } else if ((Arch == Triple::mipsel || Arch == Triple::mips) &&
             RelType == ELF::R_MIPS_26) {
    // This is an Mips branch relocation, need to use a stub function.
    DEBUG(dbgs() << "\t\tThis is a Mips branch relocation.");
    SectionEntry &Section = Sections[Rel.SectionID];
+1 −1
Original line number Diff line number Diff line
@@ -168,7 +168,7 @@ protected:
  inline unsigned getMaxStubSize() {
    if (Arch == Triple::arm || Arch == Triple::thumb)
      return 8; // 32-bit instruction and 32-bit address
    else if (Arch == Triple::mipsel)
    else if (Arch == Triple::mipsel || Arch == Triple::mips)
      return 16;
    else if (Arch == Triple::ppc64)
      return 44;
+8 −108
Original line number Diff line number Diff line
@@ -85,7 +85,7 @@ class MipsCodeEmitter : public MachineFunctionPass {

  private:

    void emitWordLE(unsigned Word);
    void emitWord(unsigned Word);

    /// Routines that handle operands which add machine relocations which are
    /// fixed up by the relocation stage.
@@ -112,12 +112,6 @@ class MipsCodeEmitter : public MachineFunctionPass {
    unsigned getSizeExtEncoding(const MachineInstr &MI, unsigned OpNo) const;
    unsigned getSizeInsEncoding(const MachineInstr &MI, unsigned OpNo) const;

    int emitULW(const MachineInstr &MI);
    int emitUSW(const MachineInstr &MI);
    int emitULH(const MachineInstr &MI);
    int emitULHu(const MachineInstr &MI);
    int emitUSH(const MachineInstr &MI);

    void emitGlobalAddressUnaligned(const GlobalValue *GV, unsigned Reloc,
                                    int Offset) const;
  };
@@ -133,7 +127,7 @@ bool MipsCodeEmitter::runOnMachineFunction(MachineFunction &MF) {
  MCPEs = &MF.getConstantPool()->getConstants();
  MJTEs = 0;
  if (MF.getJumpTableInfo()) MJTEs = &MF.getJumpTableInfo()->getJumpTables();
  JTI->Initialize(MF, IsPIC);
  JTI->Initialize(MF, IsPIC, Subtarget->isLittle());
  MCE.setModuleInfo(&getAnalysis<MachineModuleInfo> ());

  do {
@@ -271,103 +265,6 @@ void MipsCodeEmitter::emitMachineBasicBlock(MachineBasicBlock *BB,
                                             Reloc, BB));
}

int MipsCodeEmitter::emitUSW(const MachineInstr &MI) {
  unsigned src = getMachineOpValue(MI, MI.getOperand(0));
  unsigned base = getMachineOpValue(MI, MI.getOperand(1));
  unsigned offset = getMachineOpValue(MI, MI.getOperand(2));
  // swr src, offset(base)
  // swl src, offset+3(base)
  MCE.emitWordLE(
    (0x2e << 26) | (base << 21) | (src << 16) | (offset & 0xffff));
  MCE.emitWordLE(
    (0x2a << 26) | (base << 21) | (src << 16) | ((offset+3) & 0xffff));
  return 2;
}

int MipsCodeEmitter::emitULW(const MachineInstr &MI) {
  unsigned dst = getMachineOpValue(MI, MI.getOperand(0));
  unsigned base = getMachineOpValue(MI, MI.getOperand(1));
  unsigned offset = getMachineOpValue(MI, MI.getOperand(2));
  unsigned at = 1;
  if (dst != base) {
    // lwr dst, offset(base)
    // lwl dst, offset+3(base)
    MCE.emitWordLE(
      (0x26 << 26) | (base << 21) | (dst << 16) | (offset & 0xffff));
    MCE.emitWordLE(
      (0x22 << 26) | (base << 21) | (dst << 16) | ((offset+3) & 0xffff));
    return 2;
  } else {
    // lwr at, offset(base)
    // lwl at, offset+3(base)
    // addu dst, at, $zero
    MCE.emitWordLE(
      (0x26 << 26) | (base << 21) | (at << 16) | (offset & 0xffff));
    MCE.emitWordLE(
      (0x22 << 26) | (base << 21) | (at << 16) | ((offset+3) & 0xffff));
    MCE.emitWordLE(
      (0x0 << 26) | (at << 21) | (0x0 << 16) | (dst << 11) | (0x0 << 6) | 0x21);
    return 3;
  }
}

int MipsCodeEmitter::emitUSH(const MachineInstr &MI) {
  unsigned src = getMachineOpValue(MI, MI.getOperand(0));
  unsigned base = getMachineOpValue(MI, MI.getOperand(1));
  unsigned offset = getMachineOpValue(MI, MI.getOperand(2));
  unsigned at = 1;
  // sb src, offset(base)
  // srl at,src,8
  // sb at, offset+1(base)
  MCE.emitWordLE(
    (0x28 << 26) | (base << 21) | (src << 16) | (offset & 0xffff));
  MCE.emitWordLE(
    (0x0 << 26) | (0x0 << 21) | (src << 16) | (at << 11) | (0x8 << 6) | 0x2);
  MCE.emitWordLE(
    (0x28 << 26) | (base << 21) | (at << 16) | ((offset+1) & 0xffff));
  return 3;
}

int MipsCodeEmitter::emitULH(const MachineInstr &MI) {
  unsigned dst = getMachineOpValue(MI, MI.getOperand(0));
  unsigned base = getMachineOpValue(MI, MI.getOperand(1));
  unsigned offset = getMachineOpValue(MI, MI.getOperand(2));
  unsigned at = 1;
  // lbu at, offset(base)
  // lb dst, offset+1(base)
  // sll dst,dst,8
  // or dst,dst,at
  MCE.emitWordLE(
    (0x24 << 26) | (base << 21) | (at << 16) | (offset & 0xffff));
  MCE.emitWordLE(
    (0x20 << 26) | (base << 21) | (dst << 16) | ((offset+1) & 0xffff));
  MCE.emitWordLE(
    (0x0 << 26) | (0x0 << 21) | (dst << 16) | (dst << 11) | (0x8 << 6) | 0x0);
  MCE.emitWordLE(
    (0x0 << 26) | (dst << 21) | (at << 16) | (dst << 11) | (0x0 << 6) | 0x25);
  return 4;
}

int MipsCodeEmitter::emitULHu(const MachineInstr &MI) {
  unsigned dst = getMachineOpValue(MI, MI.getOperand(0));
  unsigned base = getMachineOpValue(MI, MI.getOperand(1));
  unsigned offset = getMachineOpValue(MI, MI.getOperand(2));
  unsigned at = 1;
  // lbu at, offset(base)
  // lbu dst, offset+1(base)
  // sll dst,dst,8
  // or dst,dst,at
  MCE.emitWordLE(
    (0x24 << 26) | (base << 21) | (at << 16) | (offset & 0xffff));
  MCE.emitWordLE(
    (0x24 << 26) | (base << 21) | (dst << 16) | ((offset+1) & 0xffff));
  MCE.emitWordLE(
    (0x0 << 26) | (0x0 << 21) | (dst << 16) | (dst << 11) | (0x8 << 6) | 0x0);
  MCE.emitWordLE(
    (0x0 << 26) | (dst << 21) | (at << 16) | (dst << 11) | (0x0 << 6) | 0x25);
  return 4;
}

void MipsCodeEmitter::emitInstruction(const MachineInstr &MI) {
  DEBUG(errs() << "JIT: " << (void*)MCE.getCurrentPCValue() << ":\t" << MI);

@@ -377,16 +274,19 @@ void MipsCodeEmitter::emitInstruction(const MachineInstr &MI) {
  if ((MI.getDesc().TSFlags & MipsII::FormMask) == MipsII::Pseudo)
    return;

  emitWordLE(getBinaryCodeForInstr(MI));
  emitWord(getBinaryCodeForInstr(MI));
  ++NumEmitted;  // Keep track of the # of mi's emitted

  MCE.processDebugLoc(MI.getDebugLoc(), false);
}

void MipsCodeEmitter::emitWordLE(unsigned Word) {
void MipsCodeEmitter::emitWord(unsigned Word) {
  DEBUG(errs() << "  0x";
        errs().write_hex(Word) << "\n");
  if (Subtarget->isLittle())
    MCE.emitWordLE(Word);
  else
    MCE.emitWordBE(Word);
}

/// createMipsJITCodeEmitterPass - Return a pass that emits the collected Mips
+11 −4
Original line number Diff line number Diff line
@@ -222,10 +222,17 @@ void *MipsJITInfo::emitFunctionStub(const Function *F, void *Fn,
  // addiu t9, t9, %lo(EmittedAddr)
  // jalr t8, t9
  // nop
  if (IsLittleEndian) {
    JCE.emitWordLE(0xf << 26 | 25 << 16 | Hi);
    JCE.emitWordLE(9 << 26 | 25 << 21 | 25 << 16 | Lo);
    JCE.emitWordLE(25 << 21 | 24 << 11 | 9);
    JCE.emitWordLE(0);
  } else {
    JCE.emitWordBE(0xf << 26 | 25 << 16 | Hi);
    JCE.emitWordBE(9 << 26 | 25 << 21 | 25 << 16 | Lo);
    JCE.emitWordBE(25 << 21 | 24 << 11 | 9);
    JCE.emitWordBE(0);
  }

  sys::Memory::InvalidateInstructionCache(Addr, 16);
  if (!sys::Memory::setRangeExecutable(Addr, 16))
Loading