https://github.com/pent0/arme
Last synced: 7 months ago
JSON representation
- Host: GitHub
- URL: https://github.com/pent0/arme
- Owner: pent0
- Created: 2018-11-25T18:22:26.000Z (over 7 years ago)
- Default Branch: master
- Last Pushed: 2018-12-08T04:39:59.000Z (over 7 years ago)
- Last Synced: 2025-01-30T00:27:15.543Z (over 1 year ago)
- Language: C++
- Size: 11.1 MB
- Stars: 1
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
ARM2ARM recompiler for melonds
I work on this with my UWP port. Please try to compile Capstone with ARM only and as C++ code.
Incomplete instructions emitter, will work on soon, but Dynarmic example kinda works.
Small example that works:
```cpp
#include
struct callback_data
{
std::array memory;
std::uint32_t ticks_left;
};
static void write_memory8(void *userdata, arme::address addr, std::uint8_t w)
{
callback_data *data = reinterpret_cast(userdata);
data->memory[addr] = w;
}
static void write_memory16(void *userdata, arme::address addr, std::uint16_t w)
{
callback_data *data = reinterpret_cast(userdata);
*reinterpret_cast(&(data->memory[addr])) = w;
}
static void write_memory32(void *userdata, arme::address addr, std::uint32_t w)
{
callback_data *data = reinterpret_cast(userdata);
*reinterpret_cast(&(data->memory[addr])) = w;
}
static std::uint8_t read_memory8(void *userdata, arme::address addr)
{
callback_data *data = reinterpret_cast(userdata);
return data->memory[addr];
}
static std::uint16_t read_memory16(void *userdata, arme::address addr)
{
callback_data *data = reinterpret_cast(userdata);
return *reinterpret_cast(&(data->memory[addr]));
}
static std::uint32_t read_memory32(void *userdata, arme::address addr)
{
callback_data *data = reinterpret_cast(userdata);
return *reinterpret_cast(&(data->memory[addr]));
}
static void add_ticks(void *userdata, std::uint32_t ticks)
{
callback_data *data = reinterpret_cast(userdata);
if (ticks > data->ticks_left) {
data->ticks_left = 0;
return;
}
data->ticks_left -= ticks;
}
static std::uint32_t get_remaining_ticks(void *userdata)
{
callback_data *data = reinterpret_cast(userdata);
return data->ticks_left;
}
int main()
{
callback_data cbd;
arme::jit_callback callback;
callback.write_mem16 = write_memory16;
callback.write_mem32 = write_memory32;
callback.write_mem8 = write_memory8;
callback.read_mem16 = read_memory16;
callback.read_mem32 = read_memory32;
callback.read_mem8 = read_memory8;
callback.userdata = &cbd;
callback.add_cycles = add_ticks;
callback.get_remaining_cycles = get_remaining_ticks;
cbd.ticks_left = 1;
arme::jit dejit{ callback };
dejit.state.regs[15] = 0;
dejit.state.regs[0] = 1;
dejit.state.regs[1] = 2;
write_memory32(&cbd, 0, 0xE0811000); // ADD r0, r0, r1
write_memory32(&cbd, 4, 0xEA000000); // B +-0
dejit.execute();
assert((dejit.state.regs[0] == 3) && "Unexpected value");
}
```
The JIT supported the following architecture:
- Guest: ARMv4, ARMv3
- Host: ARMv5 and upper
Support:
- Low level exception handling: specify the exception base address in jit state.
- Varies of function callback: writing callback function in static C function with userdata available!
- Switching execution mode: between SVC, ABT etc
Limitation:
- Not cycle accurate
- Code generation not optimized
Speed should be x3 - x5 faster than interpreter in many cases (tested on Nokia Lumia 525 Win10 Mobile).
Instructions WIP, CP opcode not finish yet.