From 0746a40275c904b1285913c390f42bf07d0c90b7 Mon Sep 17 00:00:00 2001 From: Yen-Fu Chen Date: Tue, 26 Sep 2023 16:23:45 +0800 Subject: [PATCH] Fix constant optimization and fused instruction 1. Fix tailcall updating in fused instructions 2. Fix errors in constant optimization Close: #228 --- src/emulate.c | 18 ++++++++++-------- src/rv32_constopt.c | 22 ++++++++++++---------- 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/src/emulate.c b/src/emulate.c index cd1a0bd25..b2d77f63e 100644 --- a/src/emulate.c +++ b/src/emulate.c @@ -926,6 +926,7 @@ static void match_pattern(block_t *block) ir->rs2 = next_ir->rd; ir->rs1 = next_ir->rs1; ir->impl = dispatch_table[ir->opcode]; + ir->tailcall = next_ir->tailcall; } else if (next_ir->opcode == rv_insn_add && ir->rd == next_ir->rs1) { /* The destination register of the LUI instruction is the @@ -935,21 +936,22 @@ static void match_pattern(block_t *block) ir->rs2 = next_ir->rd; ir->rs1 = next_ir->rs2; ir->impl = dispatch_table[ir->opcode]; - } else { + ir->tailcall = next_ir->tailcall; + } else if (next_ir->opcode == rv_insn_lui) { count = 1; - next_ir = ir + 1; while (1) { if (next_ir->opcode != rv_insn_lui) break; next_ir->opcode = rv_insn_nop; count++; - next_ir += 1; - } - if (count > 1) { - ir->imm2 = count; - ir->opcode = rv_insn_fuse1; - ir->impl = dispatch_table[ir->opcode]; + if (next_ir->tailcall) + break; + next_ir++; } + ir->imm2 = count; + ir->opcode = rv_insn_fuse1; + ir->impl = dispatch_table[ir->opcode]; + ir->tailcall = next_ir->tailcall; } break; diff --git a/src/rv32_constopt.c b/src/rv32_constopt.c index af9e92213..a2ec2b0ce 100644 --- a/src/rv32_constopt.c +++ b/src/rv32_constopt.c @@ -443,8 +443,8 @@ CONSTOPT(mulh, { if (constopt_info->is_constant[ir->rs1] && constopt_info->is_constant[ir->rs2]) { constopt_info->is_constant[ir->rd] = true; - const int64_t a = constopt_info->const_val[ir->rs1]; - const int64_t b = constopt_info->const_val[ir->rs2]; + const int64_t a = (int32_t) constopt_info->const_val[ir->rs1]; + const int64_t b = (int32_t) constopt_info->const_val[ir->rs2]; ir->imm = ((uint64_t) (a * b)) >> 32; constopt_info->const_val[ir->rd] = ir->imm; ir->opcode = rv_insn_lui; @@ -457,7 +457,6 @@ CONSTOPT(mulh, { CONSTOPT(mulhsu, { if (constopt_info->is_constant[ir->rs1] && constopt_info->is_constant[ir->rs2]) { - printf("OPT MUL\n"); constopt_info->is_constant[ir->rd] = true; const int64_t a = (int32_t) constopt_info->const_val[ir->rs1]; const int64_t b = constopt_info->const_val[ir->rs2]; @@ -757,7 +756,7 @@ CONSTOPT(csw, {}) CONSTOPT(caddi, { if (constopt_info->is_constant[ir->rd]) { constopt_info->is_constant[ir->rd] = true; - ir->imm = constopt_info->const_val[ir->rd] + (uint16_t) ir->imm; + ir->imm = constopt_info->const_val[ir->rd] + (int16_t) ir->imm; constopt_info->const_val[ir->rd] = ir->imm; ir->opcode = rv_insn_clui; ir->impl = dispatch_table[ir->opcode]; @@ -768,7 +767,7 @@ CONSTOPT(caddi, { /* C.JAL */ CONSTOPT(cjal, { constopt_info->is_constant[rv_reg_ra] = true; - constopt_info->const_val[ir->rd] = ir->pc + ir->insn_len; + constopt_info->const_val[rv_reg_ra] = ir->pc + ir->insn_len; }) /* C.LI loads the sign-extended 6-bit immediate, imm, into register rd. @@ -817,7 +816,8 @@ CONSTOPT(csrli, { if (constopt_info->is_constant[ir->rs1]) { constopt_info->is_constant[ir->rs1] = true; ir->imm = constopt_info->const_val[ir->rs1] >> ir->shamt; - constopt_info->const_val[ir->rd] = ir->imm; + constopt_info->const_val[ir->rs1] = ir->imm; + ir->rd = ir->rs1; ir->opcode = rv_insn_clui; ir->impl = dispatch_table[ir->opcode]; } else @@ -834,7 +834,8 @@ CONSTOPT(csrai, { ir->imm = constopt_info->const_val[ir->rs1] >> ir->shamt; for (unsigned int i = 0; i < ir->shamt; ++i) ir->imm |= mask >> i; - constopt_info->const_val[ir->rd] = ir->imm; + constopt_info->const_val[ir->rs1] = ir->imm; + ir->rd = ir->rs1; ir->opcode = rv_insn_clui; ir->impl = dispatch_table[ir->opcode]; } else @@ -848,8 +849,9 @@ CONSTOPT(csrai, { CONSTOPT(candi, { if (constopt_info->is_constant[ir->rs1]) { constopt_info->is_constant[ir->rs1] = true; - ir->imm = constopt_info->const_val[ir->rs1] & ir->shamt; - constopt_info->const_val[ir->rd] = ir->imm; + ir->imm = constopt_info->const_val[ir->rs1] & ir->imm; + constopt_info->const_val[ir->rs1] = ir->imm; + ir->rd = ir->rs1; ir->opcode = rv_insn_clui; ir->impl = dispatch_table[ir->opcode]; } else @@ -948,7 +950,7 @@ CONSTOPT(cbnez, { CONSTOPT(cslli, { if (constopt_info->is_constant[ir->rd]) { constopt_info->is_constant[ir->rd] = true; - ir->imm = constopt_info->const_val[ir->rs2] << (uint8_t) ir->imm; + ir->imm = constopt_info->const_val[ir->rd] << (uint8_t) ir->imm; constopt_info->const_val[ir->rd] = ir->imm; ir->opcode = rv_insn_clui; ir->impl = dispatch_table[ir->opcode];