mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-06-13 22:24:07 +00:00
Change indirect-globals to use a dedicated allocIndirectGV. This lets us
remove start/finishGVStub and the BufferState helper class from the MachineCodeEmitter interface. It has the side-effect of not setting the indirect global writable and then executable on ARM, but that shouldn't be necessary. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@91464 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@ -68,29 +68,11 @@ public:
|
||||
///
|
||||
virtual bool finishFunction(MachineFunction &F) = 0;
|
||||
|
||||
/// startGVStub - This callback is invoked when the JIT needs the address of a
|
||||
/// GV (e.g. function) that has not been code generated yet. The StubSize
|
||||
/// specifies the total size required by the stub. The BufferState must be
|
||||
/// passed to finishGVStub, and start/finish pairs with the same BufferState
|
||||
/// must be properly nested.
|
||||
///
|
||||
virtual void startGVStub(BufferState &BS, const GlobalValue* GV,
|
||||
unsigned StubSize, unsigned Alignment = 1) = 0;
|
||||
|
||||
/// startGVStub - This callback is invoked when the JIT needs the address of a
|
||||
/// GV (e.g. function) that has not been code generated yet. Buffer points to
|
||||
/// memory already allocated for this stub. The BufferState must be passed to
|
||||
/// finishGVStub, and start/finish pairs with the same BufferState must be
|
||||
/// properly nested.
|
||||
///
|
||||
virtual void startGVStub(BufferState &BS, void *Buffer,
|
||||
unsigned StubSize) = 0;
|
||||
|
||||
/// finishGVStub - This callback is invoked to terminate a GV stub and returns
|
||||
/// the start address of the stub. The BufferState must first have been
|
||||
/// passed to startGVStub.
|
||||
///
|
||||
virtual void *finishGVStub(BufferState &BS) = 0;
|
||||
/// allocIndirectGV - Allocates and fills storage for an indirect
|
||||
/// GlobalValue, and returns the address.
|
||||
virtual void *allocIndirectGV(const GlobalValue *GV,
|
||||
const uint8_t *Buffer, size_t Size,
|
||||
unsigned Alignment) = 0;
|
||||
|
||||
/// emitByte - This callback is invoked when a byte needs to be written to the
|
||||
/// output stream.
|
||||
|
@ -48,41 +48,16 @@ class Function;
|
||||
/// occurred, more memory is allocated, and we reemit the code into it.
|
||||
///
|
||||
class MachineCodeEmitter {
|
||||
public:
|
||||
class BufferState {
|
||||
friend class MachineCodeEmitter;
|
||||
/// BufferBegin/BufferEnd - Pointers to the start and end of the memory
|
||||
/// allocated for this code buffer.
|
||||
uint8_t *BufferBegin, *BufferEnd;
|
||||
|
||||
/// CurBufferPtr - Pointer to the next byte of memory to fill when emitting
|
||||
/// code. This is guranteed to be in the range [BufferBegin,BufferEnd]. If
|
||||
/// this pointer is at BufferEnd, it will never move due to code emission,
|
||||
/// and all code emission requests will be ignored (this is the buffer
|
||||
/// overflow condition).
|
||||
uint8_t *CurBufferPtr;
|
||||
public:
|
||||
BufferState() : BufferBegin(NULL), BufferEnd(NULL), CurBufferPtr(NULL) {}
|
||||
};
|
||||
|
||||
protected:
|
||||
/// These have the same meanings as the fields in BufferState
|
||||
uint8_t *BufferBegin, *BufferEnd, *CurBufferPtr;
|
||||
|
||||
/// Save or restore the current buffer state. The BufferState objects must be
|
||||
/// used as a stack.
|
||||
void SaveStateTo(BufferState &BS) {
|
||||
assert(BS.BufferBegin == NULL &&
|
||||
"Can't save state into the same BufferState twice.");
|
||||
BS.BufferBegin = BufferBegin;
|
||||
BS.BufferEnd = BufferEnd;
|
||||
BS.CurBufferPtr = CurBufferPtr;
|
||||
}
|
||||
void RestoreStateFrom(BufferState &BS) {
|
||||
BufferBegin = BS.BufferBegin;
|
||||
BufferEnd = BS.BufferEnd;
|
||||
CurBufferPtr = BS.CurBufferPtr;
|
||||
}
|
||||
/// BufferBegin/BufferEnd - Pointers to the start and end of the memory
|
||||
/// allocated for this code buffer.
|
||||
uint8_t *BufferBegin, *BufferEnd;
|
||||
/// CurBufferPtr - Pointer to the next byte of memory to fill when emitting
|
||||
/// code. This is guranteed to be in the range [BufferBegin,BufferEnd]. If
|
||||
/// this pointer is at BufferEnd, it will never move due to code emission, and
|
||||
/// all code emission requests will be ignored (this is the buffer overflow
|
||||
/// condition).
|
||||
uint8_t *CurBufferPtr;
|
||||
|
||||
public:
|
||||
virtual ~MachineCodeEmitter() {}
|
||||
@ -113,15 +88,23 @@ public:
|
||||
///
|
||||
void emitWordLE(uint32_t W) {
|
||||
if (4 <= BufferEnd-CurBufferPtr) {
|
||||
*CurBufferPtr++ = (uint8_t)(W >> 0);
|
||||
*CurBufferPtr++ = (uint8_t)(W >> 8);
|
||||
*CurBufferPtr++ = (uint8_t)(W >> 16);
|
||||
*CurBufferPtr++ = (uint8_t)(W >> 24);
|
||||
emitWordLEInto(CurBufferPtr, W);
|
||||
} else {
|
||||
CurBufferPtr = BufferEnd;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// emitWordLEInto - This callback is invoked when a 32-bit word needs to be
|
||||
/// written to an arbitrary buffer in little-endian format. Buf must have at
|
||||
/// least 4 bytes of available space.
|
||||
///
|
||||
static void emitWordLEInto(uint8_t *&Buf, uint32_t W) {
|
||||
*Buf++ = (uint8_t)(W >> 0);
|
||||
*Buf++ = (uint8_t)(W >> 8);
|
||||
*Buf++ = (uint8_t)(W >> 16);
|
||||
*Buf++ = (uint8_t)(W >> 24);
|
||||
}
|
||||
|
||||
/// emitWordBE - This callback is invoked when a 32-bit word needs to be
|
||||
/// written to the output stream in big-endian format.
|
||||
///
|
||||
|
Reference in New Issue
Block a user