Add support of Load/Store FP reg

This commit is contained in:
rkx1209 2018-06-07 21:50:15 +09:00
parent 95a8fbf6c6
commit 540046ca96
4 changed files with 61 additions and 10 deletions

View file

@ -1085,10 +1085,18 @@ static void DisasLdstRegRoffset(uint32_t insn, DisasCallback *cb,
bool sf = (opt & 0x1) ? true : false; // XXX: Correct?
cb->ExtendReg (GPR_DUMMY, rm, opt, sf);
cb->ShiftI64 (GPR_DUMMY, GPR_DUMMY, ShiftType_LSL, shift ? size : 0, sf);
if (is_store) {
cb->StoreReg (rt, rn, GPR_DUMMY, size, is_signed, is_extended, false, sf);
if (is_vector) {
if (is_store) {
cb->StoreFpRegI64 (rt, GPR_DUMMY, size);
} else {
cb->LoadFpRegI64 (rt, GPR_DUMMY, size);
}
} else {
cb->LoadReg (rt, rn, GPR_DUMMY, size, is_signed, is_extended, false, sf);
if (is_store) {
cb->StoreReg (rt, rn, GPR_DUMMY, size, is_signed, is_extended, false, sf);
} else {
cb->LoadReg (rt, rn, GPR_DUMMY, size, is_signed, is_extended, false, sf);
}
}
}
@ -1164,10 +1172,18 @@ static void DisasLdstRegImm9(uint32_t insn, DisasCallback *cb,
if (!post_index) {
cb->AddI64 (GPR_DUMMY, rn, imm9, false, true);
}
if (is_store) {
cb->StoreRegI64 (rt, GPR_DUMMY, size, is_signed, is_extended);
if (is_vector) {
if (is_store) {
cb->StoreFpRegI64 (rt, GPR_DUMMY, size);
} else {
cb->LoadFpRegI64 (rt, GPR_DUMMY, size);
}
} else {
cb->LoadRegI64 (rt, GPR_DUMMY, size, is_signed, is_extended);
if (is_store) {
cb->StoreRegI64 (rt, GPR_DUMMY, size, is_signed, is_extended);
} else {
cb->LoadRegI64 (rt, GPR_DUMMY, size, is_signed, is_extended);
}
}
if (writeback) {
cb->AddI64 (rn, rn, imm9, false, true);
@ -1215,11 +1231,10 @@ static void DisasLdstRegUnsignedImm(uint32_t insn, DisasCallback *cb,
offset = imm12 << size;
cb->AddI64 (GPR_DUMMY, rn, offset, false, true);
if (is_vector) {
/* size must be 4 (128-bit) */
if (is_store) {
cb->StoreRegI64 (rt, GPR_DUMMY, size, is_signed, false);
cb->StoreFpRegI64 (rt, GPR_DUMMY, size);
} else {
cb->LoadRegI64 (rt, GPR_DUMMY, size, is_signed, false);
cb->LoadFpRegI64 (rt, GPR_DUMMY, size);
}
} else {
bool sf = DisasLdstCompute64bit (size, is_signed, opc);

View file

@ -11,7 +11,6 @@ void Interpreter::Init() {
int Interpreter::SingleStep() {
uint32_t inst = ARMv8::ReadInst (PC);
debug_print ("Run Code: 0x%lx: 0x%08lx\n", PC, inst);
//ns_print ("Run Code: 0x%lx: 0x%08lx\n", PC, inst);
Disassembler::DisasA64 (inst, disas_cb);
PC += sizeof(uint32_t);
X(GPR_ZERO) = 0; //Reset Zero register
@ -698,6 +697,34 @@ void IntprCallback::StoreVecReg(unsigned int rd_idx, int element, unsigned int v
}
}
/* Load/Store for FP */
void IntprCallback::LoadFpRegI64(unsigned int fd_idx, unsigned int ad_idx, int size) {
uint64_t addr = X(ad_idx);
debug_print("Load Fp(%d)[%u] = [X(%u)(0x%lx)]\n", size, fd_idx, ad_idx, addr);
if (size == 0) { // 1byte (8B/16B)
B(fd_idx) = ARMv8::ReadU8 (addr);
} else if (size == 1) { // 2byte (4H/8H)
H(fd_idx) = ARMv8::ReadU16 (addr);
} else if (size == 2) { // 4byte (2S/4S)
S(fd_idx) = ARMv8::ReadU32 (addr);
} else if (size == 3) {
D(fd_idx) = ARMv8::ReadU64 (addr);
}
}
void IntprCallback::StoreFpRegI64(unsigned int fd_idx, unsigned int ad_idx, int size) {
uint64_t addr = X(ad_idx);
debug_print("Store Fp(%d)[%u] => [X(%u)(0x%lx)]\n", size, fd_idx, ad_idx, addr);
if (size == 0) {
ARMv8::WriteU8 (addr, B(fd_idx));
} else if (size == 1) {
ARMv8::WriteU16 (addr, H(fd_idx));
} else if (size == 2) {
ARMv8::WriteU32 (addr, S(fd_idx));
} else if (size == 3) {
ARMv8::WriteU64 (addr, D(fd_idx));
}
}
/* Bitfield Signed/Unsigned Extract... with Immediate value */
/* X(d)<> = X(n)<off:64> */
void IntprCallback::SExtractI64(unsigned int rd_idx, unsigned int rn_idx, unsigned int pos, unsigned int len, bool bit64) {

View file

@ -117,6 +117,10 @@ virtual void NotVecReg(unsigned int rd_idx, unsigned int rm_idx) = 0;
virtual void LoadVecReg(unsigned int vd_idx, int element, unsigned int rn_idx, int size) = 0;
virtual void StoreVecReg(unsigned int rd_idx, int element, unsigned int vn_idx, int size) = 0;
/* Load/Store for FP */
virtual void LoadFpRegI64(unsigned int fd_idx, unsigned int ad_idx, int size) = 0;
virtual void StoreFpRegI64(unsigned int fd_idx, unsigned int ad_idx, int size) = 0;
/* Read Vector register to FP regsiter */
virtual void ReadVecReg(unsigned int fd_idx, unsigned int vn_idx, unsigned int index, int size) = 0;
/* Read Vector register to general register */

View file

@ -104,10 +104,15 @@ void ReadWriteNZCV(unsigned int rd_idx, bool read);
void FMovReg(unsigned int fd_idx, unsigned int fn_idx, int type);
/* ####### Vector ####### */
/* Load/Store for vector */
void LoadVecReg(unsigned int vd_idx, int element, unsigned int rn_idx, int size);
void StoreVecReg(unsigned int rd_idx, int element, unsigned int vn_idx, int size);
/* Load/Store for FP */
void LoadFpRegI64(unsigned int fd_idx, unsigned int ad_idx, int size);
void StoreFpRegI64(unsigned int fd_idx, unsigned int ad_idx, int size);
/* AND/OR/EOR/BIC/NOT ... between vector registers */
void AndVecReg(unsigned int rd_idx, unsigned int rn_idx, unsigned int rm_idx);
void OrrVecReg(unsigned int rd_idx, unsigned int rn_idx, unsigned int rm_idx);