From 2891662cc227829b5d9d59be6e10d968e289b9fe Mon Sep 17 00:00:00 2001 From: Akira Hatanaka Date: Fri, 14 Oct 2011 02:55:47 +0000 Subject: [PATCH] Add definition of class MipsELFWriterInfo. Patch by Jack Carter and Reed Kotler at Mips. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@141937 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Mips/CMakeLists.txt | 1 + lib/Target/Mips/MipsELFWriterInfo.cpp | 215 ++++++++++++++++++++++++++ lib/Target/Mips/MipsELFWriterInfo.h | 60 +++++++ 3 files changed, 276 insertions(+) create mode 100644 lib/Target/Mips/MipsELFWriterInfo.cpp create mode 100644 lib/Target/Mips/MipsELFWriterInfo.h diff --git a/lib/Target/Mips/CMakeLists.txt b/lib/Target/Mips/CMakeLists.txt index 1b4329baf0f..fb2e926e2bb 100644 --- a/lib/Target/Mips/CMakeLists.txt +++ b/lib/Target/Mips/CMakeLists.txt @@ -12,6 +12,7 @@ add_llvm_target(MipsCodeGen MipsAsmPrinter.cpp MipsCodeEmitter.cpp MipsDelaySlotFiller.cpp + MipsELFWriterInfo.cpp MipsEmitGPRestore.cpp MipsExpandPseudo.cpp MipsJITInfo.cpp diff --git a/lib/Target/Mips/MipsELFWriterInfo.cpp b/lib/Target/Mips/MipsELFWriterInfo.cpp new file mode 100644 index 00000000000..3f3414fccdb --- /dev/null +++ b/lib/Target/Mips/MipsELFWriterInfo.cpp @@ -0,0 +1,215 @@ +//===-- MipsELFWriterInfo.cpp - ELF Writer Info for the Mips backend ------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements ELF writer information for the Mips backend. +// +//===----------------------------------------------------------------------===// +#include "MipsELFWriterInfo.h" +#include "MipsRelocations.h" +#include "llvm/Function.h" +#include "llvm/Support/ELF.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Target/TargetData.h" +#include "llvm/Target/TargetMachine.h" + +using namespace llvm; + +//===----------------------------------------------------------------------===// +// Implementation of the MipsELFWriterInfo class +//===----------------------------------------------------------------------===// + +MipsELFWriterInfo::MipsELFWriterInfo(bool is64Bit_, bool isLittleEndian_) + : TargetELFWriterInfo(is64Bit_, isLittleEndian_) { + EMachine = EM_MIPS; +} + +MipsELFWriterInfo::~MipsELFWriterInfo() {} + +unsigned MipsELFWriterInfo::getRelocationType(unsigned MachineRelTy) const { + if (is64Bit) { + switch(MachineRelTy) { + default: + llvm_unreachable("unknown Mips_64 machine relocation type"); + } + } else { + switch(MachineRelTy) { + case Mips::reloc_mips_pcrel: + return ELF::R_MIPS_PC16; + case Mips::reloc_mips_hi: + return ELF::R_MIPS_HI16; + case Mips::reloc_mips_lo: + return ELF::R_MIPS_LO16; + case Mips::reloc_mips_j_jal: + return ELF::R_MIPS_26; + case Mips::reloc_mips_16: + return ELF::R_MIPS_16; + case Mips::reloc_mips_32: + return ELF::R_MIPS_32; + case Mips::reloc_mips_rel32: + return ELF::R_MIPS_REL32; + case Mips::reloc_mips_gprel16: + return ELF::R_MIPS_GPREL16; + case Mips::reloc_mips_literal: + return ELF::R_MIPS_LITERAL; + case Mips::reloc_mips_got16: + return ELF::R_MIPS_GOT16; + case Mips::reloc_mips_call16: + return ELF::R_MIPS_CALL16; + case Mips::reloc_mips_gprel32: + return ELF::R_MIPS_GPREL32; + case Mips::reloc_mips_shift5: + return ELF::R_MIPS_SHIFT5; + case Mips::reloc_mips_shift6: + return ELF::R_MIPS_SHIFT6; + case Mips::reloc_mips_64: + return ELF::R_MIPS_64; + case Mips::reloc_mips_tlsgd: + return ELF::R_MIPS_TLS_GD; + case Mips::reloc_mips_gottprel: + return ELF::R_MIPS_TLS_GOTTPREL; + case Mips::reloc_mips_tprel_hi: + return ELF::R_MIPS_TLS_TPREL_HI16; + case Mips::reloc_mips_tprel_lo: + return ELF::R_MIPS_TLS_TPREL_LO16; + case Mips::reloc_mips_branch_pcrel: + return ELF::R_MIPS_PC16; + default: + llvm_unreachable("unknown Mips machine relocation type"); + } + } + return 0; +} + +long int MipsELFWriterInfo::getDefaultAddendForRelTy(unsigned RelTy, + long int Modifier) const { + if (is64Bit) { + switch(RelTy) { + default: + llvm_unreachable("unknown Mips_64 relocation type"); + } + } else { + switch(RelTy) { + case ELF::R_MIPS_PC16: return Modifier - 4; + default: + llvm_unreachable("unknown Mips relocation type"); + } + } + return 0; +} + +unsigned MipsELFWriterInfo::getRelocationTySize(unsigned RelTy) const { + if (is64Bit) { + switch(RelTy) { + case ELF::R_MIPS_PC16: + case ELF::R_MIPS_HI16: + case ELF::R_MIPS_LO16: + case ELF::R_MIPS_26: + case ELF::R_MIPS_16: + case ELF::R_MIPS_32: + case ELF::R_MIPS_REL32: + case ELF::R_MIPS_GPREL16: + case ELF::R_MIPS_LITERAL: + case ELF::R_MIPS_GOT16: + case ELF::R_MIPS_CALL16: + case ELF::R_MIPS_GPREL32: + case ELF::R_MIPS_SHIFT5: + case ELF::R_MIPS_SHIFT6: + return 32; + case ELF::R_MIPS_64: + return 64; + default: + llvm_unreachable("unknown Mips_64 relocation type"); + } + } else { + switch(RelTy) { + case ELF::R_MIPS_PC16: + case ELF::R_MIPS_HI16: + case ELF::R_MIPS_LO16: + case ELF::R_MIPS_26: + case ELF::R_MIPS_16: + case ELF::R_MIPS_32: + case ELF::R_MIPS_REL32: + case ELF::R_MIPS_GPREL16: + case ELF::R_MIPS_LITERAL: + case ELF::R_MIPS_GOT16: + case ELF::R_MIPS_CALL16: + case ELF::R_MIPS_GPREL32: + case ELF::R_MIPS_SHIFT5: + case ELF::R_MIPS_SHIFT6: + return 32; + default: + llvm_unreachable("unknown Mips relocation type"); + } + } + return 0; +} + +bool MipsELFWriterInfo::isPCRelativeRel(unsigned RelTy) const { + if (is64Bit) { + switch(RelTy) { + case ELF::R_MIPS_PC16: + return true; + case ELF::R_MIPS_HI16: + case ELF::R_MIPS_LO16: + case ELF::R_MIPS_26: + case ELF::R_MIPS_16: + case ELF::R_MIPS_32: + case ELF::R_MIPS_REL32: + case ELF::R_MIPS_GPREL16: + case ELF::R_MIPS_LITERAL: + case ELF::R_MIPS_GOT16: + case ELF::R_MIPS_CALL16: + case ELF::R_MIPS_GPREL32: + case ELF::R_MIPS_SHIFT5: + case ELF::R_MIPS_SHIFT6: + case ELF::R_MIPS_64: + return false; + default: + llvm_unreachable("unknown Mips_64 relocation type"); + } + } else { + switch(RelTy) { + case ELF::R_MIPS_PC16: + return true; + case ELF::R_MIPS_HI16: + case ELF::R_MIPS_LO16: + case ELF::R_MIPS_26: + case ELF::R_MIPS_16: + case ELF::R_MIPS_32: + case ELF::R_MIPS_REL32: + case ELF::R_MIPS_GPREL16: + case ELF::R_MIPS_LITERAL: + case ELF::R_MIPS_GOT16: + case ELF::R_MIPS_CALL16: + case ELF::R_MIPS_GPREL32: + case ELF::R_MIPS_SHIFT5: + case ELF::R_MIPS_SHIFT6: + return false; + default: + llvm_unreachable("unknown Mips relocation type"); + } + } + return 0; +} + +unsigned MipsELFWriterInfo::getAbsoluteLabelMachineRelTy() const { + assert("getAbsoluteLabelMachineRelTy unknown for this relocation type"); + return 0; +} + +long int MipsELFWriterInfo::computeRelocation(unsigned SymOffset, + unsigned RelOffset, + unsigned RelTy) const { + if (RelTy == ELF::R_MIPS_PC16) + return SymOffset - (RelOffset + 4); + else + assert("computeRelocation unknown for this relocation type"); + + return 0; +} diff --git a/lib/Target/Mips/MipsELFWriterInfo.h b/lib/Target/Mips/MipsELFWriterInfo.h new file mode 100644 index 00000000000..8d7d02bf470 --- /dev/null +++ b/lib/Target/Mips/MipsELFWriterInfo.h @@ -0,0 +1,60 @@ +//===-- MipsELFWriterInfo.h - ELF Writer Info for Mips ----------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements ELF writer information for the Mips backend. +// +//===----------------------------------------------------------------------===// + +#ifndef Mips_ELF_WRITER_INFO_H +#define Mips_ELF_WRITER_INFO_H + +#include "llvm/Target/TargetELFWriterInfo.h" + +namespace llvm { + + class MipsELFWriterInfo : public TargetELFWriterInfo { + + public: + MipsELFWriterInfo(bool, bool); + virtual ~MipsELFWriterInfo(); + + /// getRelocationType - Returns the target specific ELF Relocation type. + /// 'MachineRelTy' contains the object code independent relocation type + virtual unsigned getRelocationType(unsigned MachineRelTy) const; + + /// hasRelocationAddend - True if the target uses an addend in the + /// ELF relocation entry. + virtual bool hasRelocationAddend() const { return true; } + // FIXME Should be case by case + + /// getDefaultAddendForRelTy - Gets the default addend value for a + /// relocation entry based on the target ELF relocation type. + virtual long int getDefaultAddendForRelTy(unsigned RelTy, + long int Modifier = 0) const; + + /// getRelTySize - Returns the size of relocatable field in bits + virtual unsigned getRelocationTySize(unsigned RelTy) const; + + /// isPCRelativeRel - True if the relocation type is pc relative + virtual bool isPCRelativeRel(unsigned RelTy) const; + + /// getJumpTableRelocationTy - Returns the machine relocation type used + /// to reference a jumptable. + virtual unsigned getAbsoluteLabelMachineRelTy() const; + + /// computeRelocation - Some relocatable fields could be relocated + /// directly, avoiding the relocation symbol emission, compute the + /// final relocation value for this symbol. + virtual long int computeRelocation(unsigned SymOffset, unsigned RelOffset, + unsigned RelTy) const; + }; + +} // end llvm namespace + +#endif // Mips_ELF_WRITER_INFO_H