arch-riscv: Make use of ImmOp's polymorphism

This patch makes use of ImmOp's polymorphism to remove unnecessary
casting from the implementations of arithmetic instructions with
immediate operands and to remove the CUIOp format by combining it with
the CIOp format (compressed arithmetic instructions with immediate
operands). Interestingly, RISC-V specifies that instructions with
unsigned immediate operands still need to sign-extend the immediates
from 12 (or 20) bits to 64 bits, so that is left alone.

Change-Id: If20d70c1e90f379b9ed8a4155b2b9222b6defe16
Reviewed-on: https://gem5-review.googlesource.com/6401
Reviewed-by: Jason Lowe-Power <jason@lowepower.com>
Reviewed-by: Tuan Ta <qtt2@cornell.edu>
Maintainer: Alec Roelke <ar4jc@virginia.edu>
This commit is contained in:
Alec Roelke
2017-12-02 12:58:14 -05:00
parent 78524bda56
commit e228943538
5 changed files with 25 additions and 35 deletions

View File

@@ -36,7 +36,7 @@
decode QUADRANT default Unknown::unknown() {
0x0: decode COPCODE {
0x0: CUIOp::c_addi4spn({{
0x0: CIOp::c_addi4spn({{
imm = CIMM8<1:1> << 2 |
CIMM8<0:0> << 3 |
CIMM8<7:6> << 4 |
@@ -45,7 +45,7 @@ decode QUADRANT default Unknown::unknown() {
if (machInst == 0)
fault = make_shared<IllegalInstFault>("zero instruction");
Rp2 = sp + imm;
}});
}}, uint64_t);
format CompressedLoad {
0x1: c_fld({{
offset = CIMM3 << 3 | CIMM2 << 6;
@@ -152,26 +152,26 @@ decode QUADRANT default Unknown::unknown() {
}
}
0x4: decode CFUNCT2HIGH {
format CUIOp {
format CIOp {
0x0: c_srli({{
imm = CIMM5 | (CIMM1 << 5);
assert(imm != 0);
}}, {{
Rp1 = Rp1 >> imm;
}});
}}, uint64_t);
0x1: c_srai({{
imm = CIMM5 | (CIMM1 << 5);
assert(imm != 0);
}}, {{
Rp1_sd = Rp1_sd >> imm;
}});
}}, uint64_t);
0x2: c_andi({{
imm = CIMM5;
if (CIMM1 > 0)
imm |= ~((uint64_t)0x1F);
}}, {{
Rp1 = Rp1 & imm;
}});
}}, uint64_t);
}
format ROp {
0x3: decode CFUNCT1 {
@@ -242,13 +242,13 @@ decode QUADRANT default Unknown::unknown() {
}
}
0x2: decode COPCODE {
0x0: CUIOp::c_slli({{
0x0: CIOp::c_slli({{
imm = CIMM5 | (CIMM1 << 5);
assert(imm != 0);
}}, {{
assert(RC1 != 0);
Rc1 = Rc1 << imm;
}});
}}, uint64_t);
format CompressedLoad {
0x1: c_fldsp({{
offset = CIMM5<4:3> << 3 |
@@ -376,9 +376,9 @@ decode QUADRANT default Unknown::unknown() {
0x03: decode FUNCT3 {
format IOp {
0x0: fence({{
}}, IsNonSpeculative, IsMemBarrier, No_OpClass);
}}, uint64_t, IsNonSpeculative, IsMemBarrier, No_OpClass);
0x1: fence_i({{
}}, IsNonSpeculative, IsSerializeAfter, No_OpClass);
}}, uint64_t, IsNonSpeculative, IsSerializeAfter, No_OpClass);
}
}
@@ -394,11 +394,11 @@ decode QUADRANT default Unknown::unknown() {
Rd = (Rs1_sd < imm) ? 1 : 0;
}});
0x3: sltiu({{
Rd = (Rs1 < (uint64_t)imm) ? 1 : 0;
}});
Rd = (Rs1 < imm) ? 1 : 0;
}}, uint64_t);
0x4: xori({{
Rd = Rs1 ^ (uint64_t)imm;
}});
Rd = Rs1 ^ imm;
}}, uint64_t);
0x5: decode SRTYPE {
0x0: srli({{
Rd = Rs1 >> SHAMT6;
@@ -408,11 +408,11 @@ decode QUADRANT default Unknown::unknown() {
}});
}
0x6: ori({{
Rd = Rs1 | (uint64_t)imm;
}});
Rd = Rs1 | imm;
}}, uint64_t);
0x7: andi({{
Rd = Rs1 & (uint64_t)imm;
}});
Rd = Rs1 & imm;
}}, uint64_t);
}
}
@@ -423,8 +423,8 @@ decode QUADRANT default Unknown::unknown() {
0x06: decode FUNCT3 {
format IOp {
0x0: addiw({{
Rd_sd = (int32_t)Rs1 + (int32_t)imm;
}});
Rd_sd = Rs1_sw + imm;
}}, int32_t);
0x1: slliw({{
Rd_sd = Rs1_sw << SHAMT5;
}});

View File

@@ -36,20 +36,9 @@ def format CROp(code, *opt_flags) {{
exec_output = BasicExecute.subst(iop)
}};
def format CIOp(imm_code, code, *opt_flags) {{
def format CIOp(imm_code, code, imm_type='int64_t', *opt_flags) {{
regs = ['_destRegIdx[0]','_srcRegIdx[0]']
iop = InstObjParams(name, Name, 'ImmOp<int64_t>',
{'code': code, 'imm_code': imm_code,
'regs': ','.join(regs)}, opt_flags)
header_output = ImmDeclare.subst(iop)
decoder_output = ImmConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
exec_output = ImmExecute.subst(iop)
}};
def format CUIOp(imm_code, code, *opt_flags) {{
regs = ['_destRegIdx[0]','_srcRegIdx[0]']
iop = InstObjParams(name, Name, 'ImmOp<uint64_t>',
iop = InstObjParams(name, Name, 'ImmOp<%s>' % imm_type,
{'code': code, 'imm_code': imm_code,
'regs': ','.join(regs)}, opt_flags)
header_output = ImmDeclare.subst(iop)

View File

@@ -218,9 +218,9 @@ def format ROp(code, *opt_flags) {{
exec_output = BasicExecute.subst(iop)
}};
def format IOp(code, *opt_flags) {{
def format IOp(code, imm_type='int64_t', *opt_flags) {{
regs = ['_destRegIdx[0]','_srcRegIdx[0]']
iop = InstObjParams(name, Name, 'ImmOp<int64_t>',
iop = InstObjParams(name, Name, 'ImmOp<%s>' % imm_type,
{'code': code, 'imm_code': 'imm = sext<12>(IMM12);',
'regs': ','.join(regs)}, opt_flags)
header_output = ImmDeclare.subst(iop)

View File

@@ -137,6 +137,7 @@ int main()
// SLTIU
expect<bool>(false, []{return I::sltiu(-1, 0);}, "sltiu, false");
expect<bool>(true, []{return I::sltiu(0, -1);}, "sltiu, true");
expect<bool>(true, []{return I::sltiu(0xFFFF, -1);}, "sltiu, sext");
// XORI
expect<uint64_t>(0xFF, []{return I::xori(0xAA, 0x55);}, "xori (1)");