mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-15 04:30:12 +00:00
ARM: move ARMUnwindOp.h into Support
Move the ARM EHABI unwind opcode definitions from the ARM MCTargetDesc into LLVM Support. This enables sharing of the definitions across the ARM target code as well as llvm-readobj. This will allow implementation of the unwind decoding in llvm-readobj. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@198576 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
0dc0e22ada
commit
733d01ed45
@ -1,4 +1,4 @@
|
|||||||
//===-- ARMUnwindOp.h - ARM Unwind Opcodes ----------------------*- C++ -*-===//
|
//===--- ARMEHABI.h - ARM Exception Handling ABI ----------------*- C++ -*-===//
|
||||||
//
|
//
|
||||||
// The LLVM Compiler Infrastructure
|
// The LLVM Compiler Infrastructure
|
||||||
//
|
//
|
||||||
@ -12,13 +12,14 @@
|
|||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#ifndef ARM_UNWIND_OP_H
|
#ifndef LLVM_SUPPORT_ARM_EHABI_H
|
||||||
#define ARM_UNWIND_OP_H
|
#define LLVM_SUPPORT_ARM_EHABI_H
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
namespace ARM {
|
||||||
|
namespace EHABI {
|
||||||
/// ARM exception handling table entry kinds
|
/// ARM exception handling table entry kinds
|
||||||
enum ARMEHTEntryKind {
|
enum EHTEntryKind {
|
||||||
EHT_GENERIC = 0x00,
|
EHT_GENERIC = 0x00,
|
||||||
EHT_COMPACT = 0x80
|
EHT_COMPACT = 0x80
|
||||||
};
|
};
|
||||||
@ -29,7 +30,7 @@ namespace llvm {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/// ARM-defined frame unwinding opcodes
|
/// ARM-defined frame unwinding opcodes
|
||||||
enum ARMUnwindOpcodes {
|
enum UnwindOpcodes {
|
||||||
// Format: 00xxxxxx
|
// Format: 00xxxxxx
|
||||||
// Purpose: vsp = vsp + ((x << 2) + 4)
|
// Purpose: vsp = vsp + ((x << 2) + 4)
|
||||||
UNWIND_OPCODE_INC_VSP = 0x00,
|
UNWIND_OPCODE_INC_VSP = 0x00,
|
||||||
@ -108,7 +109,7 @@ namespace llvm {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/// ARM-defined Personality Routine Index
|
/// ARM-defined Personality Routine Index
|
||||||
enum ARMPersonalityRoutineIndex {
|
enum PersonalityRoutineIndex {
|
||||||
// To make the exception handling table become more compact, ARM defined
|
// To make the exception handling table become more compact, ARM defined
|
||||||
// several personality routines in EHABI. There are 3 different
|
// several personality routines in EHABI. There are 3 different
|
||||||
// personality routines in ARM EHABI currently. It is possible to have 16
|
// personality routines in ARM EHABI currently. It is possible to have 16
|
||||||
@ -119,7 +120,8 @@ namespace llvm {
|
|||||||
|
|
||||||
NUM_PERSONALITY_INDEX
|
NUM_PERSONALITY_INDEX
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // ARM_UNWIND_OP_H
|
#endif // ARM_UNWIND_OP_H
|
@ -17,7 +17,6 @@
|
|||||||
#include "ARMArchName.h"
|
#include "ARMArchName.h"
|
||||||
#include "ARMFPUName.h"
|
#include "ARMFPUName.h"
|
||||||
#include "ARMRegisterInfo.h"
|
#include "ARMRegisterInfo.h"
|
||||||
#include "ARMUnwindOp.h"
|
|
||||||
#include "ARMUnwindOpAsm.h"
|
#include "ARMUnwindOpAsm.h"
|
||||||
#include "llvm/ADT/SmallPtrSet.h"
|
#include "llvm/ADT/SmallPtrSet.h"
|
||||||
#include "llvm/ADT/StringExtras.h"
|
#include "llvm/ADT/StringExtras.h"
|
||||||
@ -40,6 +39,7 @@
|
|||||||
#include "llvm/MC/MCStreamer.h"
|
#include "llvm/MC/MCStreamer.h"
|
||||||
#include "llvm/MC/MCSymbol.h"
|
#include "llvm/MC/MCSymbol.h"
|
||||||
#include "llvm/MC/MCValue.h"
|
#include "llvm/MC/MCValue.h"
|
||||||
|
#include "llvm/Support/ARMEHABI.h"
|
||||||
#include "llvm/Support/Debug.h"
|
#include "llvm/Support/Debug.h"
|
||||||
#include "llvm/Support/ELF.h"
|
#include "llvm/Support/ELF.h"
|
||||||
#include "llvm/Support/FormattedStream.h"
|
#include "llvm/Support/FormattedStream.h"
|
||||||
@ -49,7 +49,8 @@
|
|||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
static std::string GetAEABIUnwindPersonalityName(unsigned Index) {
|
static std::string GetAEABIUnwindPersonalityName(unsigned Index) {
|
||||||
assert(Index < NUM_PERSONALITY_INDEX && "Invalid personality index");
|
assert(Index < ARM::EHABI::NUM_PERSONALITY_INDEX &&
|
||||||
|
"Invalid personality index");
|
||||||
return (Twine("__aeabi_unwind_cpp_pr") + Twine(Index)).str();
|
return (Twine("__aeabi_unwind_cpp_pr") + Twine(Index)).str();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -909,7 +910,7 @@ void ARMELFStreamer::Reset() {
|
|||||||
ExTab = NULL;
|
ExTab = NULL;
|
||||||
FnStart = NULL;
|
FnStart = NULL;
|
||||||
Personality = NULL;
|
Personality = NULL;
|
||||||
PersonalityIndex = NUM_PERSONALITY_INDEX;
|
PersonalityIndex = ARM::EHABI::NUM_PERSONALITY_INDEX;
|
||||||
FPReg = ARM::SP;
|
FPReg = ARM::SP;
|
||||||
FPOffset = 0;
|
FPOffset = 0;
|
||||||
SPOffset = 0;
|
SPOffset = 0;
|
||||||
@ -937,7 +938,7 @@ void ARMELFStreamer::emitFnEnd() {
|
|||||||
// Emit the exception index table entry
|
// Emit the exception index table entry
|
||||||
SwitchToExIdxSection(*FnStart);
|
SwitchToExIdxSection(*FnStart);
|
||||||
|
|
||||||
if (PersonalityIndex < NUM_PERSONALITY_INDEX)
|
if (PersonalityIndex < ARM::EHABI::NUM_PERSONALITY_INDEX)
|
||||||
EmitPersonalityFixup(GetAEABIUnwindPersonalityName(PersonalityIndex));
|
EmitPersonalityFixup(GetAEABIUnwindPersonalityName(PersonalityIndex));
|
||||||
|
|
||||||
const MCSymbolRefExpr *FnStartRef =
|
const MCSymbolRefExpr *FnStartRef =
|
||||||
@ -948,7 +949,7 @@ void ARMELFStreamer::emitFnEnd() {
|
|||||||
EmitValue(FnStartRef, 4);
|
EmitValue(FnStartRef, 4);
|
||||||
|
|
||||||
if (CantUnwind) {
|
if (CantUnwind) {
|
||||||
EmitIntValue(EXIDX_CANTUNWIND, 4);
|
EmitIntValue(ARM::EHABI::EXIDX_CANTUNWIND, 4);
|
||||||
} else if (ExTab) {
|
} else if (ExTab) {
|
||||||
// Emit a reference to the unwind opcodes in the ".ARM.extab" section.
|
// Emit a reference to the unwind opcodes in the ".ARM.extab" section.
|
||||||
const MCSymbolRefExpr *ExTabEntryRef =
|
const MCSymbolRefExpr *ExTabEntryRef =
|
||||||
@ -960,7 +961,7 @@ void ARMELFStreamer::emitFnEnd() {
|
|||||||
// For the __aeabi_unwind_cpp_pr0, we have to emit the unwind opcodes in
|
// For the __aeabi_unwind_cpp_pr0, we have to emit the unwind opcodes in
|
||||||
// the second word of exception index table entry. The size of the unwind
|
// the second word of exception index table entry. The size of the unwind
|
||||||
// opcodes should always be 4 bytes.
|
// opcodes should always be 4 bytes.
|
||||||
assert(PersonalityIndex == AEABI_UNWIND_CPP_PR0 &&
|
assert(PersonalityIndex == ARM::EHABI::AEABI_UNWIND_CPP_PR0 &&
|
||||||
"Compact model must use __aeabi_cpp_unwind_pr0 as personality");
|
"Compact model must use __aeabi_cpp_unwind_pr0 as personality");
|
||||||
assert(Opcodes.size() == 4u &&
|
assert(Opcodes.size() == 4u &&
|
||||||
"Unwind opcode size for __aeabi_cpp_unwind_pr0 must be equal to 4");
|
"Unwind opcode size for __aeabi_cpp_unwind_pr0 must be equal to 4");
|
||||||
@ -1015,7 +1016,7 @@ void ARMELFStreamer::FlushUnwindOpcodes(bool NoHandlerData) {
|
|||||||
// For compact model 0, we have to emit the unwind opcodes in the .ARM.exidx
|
// For compact model 0, we have to emit the unwind opcodes in the .ARM.exidx
|
||||||
// section. Thus, we don't have to create an entry in the .ARM.extab
|
// section. Thus, we don't have to create an entry in the .ARM.extab
|
||||||
// section.
|
// section.
|
||||||
if (NoHandlerData && PersonalityIndex == AEABI_UNWIND_CPP_PR0)
|
if (NoHandlerData && PersonalityIndex == ARM::EHABI::AEABI_UNWIND_CPP_PR0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Switch to .ARM.extab section.
|
// Switch to .ARM.extab section.
|
||||||
|
@ -13,8 +13,7 @@
|
|||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#include "ARMUnwindOpAsm.h"
|
#include "ARMUnwindOpAsm.h"
|
||||||
|
#include "llvm/Support/ARMEHABI.h"
|
||||||
#include "ARMUnwindOp.h"
|
|
||||||
#include "llvm/Support/ErrorHandling.h"
|
#include "llvm/Support/ErrorHandling.h"
|
||||||
#include "llvm/Support/LEB128.h"
|
#include "llvm/Support/LEB128.h"
|
||||||
|
|
||||||
@ -50,14 +49,15 @@ namespace {
|
|||||||
|
|
||||||
/// Emit the personality index prefix.
|
/// Emit the personality index prefix.
|
||||||
inline void EmitPersonalityIndex(unsigned PI) {
|
inline void EmitPersonalityIndex(unsigned PI) {
|
||||||
assert(PI < NUM_PERSONALITY_INDEX && "Invalid personality prefix");
|
assert(PI < ARM::EHABI::NUM_PERSONALITY_INDEX &&
|
||||||
EmitByte(EHT_COMPACT | PI);
|
"Invalid personality prefix");
|
||||||
|
EmitByte(ARM::EHABI::EHT_COMPACT | PI);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Fill the rest of bytes with FINISH opcode.
|
/// Fill the rest of bytes with FINISH opcode.
|
||||||
inline void FillFinishOpcode() {
|
inline void FillFinishOpcode() {
|
||||||
while (Pos < Vec.size())
|
while (Pos < Vec.size())
|
||||||
EmitByte(UNWIND_OPCODE_FINISH);
|
EmitByte(ARM::EHABI::UNWIND_OPCODE_FINISH);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -85,22 +85,22 @@ void UnwindOpcodeAssembler::EmitRegSave(uint32_t RegSave) {
|
|||||||
uint32_t UnmaskedReg = RegSave & 0xfff0u & (~Mask);
|
uint32_t UnmaskedReg = RegSave & 0xfff0u & (~Mask);
|
||||||
if (UnmaskedReg == 0u) {
|
if (UnmaskedReg == 0u) {
|
||||||
// Pop r[4 : (4 + n)]
|
// Pop r[4 : (4 + n)]
|
||||||
EmitInt8(UNWIND_OPCODE_POP_REG_RANGE_R4 | Range);
|
EmitInt8(ARM::EHABI::UNWIND_OPCODE_POP_REG_RANGE_R4 | Range);
|
||||||
RegSave &= 0x000fu;
|
RegSave &= 0x000fu;
|
||||||
} else if (UnmaskedReg == (1u << 14)) {
|
} else if (UnmaskedReg == (1u << 14)) {
|
||||||
// Pop r[14] + r[4 : (4 + n)]
|
// Pop r[14] + r[4 : (4 + n)]
|
||||||
EmitInt8(UNWIND_OPCODE_POP_REG_RANGE_R4_R14 | Range);
|
EmitInt8(ARM::EHABI::UNWIND_OPCODE_POP_REG_RANGE_R4_R14 | Range);
|
||||||
RegSave &= 0x000fu;
|
RegSave &= 0x000fu;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Two bytes opcode to save register r15-r4
|
// Two bytes opcode to save register r15-r4
|
||||||
if ((RegSave & 0xfff0u) != 0)
|
if ((RegSave & 0xfff0u) != 0)
|
||||||
EmitInt16(UNWIND_OPCODE_POP_REG_MASK_R4 | (RegSave >> 4));
|
EmitInt16(ARM::EHABI::UNWIND_OPCODE_POP_REG_MASK_R4 | (RegSave >> 4));
|
||||||
|
|
||||||
// Opcode to save register r3-r0
|
// Opcode to save register r3-r0
|
||||||
if ((RegSave & 0x000fu) != 0)
|
if ((RegSave & 0x000fu) != 0)
|
||||||
EmitInt16(UNWIND_OPCODE_POP_REG_MASK | (RegSave & 0x000fu));
|
EmitInt16(ARM::EHABI::UNWIND_OPCODE_POP_REG_MASK | (RegSave & 0x000fu));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Emit unwind opcodes for .vsave directives
|
/// Emit unwind opcodes for .vsave directives
|
||||||
@ -125,7 +125,7 @@ void UnwindOpcodeAssembler::EmitVFPRegSave(uint32_t VFPRegSave) {
|
|||||||
Bit >>= 1;
|
Bit >>= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
EmitInt16(UNWIND_OPCODE_POP_VFP_REG_RANGE_FSTMFDD_D16 |
|
EmitInt16(ARM::EHABI::UNWIND_OPCODE_POP_VFP_REG_RANGE_FSTMFDD_D16 |
|
||||||
((i - 16) << 4) | Range);
|
((i - 16) << 4) | Range);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,34 +147,36 @@ void UnwindOpcodeAssembler::EmitVFPRegSave(uint32_t VFPRegSave) {
|
|||||||
Bit >>= 1;
|
Bit >>= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
EmitInt16(UNWIND_OPCODE_POP_VFP_REG_RANGE_FSTMFDD | (i << 4) | Range);
|
EmitInt16(ARM::EHABI::UNWIND_OPCODE_POP_VFP_REG_RANGE_FSTMFDD | (i << 4) |
|
||||||
|
Range);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Emit unwind opcodes to copy address from source register to $sp.
|
/// Emit unwind opcodes to copy address from source register to $sp.
|
||||||
void UnwindOpcodeAssembler::EmitSetSP(uint16_t Reg) {
|
void UnwindOpcodeAssembler::EmitSetSP(uint16_t Reg) {
|
||||||
EmitInt8(UNWIND_OPCODE_SET_VSP | Reg);
|
EmitInt8(ARM::EHABI::UNWIND_OPCODE_SET_VSP | Reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Emit unwind opcodes to add $sp with an offset.
|
/// Emit unwind opcodes to add $sp with an offset.
|
||||||
void UnwindOpcodeAssembler::EmitSPOffset(int64_t Offset) {
|
void UnwindOpcodeAssembler::EmitSPOffset(int64_t Offset) {
|
||||||
if (Offset > 0x200) {
|
if (Offset > 0x200) {
|
||||||
uint8_t Buff[16];
|
uint8_t Buff[16];
|
||||||
Buff[0] = UNWIND_OPCODE_INC_VSP_ULEB128;
|
Buff[0] = ARM::EHABI::UNWIND_OPCODE_INC_VSP_ULEB128;
|
||||||
size_t ULEBSize = encodeULEB128((Offset - 0x204) >> 2, Buff + 1);
|
size_t ULEBSize = encodeULEB128((Offset - 0x204) >> 2, Buff + 1);
|
||||||
EmitBytes(Buff, ULEBSize + 1);
|
EmitBytes(Buff, ULEBSize + 1);
|
||||||
} else if (Offset > 0) {
|
} else if (Offset > 0) {
|
||||||
if (Offset > 0x100) {
|
if (Offset > 0x100) {
|
||||||
EmitInt8(UNWIND_OPCODE_INC_VSP | 0x3fu);
|
EmitInt8(ARM::EHABI::UNWIND_OPCODE_INC_VSP | 0x3fu);
|
||||||
Offset -= 0x100;
|
Offset -= 0x100;
|
||||||
}
|
}
|
||||||
EmitInt8(UNWIND_OPCODE_INC_VSP | static_cast<uint8_t>((Offset - 4) >> 2));
|
EmitInt8(ARM::EHABI::UNWIND_OPCODE_INC_VSP |
|
||||||
|
static_cast<uint8_t>((Offset - 4) >> 2));
|
||||||
} else if (Offset < 0) {
|
} else if (Offset < 0) {
|
||||||
while (Offset < -0x100) {
|
while (Offset < -0x100) {
|
||||||
EmitInt8(UNWIND_OPCODE_DEC_VSP | 0x3fu);
|
EmitInt8(ARM::EHABI::UNWIND_OPCODE_DEC_VSP | 0x3fu);
|
||||||
Offset += 0x100;
|
Offset += 0x100;
|
||||||
}
|
}
|
||||||
EmitInt8(UNWIND_OPCODE_DEC_VSP |
|
EmitInt8(ARM::EHABI::UNWIND_OPCODE_DEC_VSP |
|
||||||
static_cast<uint8_t>(((-Offset) - 4) >> 2));
|
static_cast<uint8_t>(((-Offset) - 4) >> 2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -186,7 +188,7 @@ void UnwindOpcodeAssembler::Finalize(unsigned &PersonalityIndex,
|
|||||||
|
|
||||||
if (HasPersonality) {
|
if (HasPersonality) {
|
||||||
// User-specifed personality routine: [ SIZE , OP1 , OP2 , ... ]
|
// User-specifed personality routine: [ SIZE , OP1 , OP2 , ... ]
|
||||||
PersonalityIndex = NUM_PERSONALITY_INDEX;
|
PersonalityIndex = ARM::EHABI::NUM_PERSONALITY_INDEX;
|
||||||
size_t TotalSize = Ops.size() + 1;
|
size_t TotalSize = Ops.size() + 1;
|
||||||
size_t RoundUpSize = (TotalSize + 3) / 4 * 4;
|
size_t RoundUpSize = (TotalSize + 3) / 4 * 4;
|
||||||
Result.resize(RoundUpSize);
|
Result.resize(RoundUpSize);
|
||||||
@ -194,12 +196,12 @@ void UnwindOpcodeAssembler::Finalize(unsigned &PersonalityIndex,
|
|||||||
} else {
|
} else {
|
||||||
if (Ops.size() <= 3) {
|
if (Ops.size() <= 3) {
|
||||||
// __aeabi_unwind_cpp_pr0: [ 0x80 , OP1 , OP2 , OP3 ]
|
// __aeabi_unwind_cpp_pr0: [ 0x80 , OP1 , OP2 , OP3 ]
|
||||||
PersonalityIndex = AEABI_UNWIND_CPP_PR0;
|
PersonalityIndex = ARM::EHABI::AEABI_UNWIND_CPP_PR0;
|
||||||
Result.resize(4);
|
Result.resize(4);
|
||||||
OpStreamer.EmitPersonalityIndex(PersonalityIndex);
|
OpStreamer.EmitPersonalityIndex(PersonalityIndex);
|
||||||
} else {
|
} else {
|
||||||
// __aeabi_unwind_cpp_pr1: [ 0x81 , SIZE , OP1 , OP2 , ... ]
|
// __aeabi_unwind_cpp_pr1: [ 0x81 , SIZE , OP1 , OP2 , ... ]
|
||||||
PersonalityIndex = AEABI_UNWIND_CPP_PR1;
|
PersonalityIndex = ARM::EHABI::AEABI_UNWIND_CPP_PR1;
|
||||||
size_t TotalSize = Ops.size() + 2;
|
size_t TotalSize = Ops.size() + 2;
|
||||||
size_t RoundUpSize = (TotalSize + 3) / 4 * 4;
|
size_t RoundUpSize = (TotalSize + 3) / 4 * 4;
|
||||||
Result.resize(RoundUpSize);
|
Result.resize(RoundUpSize);
|
||||||
|
@ -15,10 +15,9 @@
|
|||||||
#ifndef ARM_UNWIND_OP_ASM_H
|
#ifndef ARM_UNWIND_OP_ASM_H
|
||||||
#define ARM_UNWIND_OP_ASM_H
|
#define ARM_UNWIND_OP_ASM_H
|
||||||
|
|
||||||
#include "ARMUnwindOp.h"
|
|
||||||
|
|
||||||
#include "llvm/ADT/SmallVector.h"
|
#include "llvm/ADT/SmallVector.h"
|
||||||
#include "llvm/ADT/StringRef.h"
|
#include "llvm/ADT/StringRef.h"
|
||||||
|
#include "llvm/Support/ARMEHABI.h"
|
||||||
#include "llvm/Support/DataTypes.h"
|
#include "llvm/Support/DataTypes.h"
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
Loading…
Reference in New Issue
Block a user