//===-- PPCMachOWriterInfo.cpp - Mach-O Writer Info for the PowerPC -------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by Bill Wendling and is distributed under the
// University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements Mach-O writer information for the PowerPC backend.
//
//===----------------------------------------------------------------------===//

#include "PPCMachOWriterInfo.h"
#include "PPCRelocations.h"
#include "PPCTargetMachine.h"
#include "llvm/CodeGen/MachORelocation.h"
#include "llvm/Support/OutputBuffer.h"
using namespace llvm;

PPCMachOWriterInfo::PPCMachOWriterInfo(const PPCTargetMachine &TM)
  : TargetMachOWriterInfo(TM.getTargetData()->getPointerSizeInBits() == 64 ?
                          HDR_CPU_TYPE_POWERPC64 :
                          HDR_CPU_TYPE_POWERPC,
                          HDR_CPU_SUBTYPE_POWERPC_ALL) {}
PPCMachOWriterInfo::~PPCMachOWriterInfo() {}

/// GetTargetRelocation - For the MachineRelocation MR, convert it to one or
/// more PowerPC MachORelocation(s), add the new relocations to the
/// MachOSection, and rewrite the instruction at the section offset if required
/// by that relocation type.
unsigned PPCMachOWriterInfo::GetTargetRelocation(MachineRelocation &MR,
                                                 unsigned FromIdx,
                                                 unsigned ToAddr,
                                                 unsigned ToIdx,
                                                 OutputBuffer &RelocOut,
                                                 OutputBuffer &SecOut,
                                                 bool Scattered,
                                                 bool isExtern) const {
  unsigned NumRelocs = 0;
  uint64_t Addr = 0;

  // Get the address of whatever it is we're relocating, if possible.
  if (!isExtern)
    Addr = (uintptr_t)MR.getResultPointer() + ToAddr;

  switch ((PPC::RelocationType)MR.getRelocationType()) {
  default: assert(0 && "Unknown PPC relocation type!");
  case PPC::reloc_absolute_low_ix:
    assert(0 && "Unhandled PPC relocation type!");
    break;
  case PPC::reloc_vanilla:
    {
      // FIXME: need to handle 64 bit vanilla relocs
      MachORelocation VANILLA(MR.getMachineCodeOffset(), ToIdx,
                              false, 2, isExtern,
                              PPC_RELOC_VANILLA,
                              Scattered, (intptr_t)MR.getResultPointer());
      ++NumRelocs;

      if (Scattered) {
        RelocOut.outword(VANILLA.getPackedFields());
        RelocOut.outword(VANILLA.getAddress());
      } else {
        RelocOut.outword(VANILLA.getAddress());
        RelocOut.outword(VANILLA.getPackedFields());
      }
      
      intptr_t SymbolOffset;

      if (Scattered)
        SymbolOffset = Addr + MR.getConstantVal();
      else
        SymbolOffset = Addr;

      printf("vanilla fixup: sec_%x[%x] = %x\n", FromIdx,
             unsigned(MR.getMachineCodeOffset()),
             unsigned(SymbolOffset));
      SecOut.fixword(SymbolOffset, MR.getMachineCodeOffset());
    }
    break;
  case PPC::reloc_pcrel_bx:
    {
      // FIXME: Presumably someday we will need to branch to other, non-extern
      // functions too.  Need to figure out some way to distinguish between
      // target is BB and target is function.
      if (isExtern) {
        MachORelocation BR24(MR.getMachineCodeOffset(), ToIdx, true, 2, 
                             isExtern, PPC_RELOC_BR24, Scattered, 
                             (intptr_t)MR.getMachineCodeOffset());
        RelocOut.outword(BR24.getAddress());
        RelocOut.outword(BR24.getPackedFields());
        ++NumRelocs;
      }

      Addr -= MR.getMachineCodeOffset();
      Addr >>= 2;
      Addr &= 0xFFFFFF;
      Addr <<= 2;
      Addr |= (SecOut[MR.getMachineCodeOffset()] << 24);
      Addr |= (SecOut[MR.getMachineCodeOffset()+3] & 0x3);
      SecOut.fixword(Addr, MR.getMachineCodeOffset());
      break;
    }
  case PPC::reloc_pcrel_bcx:
    {
      Addr -= MR.getMachineCodeOffset();
      Addr &= 0xFFFC;

      SecOut.fixhalf(Addr, MR.getMachineCodeOffset() + 2);
      break;
    }
  case PPC::reloc_absolute_high:
    {
      MachORelocation HA16(MR.getMachineCodeOffset(), ToIdx, false, 2,
                           isExtern, PPC_RELOC_HA16);
      MachORelocation PAIR(Addr & 0xFFFF, 0xFFFFFF, false, 2, isExtern,
                           PPC_RELOC_PAIR);
      NumRelocs = 2;

      RelocOut.outword(HA16.getRawAddress());
      RelocOut.outword(HA16.getPackedFields());
      RelocOut.outword(PAIR.getRawAddress());
      RelocOut.outword(PAIR.getPackedFields());

      Addr += 0x8000;

      SecOut.fixhalf(Addr >> 16, MR.getMachineCodeOffset() + 2);
      break;
    }
  case PPC::reloc_absolute_low:
    {
      MachORelocation LO16(MR.getMachineCodeOffset(), ToIdx, false, 2,
                           isExtern, PPC_RELOC_LO16);
      MachORelocation PAIR(Addr >> 16, 0xFFFFFF, false, 2, isExtern,
                           PPC_RELOC_PAIR);
      NumRelocs = 2;

      RelocOut.outword(LO16.getRawAddress());
      RelocOut.outword(LO16.getPackedFields());
      RelocOut.outword(PAIR.getRawAddress());
      RelocOut.outword(PAIR.getPackedFields());

      SecOut.fixhalf(Addr, MR.getMachineCodeOffset() + 2);
      break;
    }
  }

  return NumRelocs;
}
