From c06b1817297b4486c372950b4f65d34417aa01d0 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Fri, 21 Aug 2015 14:06:57 -0700 Subject: target-tilegx: Handle bitfield instructions Reviewed-by: Peter Maydell Signed-off-by: Richard Henderson --- target-tilegx/translate.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) (limited to 'target-tilegx') diff --git a/target-tilegx/translate.c b/target-tilegx/translate.c index 168b4da3c6..ba56a2ebcc 100644 --- a/target-tilegx/translate.c +++ b/target-tilegx/translate.c @@ -1125,13 +1125,87 @@ static TileExcp gen_bf_opcode_x0(DisasContext *dc, unsigned ext, unsigned dest, unsigned srca, unsigned bfs, unsigned bfe) { + TCGv tdest = dest_gr(dc, dest); + TCGv tsrca = load_gr(dc, srca); + TCGv tsrcd; + int len; const char *mnemonic; + /* The bitfield is either between E and S inclusive, + or up from S and down from E inclusive. */ + if (bfs <= bfe) { + len = bfe - bfs + 1; + } else { + len = (64 - bfs) + (bfe + 1); + } + switch (ext) { case BFEXTU_BF_OPCODE_X0: + if (bfs == 0 && bfe == 7) { + tcg_gen_ext8u_tl(tdest, tsrca); + } else if (bfs == 0 && bfe == 15) { + tcg_gen_ext16u_tl(tdest, tsrca); + } else if (bfs == 0 && bfe == 31) { + tcg_gen_ext32u_tl(tdest, tsrca); + } else { + int rol = 63 - bfe; + if (bfs <= bfe) { + tcg_gen_shli_tl(tdest, tsrca, rol); + } else { + tcg_gen_rotli_tl(tdest, tsrca, rol); + } + tcg_gen_shri_tl(tdest, tdest, (bfs + rol) & 63); + } + mnemonic = "bfextu"; + break; + case BFEXTS_BF_OPCODE_X0: + if (bfs == 0 && bfe == 7) { + tcg_gen_ext8s_tl(tdest, tsrca); + } else if (bfs == 0 && bfe == 15) { + tcg_gen_ext16s_tl(tdest, tsrca); + } else if (bfs == 0 && bfe == 31) { + tcg_gen_ext32s_tl(tdest, tsrca); + } else { + int rol = 63 - bfe; + if (bfs <= bfe) { + tcg_gen_shli_tl(tdest, tsrca, rol); + } else { + tcg_gen_rotli_tl(tdest, tsrca, rol); + } + tcg_gen_sari_tl(tdest, tdest, (bfs + rol) & 63); + } + mnemonic = "bfexts"; + break; + case BFINS_BF_OPCODE_X0: + tsrcd = load_gr(dc, dest); + if (bfs <= bfe) { + tcg_gen_deposit_tl(tdest, tsrcd, tsrca, bfs, len); + } else { + tcg_gen_rotri_tl(tdest, tsrcd, bfs); + tcg_gen_deposit_tl(tdest, tdest, tsrca, 0, len); + tcg_gen_rotli_tl(tdest, tdest, bfs); + } + mnemonic = "bfins"; + break; + case MM_BF_OPCODE_X0: + tsrcd = load_gr(dc, dest); + if (bfs == 0) { + tcg_gen_deposit_tl(tdest, tsrca, tsrcd, 0, len); + } else { + uint64_t mask = len == 64 ? -1 : rol64((1ULL << len) - 1, bfs); + TCGv tmp = tcg_const_tl(mask); + + tcg_gen_and_tl(tdest, tsrcd, tmp); + tcg_gen_andc_tl(tmp, tsrca, tmp); + tcg_gen_or_tl(tdest, tdest, tmp); + tcg_temp_free(tmp); + } + mnemonic = "mm"; + break; + default: return TILEGX_EXCP_OPCODE_UNIMPLEMENTED; } -- cgit v1.2.1