#define sext_xprlen(x) ((sreg_t(x) << (64-xprlen)) >> (64-xprlen))
#define zext_xprlen(x) ((reg_t(x) << (64-xprlen)) >> (64-xprlen))
+#ifndef RISCV_ENABLE_RVC
+# define set_pc(x) \
+ do { if((x) & (sizeof(insn_t)-1)) \
+ { badvaddr = (x); throw trap_instruction_address_misaligned; } \
+ npc = (x); \
+ } while(0)
+#else
+# define set_pc(x) \
+ do { if((x) & ((sr & SR_EC) ? 1 : 3)) \
+ { badvaddr = (x); throw trap_instruction_address_misaligned; } \
+ npc = (x); \
+ } while(0)
+#endif
+
// RVC stuff
#define INSN_IS_RVC(x) (((x) & 0x3) < 0x3)
if(cmp_trunc(RS1) == cmp_trunc(RS2))
- npc = BRANCH_TARGET;
+ set_pc(BRANCH_TARGET);
if(sreg_t(cmp_trunc(RS1)) >= sreg_t(cmp_trunc(RS2)))
- npc = BRANCH_TARGET;
+ set_pc(BRANCH_TARGET);
if(cmp_trunc(RS1) >= cmp_trunc(RS2))
- npc = BRANCH_TARGET;
+ set_pc(BRANCH_TARGET);
if(sreg_t(cmp_trunc(RS1)) < sreg_t(cmp_trunc(RS2)))
- npc = BRANCH_TARGET;
+ set_pc(BRANCH_TARGET);
if(cmp_trunc(RS1) < cmp_trunc(RS2))
- npc = BRANCH_TARGET;
+ set_pc(BRANCH_TARGET);
if(cmp_trunc(RS1) != cmp_trunc(RS2))
- npc = BRANCH_TARGET;
+ set_pc(BRANCH_TARGET);
require_rvc;
if(CRD_REGNUM == 0)
{
- reg_t temp = npc;
- npc = CRS1;
+ reg_t temp = CRS1;
if(CIMM6 & 0x20)
- RA = temp;
+ RA = npc;
+ set_pc(temp);
}
else
CRD = sext_xprlen(CRS2 + CIMM6);
require_rvc;
if(cmp_trunc(CRS1S) == cmp_trunc(CRS2S))
- npc = CBRANCH_TARGET;
+ set_pc(CBRANCH_TARGET);
require_rvc;
if(cmp_trunc(CRS1S) != cmp_trunc(CRS2S))
- npc = CBRANCH_TARGET;
+ set_pc(CBRANCH_TARGET);
require_rvc;
-npc = CJUMP_TARGET;
+set_pc(CJUMP_TARGET);
if(sr & SR_ET)
throw trap_illegal_instruction;
set_sr(((sr & SR_PS) ? sr : (sr & ~SR_S)) | SR_ET);
-npc = epc;
+set_pc(epc);
-npc = JUMP_TARGET;
+set_pc(JUMP_TARGET);
RA = npc;
-npc = JUMP_TARGET;
+set_pc(JUMP_TARGET);
-reg_t temp = npc;
-npc = RS1 + SIMM;
-RD = temp;
+reg_t temp = RS1;
+RD = npc;
+set_pc(temp + SIMM);