Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
makigumo committed Dec 7, 2016
1 parent 88f7f9b commit ab27e06
Show file tree
Hide file tree
Showing 3 changed files with 143 additions and 33 deletions.
58 changes: 47 additions & 11 deletions RISCV/RISCVCtx.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,17 @@ extern DisasmOperandType (*getRegMask)(uint8_t);
#define OPCODE_OPIMM (uint8_t) 0b0010011
#define OPCODE_OPIMM32 OPCODE_OPIMM
#define OPCODE_OPIMM64 (uint8_t) 0b0011011
#define OPCODE_LOAD (uint8_t) 0b0000011
#define OPCODE_STORE (uint8_t) 0b0100011
#define OPCODE_OP (uint8_t) 0b0110011
#define OPCODE_OP32 (uint8_t) 0b0111011
#define OPCODE_AUIPC (uint8_t) 0b0010111
#define OPCODE_LUI (uint8_t) 0b0110111
#define OPCODE_BRANCH (uint8_t) 0b1100011
#define OPCODE_JALR (uint8_t) 0b1100111
#define OPCODE_JAL (uint8_t) 0b1101111
#define OPCODE_MISC_MEM (uint8_t) 0b0001111
#define OPCODE_SYSTEM (uint8_t) 0b1110011

typedef struct {
uint8_t opcode; /* bits 6..0 */
Expand All @@ -66,10 +70,11 @@ static inline int32_t getUJtypeImmediate(uint32_t insn) {

// the 12-bit B-immediate encodes signed offsets in multiples of 2
static inline int32_t getBtypeImmediate(uint32_t insn) {
return ((int32_t) (insn & 0x80E00000) >> 19 /* bits 31 -> 12 */ |
(int32_t) (insn & 0x00000080) >> 9 /* bit 7 -> 11 */ |
(int32_t) (insn & 0x7D000000) >> 20 /* bits 30..25 -> 10..5 */ |
(int32_t) (insn & 0x80000f00) >> 8 /* bit 11..8 -> 4..1 */);
return (((int32_t) (insn & 0x00000080) << 4 /* bit 7 -> 11 */ |
(int32_t) (insn & 0x7E000000) >> 20 /* bits 30..25 -> 10..5 */ |
(int32_t) (insn & 0x00000f00) >> 7 /* bit 11..8 -> 4..1 */ |
(int32_t) (-((insn >> 31) & 1)) << 12 /* bits 31 -> 12 */)
) & ~1;
}

// returns 12 bit signed I-immediate with LSB cleared
Expand All @@ -81,6 +86,11 @@ static inline int32_t getItypeImmediate(uint32_t insn) {
return ((int32_t) (insn & 0xfff00000) >> 20) /* bits 31..20 */;
}

static inline int32_t getStypeImmediate(uint32_t insn) {
return ((int32_t) (insn & 0x00000f80) >> 7) /* bits 11..7 -> 4..0 */ |
((int32_t) (insn & 0xfe000000) >> 20) /* bits 31..25 -> 11..5 */;
}

static inline int32_t getUtypeImmediate(uint32_t insn) {
return ((insn & 0xfffff000) >> 12) /* bits 31..12 */;
}
Expand Down Expand Up @@ -117,16 +127,16 @@ static inline uint8_t getRD(uint32_t insncode) {

// get shift amount
static inline uint8_t getShamt(uint32_t insncode) {
return (uint8_t) (((uint32_t)(insncode & SHAMT_MASK)) >> 20 );
return (uint8_t) (((uint32_t) (insncode & SHAMT_MASK)) >> 20);
}

// get shift amount 64 bit extension
static inline uint8_t getShamt64(uint32_t insncode) {
return (uint8_t) (((uint32_t)(insncode & SHAMT64_MASK)) >> 20 );
return (uint8_t) (((uint32_t) (insncode & SHAMT64_MASK)) >> 20);
}

static inline void populateOP(DisasmStruct* disasm, uint32_t insn, const char* mnemonic) {
strcpy(disasm->instruction.mnemonic, mnemonic);
static inline void populateOP(DisasmStruct *disasm, uint32_t insn, const char *mnemonic) {
strcpy(disasm->instruction.mnemonic, mnemonic);
disasm->operand[0].type = DISASM_OPERAND_REGISTER_TYPE;
disasm->operand[0].type |= getRegMask(getRD(insn));
disasm->operand[0].accessMode = DISASM_ACCESS_WRITE;
Expand All @@ -138,7 +148,7 @@ static inline void populateOP(DisasmStruct* disasm, uint32_t insn, const char* m
disasm->operand[2].accessMode = DISASM_ACCESS_READ;
}

static inline void populateOPIMM(DisasmStruct * disasm, uint32_t insn, const char* mnemonic) {
static inline void populateOPIMM(DisasmStruct *disasm, uint32_t insn, const char *mnemonic) {
strcpy(disasm->instruction.mnemonic, mnemonic);
disasm->operand[0].type = DISASM_OPERAND_REGISTER_TYPE;
disasm->operand[0].type |= getRegMask(getRD(insn));
Expand All @@ -151,7 +161,7 @@ static inline void populateOPIMM(DisasmStruct * disasm, uint32_t insn, const cha
disasm->operand[2].accessMode = DISASM_ACCESS_READ;
}

static inline void populateOPIMMShift(DisasmStruct * disasm, uint32_t insn, const char* mnemonic) {
static inline void populateOPIMMShift(DisasmStruct *disasm, uint32_t insn, const char *mnemonic) {
strcpy(disasm->instruction.mnemonic, mnemonic);
disasm->operand[0].type = DISASM_OPERAND_REGISTER_TYPE;
disasm->operand[0].type |= getRegMask(getRD(insn));
Expand All @@ -164,7 +174,7 @@ static inline void populateOPIMMShift(DisasmStruct * disasm, uint32_t insn, cons
disasm->operand[2].accessMode = DISASM_ACCESS_READ;
}

static inline void populateOPIMMShift64(DisasmStruct * disasm, uint32_t insn, const char* mnemonic) {
static inline void populateOPIMMShift64(DisasmStruct *disasm, uint32_t insn, const char *mnemonic) {
strcpy(disasm->instruction.mnemonic, mnemonic);
disasm->operand[0].type = DISASM_OPERAND_REGISTER_TYPE;
disasm->operand[0].type |= getRegMask(getRD(insn));
Expand All @@ -176,3 +186,29 @@ static inline void populateOPIMMShift64(DisasmStruct * disasm, uint32_t insn, co
disasm->operand[2].immediateValue = getShamt64(insn);
disasm->operand[2].accessMode = DISASM_ACCESS_READ;
}

static inline void populateLOAD(DisasmStruct *disasm, uint32_t insn, const char *mnemonic) {
strcpy(disasm->instruction.mnemonic, mnemonic);
disasm->operand[0].type = DISASM_OPERAND_REGISTER_TYPE;
disasm->operand[0].type |= getRegMask(getRD(insn));
disasm->operand[0].accessMode = DISASM_ACCESS_WRITE;
disasm->operand[1].type = DISASM_OPERAND_MEMORY_TYPE;
disasm->operand[1].type |= getRegMask(getRS1(insn));
disasm->operand[1].memory.baseRegistersMask = getRegMask(getRS1(insn));
disasm->operand[1].memory.displacement = getItypeImmediate(insn);
disasm->operand[1].memory.scale = 1;
disasm->operand[2].accessMode = DISASM_ACCESS_READ;
}

static inline void populateSTORE(DisasmStruct *disasm, uint32_t insn, const char *mnemonic) {
strcpy(disasm->instruction.mnemonic, mnemonic);
disasm->operand[0].type = DISASM_OPERAND_REGISTER_TYPE;
disasm->operand[0].type |= getRegMask(getRS2(insn));
disasm->operand[0].accessMode = DISASM_ACCESS_WRITE;
disasm->operand[1].type = DISASM_OPERAND_MEMORY_TYPE;
disasm->operand[1].type |= getRegMask(getRS1(insn));
disasm->operand[1].memory.baseRegistersMask = getRegMask(getRS1(insn));
disasm->operand[1].memory.displacement = getStypeImmediate(insn);
disasm->operand[1].memory.scale = 1;
disasm->operand[2].accessMode = DISASM_ACCESS_READ;
}
117 changes: 95 additions & 22 deletions RISCV/RISCVCtx.m
Original file line number Diff line number Diff line change
Expand Up @@ -249,11 +249,6 @@ - (int)disassembleSingleInstruction:(DisasmStruct *)disasm usingProcessorMode:(N
disasm->operand[0].type = DISASM_OPERAND_REGISTER_TYPE;
disasm->operand[0].type |= getRegMask(dest_reg);
disasm->operand[0].accessMode = DISASM_ACCESS_WRITE;
disasm->operand[1].type = DISASM_OPERAND_MEMORY_TYPE;
disasm->operand[1].type |= getRegMask(src1_reg);
disasm->operand[1].memory.baseRegistersMask = getRegMask(src1_reg);
disasm->operand[1].memory.displacement = getItypeImmediate(insncode);
disasm->operand[1].memory.scale = 1;
disasm->operand[1].accessMode = DISASM_ACCESS_READ;
disasm->operand[1].isBranchDestination = 1;
disasm->instruction.branchType = DISASM_BRANCH_CALL;
Expand Down Expand Up @@ -346,8 +341,7 @@ - (int)disassembleSingleInstruction:(DisasmStruct *)disasm usingProcessorMode:(N
populateOPIMMShift(disasm, insncode, "srai");
break;
}
}
else {
} else {
// 64 bits
switch (getFunct6(insncode)) {
case 0b000000:
Expand Down Expand Up @@ -454,21 +448,6 @@ - (int)disassembleSingleInstruction:(DisasmStruct *)disasm usingProcessorMode:(N
disasm->instruction.branchType = DISASM_BRANCH_JNE;
}
break;
case 0b110 /* bltu */:
strcpy(disasm->instruction.mnemonic, "bltu");
disasm->operand[0].type = DISASM_OPERAND_REGISTER_TYPE;
disasm->operand[0].type |= getRegMask(src1_reg);
disasm->operand[0].accessMode = DISASM_ACCESS_READ;
disasm->operand[1].type = DISASM_OPERAND_REGISTER_TYPE;
disasm->operand[1].type |= getRegMask(src2_reg);
disasm->operand[1].accessMode = DISASM_ACCESS_READ;
disasm->operand[2].type = DISASM_OPERAND_CONSTANT_TYPE | DISASM_OPERAND_RELATIVE;
disasm->operand[2].immediateValue = getBtypeImmediate(insncode);
disasm->operand[2].accessMode = DISASM_ACCESS_READ;
disasm->operand[2].isBranchDestination = 1;
disasm->instruction.addressValue = (Address) getBtypeImmediate(insncode) + disasm->virtualAddr /* + src1_reg */;
disasm->instruction.branchType = DISASM_BRANCH_JNE;
break;
case 0b101 /* bge */:
if (src2_reg == 0 /* zero */) {
strcpy(disasm->instruction.mnemonic, "bgez");
Expand Down Expand Up @@ -497,6 +476,21 @@ - (int)disassembleSingleInstruction:(DisasmStruct *)disasm usingProcessorMode:(N
disasm->instruction.branchType = DISASM_BRANCH_JNE;
}
break;
case 0b110 /* bltu */:
strcpy(disasm->instruction.mnemonic, "bltu");
disasm->operand[0].type = DISASM_OPERAND_REGISTER_TYPE;
disasm->operand[0].type |= getRegMask(src1_reg);
disasm->operand[0].accessMode = DISASM_ACCESS_READ;
disasm->operand[1].type = DISASM_OPERAND_REGISTER_TYPE;
disasm->operand[1].type |= getRegMask(src2_reg);
disasm->operand[1].accessMode = DISASM_ACCESS_READ;
disasm->operand[2].type = DISASM_OPERAND_CONSTANT_TYPE | DISASM_OPERAND_RELATIVE;
disasm->operand[2].immediateValue = getBtypeImmediate(insncode);
disasm->operand[2].accessMode = DISASM_ACCESS_READ;
disasm->operand[2].isBranchDestination = 1;
disasm->instruction.addressValue = (Address) getBtypeImmediate(insncode) + disasm->virtualAddr /* + src1_reg */;
disasm->instruction.branchType = DISASM_BRANCH_JNE;
break;
case 0b111 /* bgeu */:
strcpy(disasm->instruction.mnemonic, "bgeu");
disasm->operand[0].type = DISASM_OPERAND_REGISTER_TYPE;
Expand Down Expand Up @@ -589,6 +583,85 @@ - (int)disassembleSingleInstruction:(DisasmStruct *)disasm usingProcessorMode:(N
}
break;

case OPCODE_LOAD:
switch (funct3) {
case 0b000 /* LB */:
populateLOAD(disasm, insncode, "lb");
break;
case 0b001 /* LH */:
populateLOAD(disasm, insncode, "lh");
break;
case 0b010 /* LW */:
populateLOAD(disasm, insncode, "lw");
break;
case 0b011 /* LD 64 bit */:
populateLOAD(disasm, insncode, "ld");
break;
case 0b100 /* LBU */:
populateLOAD(disasm, insncode, "lbu");
break;
case 0b101 /* LHU */:
populateLOAD(disasm, insncode, "lhu");
break;
}
break;

case OPCODE_STORE:
switch (funct3) {
case 0b000 /* sb */:
populateSTORE(disasm, insncode, "sb");
break;
case 0b001 /* sh */:
populateSTORE(disasm, insncode, "sh");
break;
case 0b010 /* sw */:
populateSTORE(disasm, insncode, "sw");
break;
case 0b011 /* sd 64 bit */:
populateSTORE(disasm, insncode, "sd");
break;
}
break;

case OPCODE_MISC_MEM:
break;

case OPCODE_SYSTEM:
switch (funct3) {
case 0b000 /* ECALL/EBREAK */:
switch (getItypeImmediate(insncode) /* funct12 */) {
case 0:
if (getRS1(insncode) == 0 && getRD(insncode) == 0) {
strcpy(disasm->instruction.mnemonic, "ecall");
}
break;
case 1:
if (getRS1(insncode) == 0 && getRD(insncode) == 0) {
strcpy(disasm->instruction.mnemonic, "ebreak");
}
break;
}
break;
case 0b001 /* CSRRW */:
//strcpy(disasm->instruction.mnemonic, "cssrw");
break;
case 0b010 /* CSRRS */:
//strcpy(disasm->instruction.mnemonic, "csrrs");
break;
case 0b011 /* CSRRC */:
//strcpy(disasm->instruction.mnemonic, "csrrc");
break;
case 0b101 /* CSRRWI */:
//strcpy(disasm->instruction.mnemonic, "csrrwi");
break;
case 0b110 /* CSRRSI */:
//strcpy(disasm->instruction.mnemonic, "csrri");
break;
case 0b111 /* CSRRCI */:
//strcpy(disasm->instruction.mnemonic, "csrrci");
break;
}
break;
default:
break;
}
Expand Down
1 change: 1 addition & 0 deletions RISCVTests/RISCVTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ - (void)testGetUJTypeImmediate {

- (void)testGetBTypeImmediate {
XCTAssertEqual(getBtypeImmediate(0x04051063), 0x40);
XCTAssertEqual(getBtypeImmediate(0xfed79ae3), -0xc);
}

- (void)testGetShamt64 {
Expand Down

0 comments on commit ab27e06

Please sign in to comment.