mirror of
https://github.com/FEX-Emu/vixl.git
synced 2024-11-23 06:29:49 +00:00
AArch32: allow literals' update
Numerical literals can now be updated even after being emitted. Change-Id: Ief50bac9079bb8c89c800c911ce6eb93a43ffd0e
This commit is contained in:
parent
97a5640aed
commit
3e1b899f48
@ -35,6 +35,7 @@ extern "C" {
|
||||
#include <ostream>
|
||||
|
||||
#include "utils-vixl.h"
|
||||
#include "code-buffer-vixl.h"
|
||||
#include "aarch32/constants-aarch32.h"
|
||||
#include "aarch32/label-aarch32.h"
|
||||
|
||||
@ -1355,6 +1356,12 @@ class Literal : public RawLiteral {
|
||||
explicit Literal(const T& value,
|
||||
DeletionPolicy deletion_policy = kManuallyDeleted)
|
||||
: RawLiteral(&value_, sizeof(T), deletion_policy), value_(value) {}
|
||||
void UpdateValue(const T& value, CodeBuffer* buffer) {
|
||||
value_ = value;
|
||||
if (IsBound()) {
|
||||
buffer->UpdateData(GetLocation(), GetDataAddress(), GetSize());
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
T value_;
|
||||
|
@ -84,6 +84,14 @@ void CodeBuffer::EmitData(const void* data, size_t size) {
|
||||
}
|
||||
|
||||
|
||||
void CodeBuffer::UpdateData(size_t offset, const void* data, size_t size) {
|
||||
dirty_ = true;
|
||||
byte* dst = buffer_ + offset;
|
||||
VIXL_ASSERT(dst + size <= cursor_);
|
||||
memcpy(dst, data, size);
|
||||
}
|
||||
|
||||
|
||||
void CodeBuffer::Align() {
|
||||
byte* end = AlignUp(cursor_, 4);
|
||||
VIXL_ASSERT(end >= cursor_);
|
||||
|
@ -107,6 +107,8 @@ class CodeBuffer {
|
||||
|
||||
void EmitData(const void* data, size_t size);
|
||||
|
||||
void UpdateData(size_t offset, const void* data, size_t size);
|
||||
|
||||
// Align to 32bit.
|
||||
void Align();
|
||||
|
||||
|
@ -1266,6 +1266,53 @@ TEST(veneers_labels_sort) {
|
||||
}
|
||||
|
||||
|
||||
// This test check that we can update a Literal after usage.
|
||||
TEST(literal_update) {
|
||||
SETUP();
|
||||
|
||||
START();
|
||||
Label exit;
|
||||
Literal<uint32_t>* a32 =
|
||||
new Literal<uint32_t>(0xabcdef01, RawLiteral::kDeletedOnPoolDestruction);
|
||||
Literal<uint64_t>* a64 =
|
||||
new Literal<uint64_t>(
|
||||
UINT64_C(0xabcdef01abcdef01), RawLiteral::kDeletedOnPoolDestruction);
|
||||
__ AddLiteral(a32);
|
||||
__ AddLiteral(a64);
|
||||
__ Ldr(r0, a32);
|
||||
__ Ldrd(r2, r3, a64);
|
||||
__ EmitLiteralPool();
|
||||
Literal<uint32_t>* b32 =
|
||||
new Literal<uint32_t>(0x10fedcba, RawLiteral::kDeletedOnPoolDestruction);
|
||||
Literal<uint64_t>* b64 =
|
||||
new Literal<uint64_t>(
|
||||
UINT64_C(0x10fedcba10fedcba), RawLiteral::kDeletedOnPoolDestruction);
|
||||
__ AddLiteral(b32);
|
||||
__ AddLiteral(b64);
|
||||
__ Ldr(r1, b32);
|
||||
__ Ldrd(r4, r5, b64);
|
||||
// Update literals' values. "a32" and "a64" are already emitted. "b32" and
|
||||
// "b64" will only be emitted when "END()" will be called.
|
||||
a32->UpdateValue(0x12345678, &masm.GetBuffer());
|
||||
a64->UpdateValue(UINT64_C(0x13579bdf02468ace), &masm.GetBuffer());
|
||||
b32->UpdateValue(0x87654321, &masm.GetBuffer());
|
||||
b64->UpdateValue(UINT64_C(0x1032547698badcfe), &masm.GetBuffer());
|
||||
END();
|
||||
|
||||
RUN();
|
||||
|
||||
PrintDisassembler dis(std::cout, 0);
|
||||
dis.DisassembleA32Buffer(
|
||||
masm.GetBuffer().GetOffsetAddress<uint32_t*>(0), masm.GetCursorOffset());
|
||||
ASSERT_EQUAL_32(0x12345678, r0);
|
||||
ASSERT_EQUAL_32(0x87654321, r1);
|
||||
ASSERT_EQUAL_32(0x13579bdf, r2);
|
||||
ASSERT_EQUAL_32(0x02468ace, r3);
|
||||
ASSERT_EQUAL_32(0x10325476, r4);
|
||||
ASSERT_EQUAL_32(0x98badcfe, r5);
|
||||
}
|
||||
|
||||
|
||||
void SwitchCase(JumpTableBase* switch_, uint32_t case_index,
|
||||
bool is_using_t32) {
|
||||
SETUP();
|
||||
|
Loading…
Reference in New Issue
Block a user