mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-11-06 04:18:00 +00:00
MC: make MCWin64EHInstruction a POD-like struct
This is the first of a number of changes designed to generalise MCWin64EHInstruction to support different target architectures. An ordered set (vector) of these instructions is saved per frame to permit the emission of information for Windows NT style unwinding. The only bit of information which is actually target specific here is the Opcode for the unwinding bytecode. The remainder of the information is simply generic information that is relevant to the Windows NT unwinding model. Remove the accessors for the fields, making them const and public instead. Sink the knowledge of the alias'ed name into the single source and sink a single-use check method into the use. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@212914 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -24,41 +24,37 @@ namespace llvm {
|
|||||||
class MCStreamer;
|
class MCStreamer;
|
||||||
class MCSymbol;
|
class MCSymbol;
|
||||||
|
|
||||||
class MCWin64EHInstruction {
|
struct MCWin64EHInstruction {
|
||||||
public:
|
typedef Win64EH::UnwindOpcodes OpType;
|
||||||
typedef Win64EH::UnwindOpcodes OpType;
|
const OpType Operation;
|
||||||
private:
|
const MCSymbol *Label;
|
||||||
OpType Operation;
|
const unsigned Offset;
|
||||||
MCSymbol *Label;
|
const unsigned Register;
|
||||||
unsigned Offset;
|
|
||||||
unsigned Register;
|
MCWin64EHInstruction(OpType Op, MCSymbol *L, unsigned Reg)
|
||||||
public:
|
|
||||||
MCWin64EHInstruction(OpType Op, MCSymbol *L, unsigned Reg)
|
|
||||||
: Operation(Op), Label(L), Offset(0), Register(Reg) {
|
: Operation(Op), Label(L), Offset(0), Register(Reg) {
|
||||||
assert(Op == Win64EH::UOP_PushNonVol);
|
assert(Op == Win64EH::UOP_PushNonVol);
|
||||||
}
|
}
|
||||||
MCWin64EHInstruction(MCSymbol *L, unsigned Size)
|
|
||||||
: Operation(Size>128 ? Win64EH::UOP_AllocLarge : Win64EH::UOP_AllocSmall),
|
MCWin64EHInstruction(MCSymbol *L, unsigned Size)
|
||||||
Label(L), Offset(Size) { }
|
: Operation(Size > 128 ? Win64EH::UOP_AllocLarge
|
||||||
MCWin64EHInstruction(OpType Op, MCSymbol *L, unsigned Reg, unsigned Off)
|
: Win64EH::UOP_AllocSmall),
|
||||||
|
Label(L), Offset(Size), Register(-1) {}
|
||||||
|
|
||||||
|
MCWin64EHInstruction(OpType Op, MCSymbol *L, unsigned Reg, unsigned Off)
|
||||||
: Operation(Op), Label(L), Offset(Off), Register(Reg) {
|
: Operation(Op), Label(L), Offset(Off), Register(Reg) {
|
||||||
assert(Op == Win64EH::UOP_SetFPReg ||
|
assert(Op == Win64EH::UOP_SetFPReg ||
|
||||||
Op == Win64EH::UOP_SaveNonVol ||
|
Op == Win64EH::UOP_SaveNonVol ||
|
||||||
Op == Win64EH::UOP_SaveNonVolBig ||
|
Op == Win64EH::UOP_SaveNonVolBig ||
|
||||||
Op == Win64EH::UOP_SaveXMM128 ||
|
Op == Win64EH::UOP_SaveXMM128 ||
|
||||||
Op == Win64EH::UOP_SaveXMM128Big);
|
Op == Win64EH::UOP_SaveXMM128Big);
|
||||||
}
|
}
|
||||||
MCWin64EHInstruction(OpType Op, MCSymbol *L, bool Code)
|
|
||||||
: Operation(Op), Label(L), Offset(Code ? 1 : 0) {
|
MCWin64EHInstruction(OpType Op, MCSymbol *L, bool Code)
|
||||||
assert(Op == Win64EH::UOP_PushMachFrame);
|
: Operation(Op), Label(L), Offset(Code ? 1 : 0), Register(-1) {
|
||||||
}
|
assert(Op == Win64EH::UOP_PushMachFrame);
|
||||||
OpType getOperation() const { return Operation; }
|
}
|
||||||
MCSymbol *getLabel() const { return Label; }
|
};
|
||||||
unsigned getOffset() const { return Offset; }
|
|
||||||
unsigned getSize() const { return Offset; }
|
|
||||||
unsigned getRegister() const { return Register; }
|
|
||||||
bool isPushCodeFrame() const { return Offset == 1; }
|
|
||||||
};
|
|
||||||
|
|
||||||
struct MCWinFrameInfo {
|
struct MCWinFrameInfo {
|
||||||
MCWinFrameInfo()
|
MCWinFrameInfo()
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ namespace llvm {
|
|||||||
static uint8_t CountOfUnwindCodes(std::vector<MCWin64EHInstruction> &Insns) {
|
static uint8_t CountOfUnwindCodes(std::vector<MCWin64EHInstruction> &Insns) {
|
||||||
uint8_t Count = 0;
|
uint8_t Count = 0;
|
||||||
for (const auto &I : Insns) {
|
for (const auto &I : Insns) {
|
||||||
switch (I.getOperation()) {
|
switch (I.Operation) {
|
||||||
case Win64EH::UOP_PushNonVol:
|
case Win64EH::UOP_PushNonVol:
|
||||||
case Win64EH::UOP_AllocSmall:
|
case Win64EH::UOP_AllocSmall:
|
||||||
case Win64EH::UOP_SetFPReg:
|
case Win64EH::UOP_SetFPReg:
|
||||||
@@ -39,7 +39,7 @@ static uint8_t CountOfUnwindCodes(std::vector<MCWin64EHInstruction> &Insns) {
|
|||||||
Count += 3;
|
Count += 3;
|
||||||
break;
|
break;
|
||||||
case Win64EH::UOP_AllocLarge:
|
case Win64EH::UOP_AllocLarge:
|
||||||
Count += (I.getSize() > 512 * 1024 - 8) ? 3 : 2;
|
Count += (I.Offset > 512 * 1024 - 8) ? 3 : 2;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -59,63 +59,63 @@ static void EmitUnwindCode(MCStreamer &streamer, MCSymbol *begin,
|
|||||||
MCWin64EHInstruction &inst) {
|
MCWin64EHInstruction &inst) {
|
||||||
uint8_t b2;
|
uint8_t b2;
|
||||||
uint16_t w;
|
uint16_t w;
|
||||||
b2 = (inst.getOperation() & 0x0F);
|
b2 = (inst.Operation & 0x0F);
|
||||||
switch (inst.getOperation()) {
|
switch (inst.Operation) {
|
||||||
case Win64EH::UOP_PushNonVol:
|
case Win64EH::UOP_PushNonVol:
|
||||||
EmitAbsDifference(streamer, inst.getLabel(), begin);
|
EmitAbsDifference(streamer, inst.Label, begin);
|
||||||
b2 |= (inst.getRegister() & 0x0F) << 4;
|
b2 |= (inst.Register & 0x0F) << 4;
|
||||||
streamer.EmitIntValue(b2, 1);
|
streamer.EmitIntValue(b2, 1);
|
||||||
break;
|
break;
|
||||||
case Win64EH::UOP_AllocLarge:
|
case Win64EH::UOP_AllocLarge:
|
||||||
EmitAbsDifference(streamer, inst.getLabel(), begin);
|
EmitAbsDifference(streamer, inst.Label, begin);
|
||||||
if (inst.getSize() > 512*1024-8) {
|
if (inst.Offset > 512 * 1024 - 8) {
|
||||||
b2 |= 0x10;
|
b2 |= 0x10;
|
||||||
streamer.EmitIntValue(b2, 1);
|
streamer.EmitIntValue(b2, 1);
|
||||||
w = inst.getSize() & 0xFFF8;
|
w = inst.Offset & 0xFFF8;
|
||||||
streamer.EmitIntValue(w, 2);
|
streamer.EmitIntValue(w, 2);
|
||||||
w = inst.getSize() >> 16;
|
w = inst.Offset >> 16;
|
||||||
} else {
|
} else {
|
||||||
streamer.EmitIntValue(b2, 1);
|
streamer.EmitIntValue(b2, 1);
|
||||||
w = inst.getSize() >> 3;
|
w = inst.Offset >> 3;
|
||||||
}
|
}
|
||||||
streamer.EmitIntValue(w, 2);
|
streamer.EmitIntValue(w, 2);
|
||||||
break;
|
break;
|
||||||
case Win64EH::UOP_AllocSmall:
|
case Win64EH::UOP_AllocSmall:
|
||||||
b2 |= (((inst.getSize()-8) >> 3) & 0x0F) << 4;
|
b2 |= (((inst.Offset - 8) >> 3) & 0x0F) << 4;
|
||||||
EmitAbsDifference(streamer, inst.getLabel(), begin);
|
EmitAbsDifference(streamer, inst.Label, begin);
|
||||||
streamer.EmitIntValue(b2, 1);
|
streamer.EmitIntValue(b2, 1);
|
||||||
break;
|
break;
|
||||||
case Win64EH::UOP_SetFPReg:
|
case Win64EH::UOP_SetFPReg:
|
||||||
EmitAbsDifference(streamer, inst.getLabel(), begin);
|
EmitAbsDifference(streamer, inst.Label, begin);
|
||||||
streamer.EmitIntValue(b2, 1);
|
streamer.EmitIntValue(b2, 1);
|
||||||
break;
|
break;
|
||||||
case Win64EH::UOP_SaveNonVol:
|
case Win64EH::UOP_SaveNonVol:
|
||||||
case Win64EH::UOP_SaveXMM128:
|
case Win64EH::UOP_SaveXMM128:
|
||||||
b2 |= (inst.getRegister() & 0x0F) << 4;
|
b2 |= (inst.Register & 0x0F) << 4;
|
||||||
EmitAbsDifference(streamer, inst.getLabel(), begin);
|
EmitAbsDifference(streamer, inst.Label, begin);
|
||||||
streamer.EmitIntValue(b2, 1);
|
streamer.EmitIntValue(b2, 1);
|
||||||
w = inst.getOffset() >> 3;
|
w = inst.Offset >> 3;
|
||||||
if (inst.getOperation() == Win64EH::UOP_SaveXMM128)
|
if (inst.Operation == Win64EH::UOP_SaveXMM128)
|
||||||
w >>= 1;
|
w >>= 1;
|
||||||
streamer.EmitIntValue(w, 2);
|
streamer.EmitIntValue(w, 2);
|
||||||
break;
|
break;
|
||||||
case Win64EH::UOP_SaveNonVolBig:
|
case Win64EH::UOP_SaveNonVolBig:
|
||||||
case Win64EH::UOP_SaveXMM128Big:
|
case Win64EH::UOP_SaveXMM128Big:
|
||||||
b2 |= (inst.getRegister() & 0x0F) << 4;
|
b2 |= (inst.Register & 0x0F) << 4;
|
||||||
EmitAbsDifference(streamer, inst.getLabel(), begin);
|
EmitAbsDifference(streamer, inst.Label, begin);
|
||||||
streamer.EmitIntValue(b2, 1);
|
streamer.EmitIntValue(b2, 1);
|
||||||
if (inst.getOperation() == Win64EH::UOP_SaveXMM128Big)
|
if (inst.Operation == Win64EH::UOP_SaveXMM128Big)
|
||||||
w = inst.getOffset() & 0xFFF0;
|
w = inst.Offset & 0xFFF0;
|
||||||
else
|
else
|
||||||
w = inst.getOffset() & 0xFFF8;
|
w = inst.Offset & 0xFFF8;
|
||||||
streamer.EmitIntValue(w, 2);
|
streamer.EmitIntValue(w, 2);
|
||||||
w = inst.getOffset() >> 16;
|
w = inst.Offset >> 16;
|
||||||
streamer.EmitIntValue(w, 2);
|
streamer.EmitIntValue(w, 2);
|
||||||
break;
|
break;
|
||||||
case Win64EH::UOP_PushMachFrame:
|
case Win64EH::UOP_PushMachFrame:
|
||||||
if (inst.isPushCodeFrame())
|
if (inst.Offset == 1)
|
||||||
b2 |= 0x10;
|
b2 |= 0x10;
|
||||||
EmitAbsDifference(streamer, inst.getLabel(), begin);
|
EmitAbsDifference(streamer, inst.Label, begin);
|
||||||
streamer.EmitIntValue(b2, 1);
|
streamer.EmitIntValue(b2, 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -178,9 +178,8 @@ static void EmitUnwindInfo(MCStreamer &streamer, MCWinFrameInfo *info) {
|
|||||||
uint8_t frame = 0;
|
uint8_t frame = 0;
|
||||||
if (info->LastFrameInst >= 0) {
|
if (info->LastFrameInst >= 0) {
|
||||||
MCWin64EHInstruction &frameInst = info->Instructions[info->LastFrameInst];
|
MCWin64EHInstruction &frameInst = info->Instructions[info->LastFrameInst];
|
||||||
assert(frameInst.getOperation() == Win64EH::UOP_SetFPReg);
|
assert(frameInst.Operation == Win64EH::UOP_SetFPReg);
|
||||||
frame = (frameInst.getRegister() & 0x0F) |
|
frame = (frameInst.Register & 0x0F) | (frameInst.Offset & 0xF0);
|
||||||
(frameInst.getOffset() & 0xF0);
|
|
||||||
}
|
}
|
||||||
streamer.EmitIntValue(frame, 1);
|
streamer.EmitIntValue(frame, 1);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user