mirror of
https://github.com/RKX1209/nsemu.git
synced 2024-06-23 14:43:16 -04:00
Add support for load literal operation
This commit is contained in:
parent
33334725e2
commit
305b7f9349
|
@ -707,7 +707,25 @@ static void DisasDataProcReg(uint32_t insn, DisasCallback *cb) {
|
|||
}
|
||||
}
|
||||
|
||||
/* Load register (literal) ... literal means PC-relative immediate value */
|
||||
static void DisasLdLit(uint32_t insn, DisasCallback *cb) {
|
||||
unsigned int rt = extract32(insn, 0, 5);
|
||||
int64_t imm = sextract32(insn, 5, 19) << 2;
|
||||
bool is_vector = extract32(insn, 26, 1);
|
||||
unsigned int opc = extract32(insn, 30, 2);
|
||||
bool sf = opc != 0;
|
||||
bool is_signed = false;
|
||||
int size = 2;
|
||||
if (is_vector) {
|
||||
UnsupportedOp("LDR (SIMD&FP)");
|
||||
} else {
|
||||
if (opc == 3) {
|
||||
return;
|
||||
}
|
||||
size = 2 + extract32(opc, 0, 1);
|
||||
is_signed = extract32(opc, 1, 1);
|
||||
}
|
||||
cb->LoadReg (rt, PC + imm - 4, size, false, sf);
|
||||
}
|
||||
|
||||
static void DisasLdSt(uint32_t insn, DisasCallback *cb) {
|
||||
|
|
|
@ -343,6 +343,23 @@ void IntprCallback::ExtendReg(unsigned int rd_idx, unsigned int rn_idx, unsigned
|
|||
/* TODO: */
|
||||
}
|
||||
|
||||
/* Load/Store */
|
||||
void IntprCallback::LoadReg(unsigned int rd_idx, uint64_t addr, int size, bool extend, bool bit64) {
|
||||
if (bit64) {
|
||||
if (size == 4)
|
||||
X(rd_idx) = ARMv8::ReadU32 (addr);
|
||||
if (size == 8)
|
||||
X(rd_idx) = ARMv8::ReadU64 (addr);
|
||||
/* TODO: if (extend)
|
||||
ExtendReg(rd_idx, rd_idx, type, true); */
|
||||
} else {
|
||||
if (size == 4)
|
||||
W(rd_idx) = ARMv8::ReadU32 (addr);
|
||||
/* TODO: if (extend)
|
||||
ExtendReg(rd_idx, rd_idx, type, true); */
|
||||
}
|
||||
}
|
||||
|
||||
/* Bitfield Signed/Unsigned Extract... with Immediate value */
|
||||
void IntprCallback::SExtractI64(unsigned int rd_idx, unsigned int rn_idx, unsigned int pos, unsigned int len, bool bit64) {
|
||||
/* TODO: */
|
||||
|
|
|
@ -3,16 +3,14 @@
|
|||
|
||||
namespace ARMv8 {
|
||||
|
||||
uint32_t ReadInst(uint64_t vaddr) {
|
||||
/* XXX: Implement Page translation */
|
||||
const uint64_t paddr = vaddr;
|
||||
return ReadU32 (paddr);
|
||||
uint32_t ReadInst(uint64_t gva) {
|
||||
return ReadU32 (gva);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static T ReadFromRAM(const uint64_t paddr) {
|
||||
static T ReadFromRAM(const uint64_t gpa) {
|
||||
T value = 0;
|
||||
for (uint64_t addr = paddr; addr < paddr + sizeof(T); addr++) {
|
||||
for (uint64_t addr = gpa; addr < gpa + sizeof(T); addr++) {
|
||||
uint8_t byte;
|
||||
std::memcpy (&byte, &Memory::pRAM[addr], sizeof(uint8_t));
|
||||
value = (value << 8) | byte;
|
||||
|
@ -20,8 +18,25 @@ static T ReadFromRAM(const uint64_t paddr) {
|
|||
return value;
|
||||
}
|
||||
|
||||
uint32_t ReadU32(const uint64_t paddr) {
|
||||
return ReadFromRAM<uint32_t>(paddr);
|
||||
uint8_t ReadU8(const uint64_t gva) {
|
||||
/* XXX: Implement Page translation */
|
||||
uint64_t gpa = gva;
|
||||
return ReadFromRAM<uint8_t>(gpa);
|
||||
}
|
||||
uint16_t ReadU16(const uint64_t gva) {
|
||||
/* XXX: Implement Page translation */
|
||||
uint64_t gpa = gva;
|
||||
return ReadFromRAM<uint16_t>(gpa);
|
||||
}
|
||||
uint32_t ReadU32(const uint64_t gva) {
|
||||
/* XXX: Implement Page translation */
|
||||
uint64_t gpa = gva;
|
||||
return ReadFromRAM<uint32_t>(gpa);
|
||||
}
|
||||
uint64_t ReadU64(const uint64_t gva) {
|
||||
/* XXX: Implement Page translation */
|
||||
uint64_t gpa = gva;
|
||||
return ReadFromRAM<uint64_t>(gpa);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
16
Memory.cpp
16
Memory.cpp
|
@ -50,8 +50,8 @@ AddressSpace *FindAddressSpace(Nsemu *nsemu, uint64_t addr, size_t len) {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
static bool _CopyMemEmu(AddressSpace *as, void *data, uint64_t addr, size_t len, bool load) {
|
||||
uint64_t off = addr - as->addr;
|
||||
static bool _CopyMemEmu(AddressSpace *as, void *data, uint64_t hva, size_t len, bool load) {
|
||||
uint64_t off = hva - as->addr;
|
||||
void *emu_mem = (uint8_t *) as->data + off;
|
||||
if (load) {
|
||||
memcpy (emu_mem, data, len);
|
||||
|
@ -61,12 +61,12 @@ static bool _CopyMemEmu(AddressSpace *as, void *data, uint64_t addr, size_t len,
|
|||
return true;
|
||||
}
|
||||
|
||||
bool CopytoEmu(Nsemu *nsemu, void *data, uint64_t addr, size_t len) {
|
||||
bool CopytoEmu(Nsemu *nsemu, void *data, uint64_t hva, size_t len) {
|
||||
AddressSpace *as;
|
||||
if (!(as = FindAddressSpace (nsemu, addr, len))) {
|
||||
if (!(as = FindAddressSpace (nsemu, hva, len))) {
|
||||
return false;
|
||||
}
|
||||
return _CopyMemEmu (as, data, addr, len, true);
|
||||
return _CopyMemEmu (as, data, hva, len, true);
|
||||
}
|
||||
|
||||
bool CopytoEmuByName(Nsemu *nsemu, void *data, std::string name, size_t len) {
|
||||
|
@ -80,12 +80,12 @@ bool CopytoEmuByName(Nsemu *nsemu, void *data, std::string name, size_t len) {
|
|||
return _CopyMemEmu (as, data, as->addr, len, true);
|
||||
}
|
||||
|
||||
bool CopyfromEmu(Nsemu *nsemu, void *data, uint64_t addr, size_t len) {
|
||||
bool CopyfromEmu(Nsemu *nsemu, void *data, uint64_t hva, size_t len) {
|
||||
AddressSpace *as;
|
||||
if (!(as = FindAddressSpace (nsemu, addr, len))) {
|
||||
if (!(as = FindAddressSpace (nsemu, hva, len))) {
|
||||
return false;
|
||||
}
|
||||
return _CopyMemEmu (as, data, addr, len, false);
|
||||
return _CopyMemEmu (as, data, hva, len, false);
|
||||
}
|
||||
|
||||
bool CopyfromEmuByName(Nsemu *nsemu, void *data, std::string name, size_t len) {
|
||||
|
|
|
@ -43,6 +43,9 @@ virtual void BicReg(unsigned int rd_idx, unsigned int rn_idx, unsigned int rm_id
|
|||
virtual void NotReg(unsigned int rd_idx, unsigned int rm_idx, bool bit64) = 0;
|
||||
virtual void ExtendReg(unsigned int rd_idx, unsigned int rn_idx, unsigned int extend_type, bool bit64) = 0;
|
||||
|
||||
/* Load/Store */
|
||||
virtual void LoadReg(unsigned int rd_idx, uint64_t addr, int size, bool extend, bool bit64) = 0;
|
||||
|
||||
/* Bitfield Signed/Unsigned Extract... with Immediate value */
|
||||
virtual void SExtractI64(unsigned int rd_idx, unsigned int rn_idx, unsigned int pos, unsigned int len, bool bit64) = 0;
|
||||
virtual void UExtractI64(unsigned int rd_idx, unsigned int rn_idx, unsigned int pos, unsigned int len, bool bit64) = 0;
|
||||
|
|
|
@ -43,6 +43,9 @@ void BicReg(unsigned int rd_idx, unsigned int rn_idx, unsigned int rm_idx, bool
|
|||
void NotReg(unsigned int rd_idx, unsigned int rm_idx, bool bit64);
|
||||
void ExtendReg(unsigned int rd_idx, unsigned int rn_idx, unsigned int extend_type, bool bit64);
|
||||
|
||||
/* Load/Store */
|
||||
void LoadReg(unsigned int rd_idx, uint64_t addr, int size, bool extend, bool bit64);
|
||||
|
||||
/* Bitfield Signed/Unsigned Extract... with Immediate value */
|
||||
void SExtractI64(unsigned int rd_idx, unsigned int rn_idx, unsigned int pos, unsigned int len, bool bit64);
|
||||
void UExtractI64(unsigned int rd_idx, unsigned int rn_idx, unsigned int pos, unsigned int len, bool bit64);
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
#ifndef _MMU_HPP
|
||||
#define _MMU_HPP
|
||||
|
||||
/* MMU interface that support access by guest virtual/physical address. */
|
||||
|
||||
namespace ARMv8 {
|
||||
|
||||
uint32_t ReadInst(uint64_t vaddr);
|
||||
uint32_t ReadU32(const uint64_t paddr);
|
||||
|
||||
uint32_t ReadInst(uint64_t gva);
|
||||
uint8_t ReadU8(const uint64_t gva);
|
||||
uint16_t ReadU16(const uint64_t gva);
|
||||
uint32_t ReadU32(const uint64_t gva);
|
||||
uint64_t ReadU64(const uint64_t gva);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#ifndef _MEMORY_HPP
|
||||
#define _MEMORY_HPP
|
||||
|
||||
/* Memory utilities that support access by host virtual address. */
|
||||
|
||||
#include <string>
|
||||
#include <sys/types.h>
|
||||
|
||||
|
|
Loading…
Reference in a new issue