arch-riscv: Refactor compressed instructions
1. C.JAL should use CJOp format to generate code 2. Use sext function to handle MSB for immediate 3. Add IsCall flags to c.jal, c.jalr 4. Use JumpConstructor to CJOp format Change-Id: Id01c0d7cc1a3e17776890268879c568fc9996bc5 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/66732 Reviewed-by: Yu-hsin Wang <yuhsingw@google.com> Maintainer: Jason Lowe-Power <power.jg@gmail.com> Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
@@ -47,7 +47,7 @@ decode QUADRANT default Unknown::unknown() {
|
||||
CIMM8<7:6> << 4 |
|
||||
CIMM8<5:2> << 6;
|
||||
}}, {{
|
||||
if (machInst == 0)
|
||||
if (imm == 0)
|
||||
return std::make_shared<IllegalInstFault>("zero instruction",
|
||||
machInst);
|
||||
Rp2 = rvSext(sp + imm);
|
||||
@@ -147,91 +147,71 @@ decode QUADRANT default Unknown::unknown() {
|
||||
}
|
||||
}
|
||||
0x1: decode COPCODE {
|
||||
format CIOp {
|
||||
0x0: c_addi({{
|
||||
imm = CIMM5;
|
||||
if (CIMM1 > 0)
|
||||
imm |= ~((uint64_t)0x1F);
|
||||
}}, {{
|
||||
if ((RC1 == 0) != (imm == 0)) {
|
||||
if (RC1 == 0) {
|
||||
return std::make_shared<IllegalInstFault>(
|
||||
"source reg x0", machInst);
|
||||
} else { // imm == 0
|
||||
return std::make_shared<IllegalInstFault>(
|
||||
"immediate = 0", machInst);
|
||||
}
|
||||
0x0: CIOp::c_addi({{
|
||||
imm = sext<6>(CIMM5 | (CIMM1 << 5));
|
||||
}}, {{
|
||||
if ((RC1 == 0) != (imm == 0)) {
|
||||
if (RC1 == 0) {
|
||||
return std::make_shared<IllegalInstFault>(
|
||||
"source reg x0", machInst);
|
||||
} else { // imm == 0
|
||||
return std::make_shared<IllegalInstFault>(
|
||||
"immediate = 0", machInst);
|
||||
}
|
||||
Rc1_sd = rvSext(Rc1_sd + imm);
|
||||
}});
|
||||
0x1: decode RVTYPE {
|
||||
0x0: c_jal({{
|
||||
imm = sext<12>((CJUMPIMM3TO1 << 1) |
|
||||
(CJUMPIMM4TO4 << 4) |
|
||||
(CJUMPIMM5TO5 << 5) |
|
||||
(CJUMPIMM6TO6 << 6) |
|
||||
(CJUMPIMM7TO7 << 7) |
|
||||
(CJUMPIMM9TO8 << 8) |
|
||||
(CJUMPIMM10TO10 << 10) |
|
||||
(CJUMPIMMSIGN << 11));
|
||||
}}, {{
|
||||
ra_sw = NPC_uw;
|
||||
NPC_uw = PC_uw + imm;
|
||||
}});
|
||||
0x1: c_addiw({{
|
||||
imm = CIMM5;
|
||||
if (CIMM1 > 0)
|
||||
imm |= ~((uint64_t)0x1F);
|
||||
}}, {{
|
||||
if (RC1 == 0) {
|
||||
return std::make_shared<IllegalInstFault>(
|
||||
"source reg x0", machInst);
|
||||
}
|
||||
Rc1_sw = (int32_t)(Rc1_sw + imm);
|
||||
}});
|
||||
}
|
||||
0x2: c_li({{
|
||||
imm = CIMM5;
|
||||
if (CIMM1 > 0)
|
||||
imm |= ~((uint64_t)0x1F);
|
||||
Rc1_sd = rvSext(Rc1_sd + imm);
|
||||
}});
|
||||
0x1: decode RVTYPE {
|
||||
0x0: CJOp::c_jal({{
|
||||
ra_sw = NPC_uw;
|
||||
NPC_uw = PC_uw + imm;
|
||||
}}, IsDirectControl, IsUncondControl, IsCall);
|
||||
0x1: CIOp::c_addiw({{
|
||||
imm = sext<6>(CIMM5 | (CIMM1 << 5));
|
||||
}}, {{
|
||||
if (RC1 == 0) {
|
||||
return std::make_shared<IllegalInstFault>(
|
||||
"source reg x0", machInst);
|
||||
}
|
||||
Rc1_sw = (int32_t)(Rc1_sw + imm);
|
||||
}});
|
||||
}
|
||||
0x2: CIOp::c_li({{
|
||||
imm = sext<6>(CIMM5 | (CIMM1 << 5));
|
||||
}}, {{
|
||||
if (RC1 == 0) {
|
||||
return std::make_shared<IllegalInstFault>(
|
||||
"source reg x0", machInst);
|
||||
}
|
||||
Rc1_sd = imm;
|
||||
}});
|
||||
0x3: decode RC1 {
|
||||
0x2: CIOp::c_addi16sp({{
|
||||
imm = sext<10>((CIMM5<4:4> << 4) |
|
||||
(CIMM5<0:0> << 5) |
|
||||
(CIMM5<3:3> << 6) |
|
||||
(CIMM5<2:1> << 7) |
|
||||
(CIMM1 << 9));
|
||||
}}, {{
|
||||
if (imm == 0) {
|
||||
return std::make_shared<IllegalInstFault>(
|
||||
"immediate = 0", machInst);
|
||||
}
|
||||
sp_sd = rvSext(sp_sd + imm);
|
||||
}});
|
||||
default: CIOp::c_lui({{
|
||||
imm = sext<6>(CIMM5 | (CIMM1 << 5)) << 12;
|
||||
}}, {{
|
||||
if (RC1 == 0 || RC1 == 2) {
|
||||
return std::make_shared<IllegalInstFault>(
|
||||
"source reg x0", machInst);
|
||||
}
|
||||
if (imm == 0) {
|
||||
return std::make_shared<IllegalInstFault>(
|
||||
"immediate = 0", machInst);
|
||||
}
|
||||
Rc1_sd = imm;
|
||||
}});
|
||||
0x3: decode RC1 {
|
||||
0x2: c_addi16sp({{
|
||||
imm = CIMM5<4:4> << 4 |
|
||||
CIMM5<0:0> << 5 |
|
||||
CIMM5<3:3> << 6 |
|
||||
CIMM5<2:1> << 7;
|
||||
if (CIMM1 > 0)
|
||||
imm |= ~((int64_t)0x1FF);
|
||||
}}, {{
|
||||
if (imm == 0) {
|
||||
return std::make_shared<IllegalInstFault>(
|
||||
"immediate = 0", machInst);
|
||||
}
|
||||
sp_sd = rvSext(sp_sd + imm);
|
||||
}});
|
||||
default: c_lui({{
|
||||
imm = CIMM5 << 12;
|
||||
if (CIMM1 > 0)
|
||||
imm |= ~((uint64_t)0x1FFFF);
|
||||
}}, {{
|
||||
if (RC1 == 0 || RC1 == 2) {
|
||||
return std::make_shared<IllegalInstFault>(
|
||||
"source reg x0", machInst);
|
||||
}
|
||||
if (imm == 0) {
|
||||
return std::make_shared<IllegalInstFault>(
|
||||
"immediate = 0", machInst);
|
||||
}
|
||||
Rc1_sd = imm;
|
||||
}});
|
||||
}
|
||||
}
|
||||
0x4: decode CFUNCT2HIGH {
|
||||
format CIOp {
|
||||
@@ -418,7 +398,7 @@ decode QUADRANT default Unknown::unknown() {
|
||||
}
|
||||
ra = rvSext(NPC);
|
||||
NPC = rvZext(Rc1);
|
||||
}}, IsIndirectControl, IsUncondControl);
|
||||
}}, IsIndirectControl, IsUncondControl, IsCall);
|
||||
default: CompressedROp::c_add({{
|
||||
Rc1_sd = rvSext(Rc1_sd + Rc2_sd);
|
||||
}});
|
||||
|
||||
@@ -61,33 +61,31 @@ def format CIOp(imm_code, code, imm_type='int64_t', *opt_flags) {{
|
||||
|
||||
def format CJOp(code, *opt_flags) {{
|
||||
imm_code = """
|
||||
imm = CJUMPIMM3TO1 << 1 |
|
||||
CJUMPIMM4TO4 << 4 |
|
||||
CJUMPIMM5TO5 << 5 |
|
||||
CJUMPIMM6TO6 << 6 |
|
||||
CJUMPIMM7TO7 << 7 |
|
||||
CJUMPIMM9TO8 << 8 |
|
||||
CJUMPIMM10TO10 << 10;
|
||||
if (CJUMPIMMSIGN)
|
||||
imm |= ~((int64_t)0x7FF);
|
||||
imm = sext<12>((CJUMPIMM3TO1 << 1) |
|
||||
(CJUMPIMM4TO4 << 4) |
|
||||
(CJUMPIMM5TO5 << 5) |
|
||||
(CJUMPIMM6TO6 << 6) |
|
||||
(CJUMPIMM7TO7 << 7) |
|
||||
(CJUMPIMM9TO8 << 8) |
|
||||
(CJUMPIMM10TO10 << 10) |
|
||||
(CJUMPIMMSIGN << 11));
|
||||
"""
|
||||
iop = InstObjParams(name, Name, 'ImmOp<int64_t>',
|
||||
{'code': code, 'imm_code': imm_code,
|
||||
'regs': ''}, opt_flags)
|
||||
header_output = BranchDeclare.subst(iop)
|
||||
decoder_output = ImmConstructor.subst(iop)
|
||||
decoder_output = JumpConstructor.subst(iop)
|
||||
decode_block = BasicDecode.subst(iop)
|
||||
exec_output = BranchExecute.subst(iop)
|
||||
}};
|
||||
|
||||
def format CBOp(code, *opt_flags) {{
|
||||
imm_code = """
|
||||
imm = CIMM5<2:1> << 1 |
|
||||
CIMM3<1:0> << 3 |
|
||||
CIMM5<0:0> << 5 |
|
||||
CIMM5<4:3> << 6;
|
||||
if (CIMM3<2:2> > 0)
|
||||
imm |= ~((int64_t)0xFF);
|
||||
imm = sext<9>((CIMM5<2:1> << 1) |
|
||||
(CIMM3<1:0> << 3) |
|
||||
(CIMM5<0:0> << 5) |
|
||||
(CIMM5<4:3> << 6) |
|
||||
(CIMM3<2:2> << 8));
|
||||
"""
|
||||
regs = 'srcRegIdx(0)'
|
||||
iop = InstObjParams(name, Name, 'ImmOp<int64_t>',
|
||||
|
||||
Reference in New Issue
Block a user