On 11/16/22 23:03, Weiwei Li wrote:
Add encode, trans* functions for Zcmp instructions
Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn>
Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
---
target/riscv/insn16.decode | 18 ++
target/riscv/insn_trans/trans_rvzce.c.inc | 242 +++++++++++++++++++++-
target/riscv/translate.c | 5 +
3 files changed, 264 insertions(+), 1 deletion(-)
Better, though...
+static bool gen_zcmp_check(DisasContext *ctx, arg_zcmp *a)
+{
+ /* rlist 0 to 3 are reserved for future EABI variant */
+ if (a->zcmp_rlist < 4) {
+ return false;
+ }
+
+ /* rlist <= 6 when RV32E/RV64E */
+ if (ctx->cfg_ptr->ext_e && a->zcmp_rlist > 6) {
+ return false;
+ }
+
+ return true;
+}
This could be merged into...
+
+#define X_S0 8
+#define X_S1 9
+#define X_Sn 16
+
+static inline void update_push_pop_list(target_ulong rlist, bool
*xreg_list)
... here.
For instance, one way is to return false when the list is invalid.
Better is to return a uint32_t bitmap of the registers in the list,
with 0 indicating invalid.
Nit 1: Remove the inline.
Nit 2: A better name might be decode_push_pop_list.
+static inline target_ulong caculate_stack_adj(int bytes,
target_ulong rlist,
+ target_ulong spimm)
+{
+ target_ulong stack_adj_base = 0;
+ switch (rlist) {
+ case 15:
+ stack_adj_base = bytes == 4 ? 64 : 112;
+ break;
+ case 14:
+ stack_adj_base = bytes == 4 ? 48 : 96;
+ break;
+ case 13:
+ case 12:
+ stack_adj_base = bytes == 4 ? 48 : 80;
+ break;
+ case 11:
+ case 10:
+ stack_adj_base = bytes == 4 ? 32 : 64;
+ break;
+ case 9:
+ case 8:
+ stack_adj_base = bytes == 4 ? 32 : 48;
+ break;
+ case 7:
+ case 6:
+ stack_adj_base = bytes == 4 ? 16 : 32;
+ break;
+ case 5:
+ case 4:
+ stack_adj_base = 16;
+ break;
+ }
I really dislike this, as it replicates the decoding done just above.
I think this ought to be simply:
ROUND_UP(ctpop32(reg_bitmap) * reg_size, 16) + spimm
+ switch (bytes) {
+ case 4:
+ tcg_gen_qemu_ld_tl(dest, addr, ctx->mem_idx, MO_32);
+ break;
+ case 8:
+ tcg_gen_qemu_ld_tl(dest, addr, ctx->mem_idx, MO_64);
+ break;
+ default:
+ break;
+ }
These are incorrect in that they do not indicate the target endianness.
Better to merge the two using the common memop computed above:
tcg_gen_qemu_ld_tl(dest, addr, ctx->mem_idx, memop);