summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/lib/Target/ARM/MCTargetDesc/ARMUnwindOpAsm.h
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/lib/Target/ARM/MCTargetDesc/ARMUnwindOpAsm.h')
-rw-r--r--contrib/llvm/lib/Target/ARM/MCTargetDesc/ARMUnwindOpAsm.h73
1 files changed, 24 insertions, 49 deletions
diff --git a/contrib/llvm/lib/Target/ARM/MCTargetDesc/ARMUnwindOpAsm.h b/contrib/llvm/lib/Target/ARM/MCTargetDesc/ARMUnwindOpAsm.h
index f6ecaeb..ac67c6e 100644
--- a/contrib/llvm/lib/Target/ARM/MCTargetDesc/ARMUnwindOpAsm.h
+++ b/contrib/llvm/lib/Target/ARM/MCTargetDesc/ARMUnwindOpAsm.h
@@ -27,86 +27,61 @@ class MCSymbol;
class UnwindOpcodeAssembler {
private:
- llvm::SmallVector<uint8_t, 8> Ops;
-
- unsigned Offset;
- unsigned PersonalityIndex;
+ llvm::SmallVector<uint8_t, 32> Ops;
+ llvm::SmallVector<unsigned, 8> OpBegins;
bool HasPersonality;
- enum {
- // The number of bytes to be preserved for the size and personality index
- // prefix of unwind opcodes.
- NUM_PRESERVED_PREFIX_BUF = 2
- };
-
public:
UnwindOpcodeAssembler()
- : Ops(NUM_PRESERVED_PREFIX_BUF), Offset(NUM_PRESERVED_PREFIX_BUF),
- PersonalityIndex(NUM_PERSONALITY_INDEX), HasPersonality(0) {
+ : HasPersonality(0) {
+ OpBegins.push_back(0);
}
/// Reset the unwind opcode assembler.
void Reset() {
- Ops.resize(NUM_PRESERVED_PREFIX_BUF);
- Offset = NUM_PRESERVED_PREFIX_BUF;
- PersonalityIndex = NUM_PERSONALITY_INDEX;
+ Ops.clear();
+ OpBegins.clear();
+ OpBegins.push_back(0);
HasPersonality = 0;
}
- /// Get the size of the payload (including the size byte)
- size_t size() const {
- return Ops.size() - Offset;
- }
-
- /// Get the beginning of the payload
- const uint8_t *begin() const {
- return Ops.begin() + Offset;
- }
-
- /// Get the payload
- StringRef data() const {
- return StringRef(reinterpret_cast<const char *>(begin()), size());
- }
-
/// Set the personality index
void setPersonality(const MCSymbol *Per) {
HasPersonality = 1;
}
- /// Get the personality index
- unsigned getPersonalityIndex() const {
- return PersonalityIndex;
- }
-
/// Emit unwind opcodes for .save directives
void EmitRegSave(uint32_t RegSave);
/// Emit unwind opcodes for .vsave directives
void EmitVFPRegSave(uint32_t VFPRegSave);
- /// Emit unwind opcodes for .setfp directives
- void EmitSetFP(uint16_t FPReg);
+ /// Emit unwind opcodes to copy address from source register to $sp.
+ void EmitSetSP(uint16_t Reg);
- /// Emit unwind opcodes to update stack pointer
+ /// Emit unwind opcodes to add $sp with an offset.
void EmitSPOffset(int64_t Offset);
/// Finalize the unwind opcode sequence for EmitBytes()
- void Finalize();
+ void Finalize(unsigned &PersonalityIndex,
+ SmallVectorImpl<uint8_t> &Result);
private:
- /// Get the size of the opcodes in bytes.
- size_t getOpcodeSize() const {
- return Ops.size() - NUM_PRESERVED_PREFIX_BUF;
+ void EmitInt8(unsigned Opcode) {
+ Ops.push_back(Opcode & 0xff);
+ OpBegins.push_back(OpBegins.back() + 1);
}
- /// Add the length prefix to the payload
- void AddOpcodeSizePrefix(size_t Pos);
-
- /// Add personality index prefix in some compact format
- void AddPersonalityIndexPrefix(size_t Pos, unsigned PersonalityIndex);
+ void EmitInt16(unsigned Opcode) {
+ Ops.push_back((Opcode >> 8) & 0xff);
+ Ops.push_back(Opcode & 0xff);
+ OpBegins.push_back(OpBegins.back() + 2);
+ }
- /// Fill the words with finish opcode if it is not aligned
- void EmitFinishOpcodes();
+ void EmitBytes(const uint8_t *Opcode, size_t Size) {
+ Ops.insert(Ops.end(), Opcode, Opcode + Size);
+ OpBegins.push_back(OpBegins.back() + Size);
+ }
};
} // namespace llvm
OpenPOWER on IntegriCloud