arch-riscv: Make use of ImmOp's polymorphism
authorAlec Roelke <ar4jc@virginia.edu>
Sat, 2 Dec 2017 17:58:14 +0000 (12:58 -0500)
committerAlec Roelke <ar4jc@virginia.edu>
Wed, 10 Jan 2018 16:07:02 +0000 (16:07 +0000)
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>

src/arch/riscv/isa/decoder.isa
src/arch/riscv/isa/formats/compressed.isa
src/arch/riscv/isa/formats/standard.isa
tests/test-progs/insttest/bin/riscv/linux-rv64i/insttest
tests/test-progs/insttest/src/riscv/rv64i.cpp

index 2761faca13bea844f09bd3e4677043144a73fd4f..435266c4f86abdcbcd73844cbb5817c83dae5495 100644 (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;
                 }});
index 3c47a906f4e7af3deca26ae193245b22c583c17b..03b7fb179295541d341028ccb4d0caa2a253909f 100644 (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)
index 517313d70438e1c426c34fbe316a89085dfb1fb8..ebe157160bb25e7159f67751b6cf29e456081f16 100644 (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)
index a6e5d0203886ae819da81e0f8a7212a1a482c075..c5a21739d396ce6177d055072712771adcd29e0f 100755 (executable)
Binary files a/tests/test-progs/insttest/bin/riscv/linux-rv64i/insttest and b/tests/test-progs/insttest/bin/riscv/linux-rv64i/insttest differ
index 95e8ee02ad077e596a71bfa1c1382df13f20a928..cfe5e298d0a3774f08f2027b1774fdd491edc90b 100644 (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)");