4 Star 26 Fork 10

DENGCHOW / XEMU

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
exec.c 12.23 KB
一键复制 编辑 原始数据 按行查看 历史
DENGCHOW 提交于 2023-08-28 22:42 . add lcd, only work under ubuntu platform
/*
* Copyright (c) 2020-2021, SERI Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2023-06-23 Lyons first version
*/
uint32_t exec_lui(void *info)
{
InstInfo_t *inst_info = (InstInfo_t*)info;
return ( inst_info->imm << 12 );
}
uint32_t exec_auipc(void *info)
{
InstInfo_t *inst_info = (InstInfo_t*)info;
return ( inst_info->current_pc + (inst_info->imm << 12) );
}
uint32_t exec_jal(void *info)
{
InstInfo_t *inst_info = (InstInfo_t*)info;
uint32_t iresult = inst_info->next_pc;
inst_info->imm <<= 1; // imm20 << 1
inst_info->next_pc = (int32_t)inst_info->current_pc + (int32_t)SIGN_EXTEND(inst_info->imm, 21);
return iresult;
}
uint32_t exec_jalr(void *info)
{
InstInfo_t *inst_info = (InstInfo_t*)info;
uint32_t iresult = inst_info->next_pc;
inst_info->next_pc = (int32_t)inst_info->rs1_data + (int32_t)SIGN_EXTEND(inst_info->imm, 12);
inst_info->next_pc &= 0xfffffffe;
return iresult;
}
uint32_t exec_beq(void *info)
{
InstInfo_t *inst_info = (InstInfo_t*)info;
inst_info->imm <<= 1; // im12 << 1
if ( inst_info->rs1_data == inst_info->rs2_data )
inst_info->next_pc = (int32_t)inst_info->current_pc + (int32_t)SIGN_EXTEND(inst_info->imm, 13);
return 0;
}
uint32_t exec_bne(void *info)
{
InstInfo_t *inst_info = (InstInfo_t*)info;
inst_info->imm <<= 1; // im12 << 1
if ( inst_info->rs1_data != inst_info->rs2_data )
inst_info->next_pc = (int32_t)inst_info->current_pc + (int32_t)SIGN_EXTEND(inst_info->imm, 13);
return 0;
}
uint32_t exec_blt(void *info)
{
InstInfo_t *inst_info = (InstInfo_t*)info;
inst_info->imm <<= 1; // im12 << 1
if ( (int32_t)inst_info->rs1_data < (int32_t)inst_info->rs2_data )
inst_info->next_pc = (int32_t)inst_info->current_pc + (int32_t)SIGN_EXTEND(inst_info->imm, 13);
return 0;
}
uint32_t exec_bge(void *info)
{
InstInfo_t *inst_info = (InstInfo_t*)info;
inst_info->imm <<= 1; // im12 << 1
if ( (int32_t)inst_info->rs1_data >= (int32_t)inst_info->rs2_data )
inst_info->next_pc = (int32_t)inst_info->current_pc + (int32_t)SIGN_EXTEND(inst_info->imm, 13);
return 0;
}
uint32_t exec_bltu(void *info)
{
InstInfo_t *inst_info = (InstInfo_t*)info;
inst_info->imm <<= 1; // im12 << 1
if ( inst_info->rs1_data < inst_info->rs2_data )
inst_info->next_pc = (int32_t)inst_info->current_pc + SIGN_EXTEND(inst_info->imm, 13);
return 0;
}
uint32_t exec_bgeu(void *info)
{
InstInfo_t *inst_info = (InstInfo_t*)info;
inst_info->imm <<= 1; // im12 << 1
if ( inst_info->rs1_data >= inst_info->rs2_data )
inst_info->next_pc = (int32_t)inst_info->current_pc + SIGN_EXTEND(inst_info->imm, 13);
return 0;
}
uint32_t exec_lb(void *info)
{
InstInfo_t *inst_info = (InstInfo_t*)info;
inst_info->mem_addr = (int32_t)inst_info->rs1_data + (int32_t)SIGN_EXTEND(inst_info->imm, 12);
inst_info->mem_rd = 1;
inst_info->mem_ext = eMemoryExtType_Sign;
inst_info->mem_size = eMemorySize_Byte;
return 0;
}
uint32_t exec_lh(void *info)
{
InstInfo_t *inst_info = (InstInfo_t*)info;
inst_info->mem_addr = (int32_t)inst_info->rs1_data + (int32_t)SIGN_EXTEND(inst_info->imm, 12);
inst_info->mem_rd = 1;
inst_info->mem_ext = eMemoryExtType_Sign;
inst_info->mem_size = eMemorySize_HalfWord;
return 0;
}
uint32_t exec_lw(void *info)
{
InstInfo_t *inst_info = (InstInfo_t*)info;
inst_info->mem_addr = (int32_t)inst_info->rs1_data + (int32_t)SIGN_EXTEND(inst_info->imm, 12);
inst_info->mem_rd = 1;
inst_info->mem_ext = eMemoryExtType_Sign;
inst_info->mem_size = eMemorySize_Word;
return 0;
}
uint32_t exec_lbu(void *info)
{
InstInfo_t *inst_info = (InstInfo_t*)info;
inst_info->mem_addr = (int32_t)inst_info->rs1_data + (int32_t)SIGN_EXTEND(inst_info->imm, 12);
inst_info->mem_rd = 1;
inst_info->mem_ext = eMemoryExtType_Zero;
inst_info->mem_size = eMemorySize_Byte;
return 0;
}
uint32_t exec_lhu(void *info)
{
InstInfo_t *inst_info = (InstInfo_t*)info;
inst_info->mem_addr = (int32_t)inst_info->rs1_data + (int32_t)SIGN_EXTEND(inst_info->imm, 12);
inst_info->mem_rd = 1;
inst_info->mem_ext = eMemoryExtType_Zero;
inst_info->mem_size = eMemorySize_HalfWord;
return 0;
}
uint32_t exec_sb(void *info)
{
InstInfo_t *inst_info = (InstInfo_t*)info;
inst_info->mem_addr = (int32_t)inst_info->rs1_data + (int32_t)SIGN_EXTEND(inst_info->imm, 12);
inst_info->mem_data = inst_info->rs2_data;
inst_info->mem_we = 1;
inst_info->mem_size = eMemorySize_Byte;
return 0;
}
uint32_t exec_sh(void *info)
{
InstInfo_t *inst_info = (InstInfo_t*)info;
inst_info->mem_addr = (int32_t)inst_info->rs1_data + (int32_t)SIGN_EXTEND(inst_info->imm, 12);
inst_info->mem_data = inst_info->rs2_data;
inst_info->mem_we = 1;
inst_info->mem_size = eMemorySize_HalfWord;
return 0;
}
uint32_t exec_sw(void *info)
{
InstInfo_t *inst_info = (InstInfo_t*)info;
inst_info->mem_addr = (int32_t)inst_info->rs1_data + (int32_t)SIGN_EXTEND(inst_info->imm, 12);
inst_info->mem_data = inst_info->rs2_data;
inst_info->mem_we = 1;
inst_info->mem_size = eMemorySize_Word;
return 0;
}
uint32_t exec_addi(void *info)
{
InstInfo_t *inst_info = (InstInfo_t*)info;
return ( (int32_t)inst_info->rs1_data + (int32_t)SIGN_EXTEND(inst_info->imm, 12) );
}
uint32_t exec_slli(void *info)
{
InstInfo_t *inst_info = (InstInfo_t*)info;
return ( inst_info->rs1_data << inst_info->shamt );
}
uint32_t exec_slti(void *info)
{
InstInfo_t *inst_info = (InstInfo_t*)info;
return ( ((int32_t)inst_info->rs1_data < (int32_t)SIGN_EXTEND(inst_info->imm, 12)) ? 1 : 0 );
}
uint32_t exec_sltiu(void *info)
{
InstInfo_t *inst_info = (InstInfo_t*)info;
return ( (inst_info->rs1_data < SIGN_EXTEND(inst_info->imm, 12)) ? 1 : 0 );
}
uint32_t exec_xori(void *info)
{
InstInfo_t *inst_info = (InstInfo_t*)info;
return ( inst_info->rs1_data ^ SIGN_EXTEND(inst_info->imm, 12) );
}
uint32_t exec_srli(void *info)
{
InstInfo_t *inst_info = (InstInfo_t*)info;
return ( inst_info->rs1_data >> inst_info->shamt );
}
uint32_t exec_srai(void *info)
{
InstInfo_t *inst_info = (InstInfo_t*)info;
uint32_t iresult = inst_info->rs1_data >> inst_info->shamt;
uint32_t mask = SIGN_EXTEND(BIT(inst_info->rs1_data, 31), 1) >> inst_info->shamt;
if ( BIT(inst_info->rs1_data, 31) ) {
iresult |= ~mask;
}
return iresult;
}
uint32_t exec_ori(void *info)
{
InstInfo_t *inst_info = (InstInfo_t*)info;
return ( inst_info->rs1_data | SIGN_EXTEND(inst_info->imm, 12) );
}
uint32_t exec_andi(void *info)
{
InstInfo_t *inst_info = (InstInfo_t*)info;
return ( inst_info->rs1_data & SIGN_EXTEND(inst_info->imm, 12) );
}
uint32_t exec_add(void *info)
{
InstInfo_t *inst_info = (InstInfo_t*)info;
return ( (int32_t)inst_info->rs1_data + (int32_t)inst_info->rs2_data );
}
uint32_t exec_sub(void *info)
{
InstInfo_t *inst_info = (InstInfo_t*)info;
return ( (int32_t)inst_info->rs1_data - (int32_t)inst_info->rs2_data );
}
uint32_t exec_sll(void *info)
{
InstInfo_t *inst_info = (InstInfo_t*)info;
return ( inst_info->rs1_data << inst_info->rs2_data );
}
uint32_t exec_slt(void *info)
{
InstInfo_t *inst_info = (InstInfo_t*)info;
return ( ((int32_t)inst_info->rs1_data < (int32_t)inst_info->rs2_data) ? 1 : 0 );
}
uint32_t exec_sltu(void *info)
{
InstInfo_t *inst_info = (InstInfo_t*)info;
return ( (inst_info->rs1_data < inst_info->rs2_data) ? 1 : 0 );
}
uint32_t exec_xor(void *info)
{
InstInfo_t *inst_info = (InstInfo_t*)info;
return ( inst_info->rs1_data ^ inst_info->rs2_data );
}
uint32_t exec_srl(void *info)
{
InstInfo_t *inst_info = (InstInfo_t*)info;
return ( inst_info->rs1_data >> inst_info->rs2_data );
}
uint32_t exec_sra(void *info)
{
InstInfo_t *inst_info = (InstInfo_t*)info;
uint32_t iresult = inst_info->rs1_data >> inst_info->rs2_data;
uint32_t mask = SIGN_EXTEND(BIT(inst_info->rs1_data, 31), 1) >> inst_info->rs2_data;
if ( BIT(inst_info->rs1_data, 31) ) {
iresult |= ~mask;
}
return iresult;
}
uint32_t exec_or(void *info)
{
InstInfo_t *inst_info = (InstInfo_t*)info;
return ( inst_info->rs1_data | inst_info->rs2_data );
}
uint32_t exec_and(void *info)
{
InstInfo_t *inst_info = (InstInfo_t*)info;
return ( inst_info->rs1_data & inst_info->rs2_data );
}
uint32_t exec_fence(void *info)
{
InstInfo_t *inst_info = (InstInfo_t*)info;
return 0;
}
uint32_t exec_mret(void *info)
{
InstInfo_t *inst_info = (InstInfo_t*)info;
inst_info->mret = 1;
return 0;
}
uint32_t exec_csrrw(void *info)
{
InstInfo_t *inst_info = (InstInfo_t*)info;
uint32_t iresult = inst_info->csr_data;
inst_info->csr_data = inst_info->rs1_data;
return iresult;
}
uint32_t exec_csrrs(void *info)
{
InstInfo_t *inst_info = (InstInfo_t*)info;
uint32_t iresult = inst_info->csr_data;
inst_info->csr_data |= inst_info->rs1_data;
return iresult;
}
uint32_t exec_csrrc(void *info)
{
InstInfo_t *inst_info = (InstInfo_t*)info;
uint32_t iresult = inst_info->csr_data;
inst_info->csr_data &= ~inst_info->rs1_data;
return iresult;
}
uint32_t exec_csrrwi(void *info)
{
InstInfo_t *inst_info = (InstInfo_t*)info;
uint32_t iresult = inst_info->csr_data;
inst_info->csr_data = ZERO_EXTEND(inst_info->imm, 5);
return iresult;
}
uint32_t exec_csrrsi(void *info)
{
InstInfo_t *inst_info = (InstInfo_t*)info;
uint32_t iresult = inst_info->csr_data;
inst_info->csr_data |= ZERO_EXTEND(inst_info->imm, 5);
return iresult;
}
uint32_t exec_csrrci(void *info)
{
InstInfo_t *inst_info = (InstInfo_t*)info;
uint32_t iresult = inst_info->csr_data;
inst_info->csr_data &= ~ZERO_EXTEND(inst_info->imm, 5);
return iresult;
}
#ifdef RV32M
uint32_t exec_mul(void *info)
{
InstInfo_t *inst_info = (InstInfo_t*)info;
uint64_t data1 = (uint64_t)inst_info->rs1_data + (BIT(inst_info->rs1_data, 31) ? 0xffffffff00000000 : 0);
uint64_t data2 = (uint64_t)inst_info->rs2_data + (BIT(inst_info->rs2_data, 31) ? 0xffffffff00000000 : 0);
uint64_t result64 = (int64_t)data1 * (int64_t)data2;
return ( result64 );
}
uint32_t exec_mulh(void *info)
{
InstInfo_t *inst_info = (InstInfo_t*)info;
uint64_t data1 = (uint64_t)inst_info->rs1_data + (BIT(inst_info->rs1_data, 31) ? 0xffffffff00000000 : 0);
uint64_t data2 = (uint64_t)inst_info->rs2_data + (BIT(inst_info->rs2_data, 31) ? 0xffffffff00000000 : 0);
uint64_t result64 = (int64_t)data1 * (int64_t)data2;
return ( result64 >> 32 );
}
uint32_t exec_mulhsu(void *info)
{
InstInfo_t *inst_info = (InstInfo_t*)info;
uint64_t data1 = (uint64_t)inst_info->rs1_data + (BIT(inst_info->rs1_data, 31) ? 0xffffffff00000000 : 0);
uint64_t data2 = (uint64_t)inst_info->rs2_data;
uint64_t result64 = (int64_t)data1 * (int64_t)data2;
return ( result64 >> 32 );
}
uint32_t exec_mulhu(void *info)
{
InstInfo_t *inst_info = (InstInfo_t*)info;
uint64_t data1 = (uint64_t)inst_info->rs1_data;
uint64_t data2 = (uint64_t)inst_info->rs2_data;
uint64_t result64 = (int64_t)data1 * (int64_t)data2;
return ( result64 >> 32 );
}
uint32_t exec_div(void *info)
{
InstInfo_t *inst_info = (InstInfo_t*)info;
uint32_t iresult = 0xffffffff;
if ( 0 != (int32_t)inst_info->rs2_data ) {
iresult = (int32_t)inst_info->rs1_data / (int32_t)inst_info->rs2_data;
}
return iresult;
}
uint32_t exec_divu(void *info)
{
InstInfo_t *inst_info = (InstInfo_t*)info;
uint32_t iresult = 0xffffffff;
if ( 0 != (uint32_t)inst_info->rs2_data ) {
iresult = (uint32_t)inst_info->rs1_data / (uint32_t)inst_info->rs2_data;
}
return iresult;
}
uint32_t exec_rem(void *info)
{
InstInfo_t *inst_info = (InstInfo_t*)info;
uint32_t iresult = inst_info->rs1_data;
if ( 0 != (int32_t)inst_info->rs2_data ) {
iresult = (int32_t)inst_info->rs1_data % (int32_t)inst_info->rs2_data;
}
return iresult;
}
uint32_t exec_remu(void *info)
{
InstInfo_t *inst_info = (InstInfo_t*)info;
uint32_t iresult = inst_info->rs1_data;
if ( 0 != (uint32_t)inst_info->rs2_data ) {
iresult = (uint32_t)inst_info->rs1_data % (uint32_t)inst_info->rs2_data;
}
return iresult;
}
#endif // #ifdef RV32M
1
https://gitee.com/dengchow/xemu.git
git@gitee.com:dengchow/xemu.git
dengchow
xemu
XEMU
master

搜索帮助