Add support for load literal operation

This commit is contained in:
rkx1209 2018-02-27 17:47:29 +09:00
parent 33334725e2
commit 305b7f9349
8 changed files with 81 additions and 19 deletions

View file

@ -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) {

View file

@ -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: */

View file

@ -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);
}
}

View file

@ -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) {

View file

@ -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;

View file

@ -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);

View file

@ -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

View file

@ -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>