From: Yongbok Kim <yongbok.kim@mips.com>
To: qemu-devel@nongnu.org
Cc: aurelien@aurel32.net, Aleksandar.Markovic@mips.com,
James.Hogan@mips.com, Paul.Burton@mips.com,
Matthew.Fortune@mips.com, Stefan.Markovic@mips.com
Subject: [Qemu-devel] [PATCH 18/35] target/mips: Add nanoMIPS branch instructions
Date: Wed, 20 Jun 2018 13:06:03 +0100 [thread overview]
Message-ID: <20180620120620.12806-19-yongbok.kim@mips.com> (raw)
In-Reply-To: <20180620120620.12806-1-yongbok.kim@mips.com>
Add nanoMIPS branch instructions
Signed-off-by: Yongbok Kim <yongbok.kim@mips.com>
---
target/mips/translate.c | 277 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 277 insertions(+)
diff --git a/target/mips/translate.c b/target/mips/translate.c
index 08765a7..948d3d5 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -16597,6 +16597,168 @@ static void gen_pool32axf_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
}
}
+/* Immediate Value Compact Branches */
+static void gen_compute_imm_branch(DisasContext *ctx, uint32_t opc,
+ int rt, int32_t imm, int32_t offset)
+{
+ int bcond_compute = 0;
+ TCGv t0 = tcg_temp_new();
+ TCGv t1 = tcg_temp_new();
+
+ if (ctx->hflags & MIPS_HFLAG_BMASK) {
+#ifdef MIPS_DEBUG_DISAS
+ LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
+ "\n", ctx->base.pc_next);
+#endif
+ generate_exception_end(ctx, EXCP_RI);
+ goto out;
+ }
+
+ gen_load_gpr(t0, rt);
+ tcg_gen_movi_tl(t1, imm);
+ ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
+
+ /* Load needed operands and calculate btarget */
+ switch (opc) {
+ case NM_BEQIC:
+ if (rt == 0 && imm == 0) {
+ /* Unconditional branch */
+ } else if (rt == 0 && imm != 0) {
+ /* Treat as NOP */
+ goto out;
+ } else {
+ bcond_compute = 1;
+ }
+ break;
+ case NM_BBEQZC:
+ case NM_BBNEZC:
+ if (imm >= 32 && !(ctx->hflags & MIPS_HFLAG_64)) {
+ generate_exception_end(ctx, EXCP_RI);
+ goto out;
+ } else if (rt == 0 && opc == NM_BBEQZC) {
+ /* Unconditional branch */
+ } else if (rt == 0 && opc == NM_BBNEZC) {
+ /* Treat as NOP */
+ goto out;
+ } else {
+ tcg_gen_shri_tl(t0, t0, imm);
+ tcg_gen_andi_tl(t0, t0, 1);
+ tcg_gen_movi_tl(t1, 0);
+ bcond_compute = 1;
+ }
+ break;
+ case NM_BNEIC:
+ if (rt == 0 && imm == 0) {
+ /* Treat as NOP */
+ goto out;
+ } else if (rt == 0 && imm != 0) {
+ /* Unconditional branch */
+ } else {
+ bcond_compute = 1;
+ }
+ break;
+ case NM_BGEIC:
+ if (rt == 0 && imm == 0) {
+ /* Unconditional branch */
+ } else {
+ bcond_compute = 1;
+ }
+ break;
+ case NM_BLTIC:
+ bcond_compute = 1;
+ break;
+ case NM_BGEIUC:
+ if (rt == 0 && imm == 0) {
+ /* Unconditional branch */
+ } else {
+ bcond_compute = 1;
+ }
+ break;
+ case NM_BLTIUC:
+ bcond_compute = 1;
+ break;
+ default:
+ MIPS_INVAL("Immediate Value Compact branch");
+ generate_exception_end(ctx, EXCP_RI);
+ goto out;
+ }
+
+ if (bcond_compute == 0) {
+ /* Uncoditional compact branch */
+ ctx->hflags |= MIPS_HFLAG_B;
+ /* Generating branch here as compact branches don't have delay slot */
+ gen_branch(ctx, 4);
+ } else {
+ /* Conditional compact branch */
+ TCGLabel *fs = gen_new_label();
+ save_cpu_state(ctx, 0);
+
+ switch (opc) {
+ case NM_BEQIC:
+ tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs);
+ break;
+ case NM_BBEQZC:
+ tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs);
+ break;
+ case NM_BNEIC:
+ tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs);
+ break;
+ case NM_BBNEZC:
+ tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs);
+ break;
+ case NM_BGEIC:
+ tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
+ break;
+ case NM_BLTIC:
+ tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
+ break;
+ case NM_BGEIUC:
+ tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
+ break;
+ case NM_BLTIUC:
+ tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
+ break;
+ }
+
+ /* Generating branch here as compact branches don't have delay slot */
+ gen_goto_tb(ctx, 1, ctx->btarget);
+ gen_set_label(fs);
+
+ ctx->hflags |= MIPS_HFLAG_FBNSLOT;
+ }
+
+out:
+ tcg_temp_free(t0);
+ tcg_temp_free(t1);
+}
+
+/* P.BALRSC type nanoMIPS R6 branches: BALRSC and BRSC */
+static void gen_compute_nanomips_pbalrsc_branch(DisasContext *ctx, int rs,
+ int rt)
+{
+ TCGv t0 = tcg_temp_new();
+ TCGv t1 = tcg_temp_new();
+
+ /* load rs */
+ gen_load_gpr(t0, rs);
+
+ /* link */
+ if (rt != 0) {
+ tcg_gen_movi_tl(cpu_gpr[rt], ctx->base.pc_next + 4);
+ }
+
+ /* calculate btarget */
+ tcg_gen_shli_tl(t0, t0, 1);
+ tcg_gen_movi_tl(t1, ctx->base.pc_next + 4);
+ gen_op_addr_add(ctx, btarget, t1, t0);
+
+ ctx->hflags |= MIPS_HFLAG_BR;
+ /* Generating branch here as compact branches don't have delay slot */
+ gen_branch(ctx, 4);
+
+ tcg_temp_free(t0);
+ tcg_temp_free(t1);
+}
static void gen_p_lsx(DisasContext *ctx, int rd, int rs, int rt)
{
@@ -17656,16 +17818,131 @@ static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx)
}
break;
case NM_MOVE_BALC:
+ {
+ TCGv t0 = tcg_temp_new();
+ int32_t s = sextract32(ctx->opcode, 0, 1) << 21 |
+ extract32(ctx->opcode, 1, 20) << 1;
+ rd = ((ctx->opcode >> 24) & 1) == 0 ? 4 : 5;
+ rt = mmreg4z_nanomips(extract32(ctx->opcode, 25, 1) << 3 |
+ extract32(ctx->opcode, 21, 3));
+ gen_load_gpr(t0, rt);
+ tcg_gen_mov_tl(cpu_gpr[rd], t0);
+ gen_compute_branch(ctx, OPC_BGEZAL, 4, 0, 0, s, 0);
+ tcg_temp_free(t0);
+ }
break;
case NM_P_BAL:
+ {
+ int32_t s = sextract32(ctx->opcode, 0, 1) << 25 |
+ extract32(ctx->opcode, 1, 24) << 1;
+
+ if (((ctx->opcode >> 25) & 1) == 0) {
+ /* BC */
+ gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, s, 0);
+ } else {
+ /* BALC */
+ gen_compute_branch(ctx, OPC_BGEZAL, 4, 0, 0, s, 0);
+ }
+ }
break;
case NM_P_J:
+ switch ((ctx->opcode >> 12) & 0x0f) {
+ case NM_JALRC:
+ case NM_JALRC_HB:
+ gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 0);
+ break;
+ case NM_P_BALRSC:
+ gen_compute_nanomips_pbalrsc_branch(ctx, rs, rt);
+ break;
+ default:
+ generate_exception_end(ctx, EXCP_RI);
+ break;
+ }
break;
case NM_P_BR1:
+ {
+ int32_t s = sextract32(ctx->opcode, 0, 1) << 14 |
+ extract32(ctx->opcode, 1, 13) << 1;
+ switch ((ctx->opcode >> 14) & 0x03) {
+ case NM_BEQC:
+ gen_compute_branch(ctx, OPC_BEQ, 4, rs, rt, s, 0);
+ break;
+ case NM_P_BR3A:
+ {
+ int32_t s = sextract32(ctx->opcode, 0, 1) << 14 |
+ extract32(ctx->opcode, 1, 13) << 1;
+ check_cp1_enabled(ctx);
+ switch ((ctx->opcode >> 16) & 0x1f) {
+ case NM_BC1EQZC:
+ gen_compute_branch1_r6(ctx, OPC_BC1EQZ, rt, s, 0);
+ break;
+ case NM_BC1NEZC:
+ gen_compute_branch1_r6(ctx, OPC_BC1NEZ, rt, s, 0);
+ break;
+ default:
+ generate_exception_end(ctx, EXCP_RI);
+ break;
+ }
+ }
+ break;
+ case NM_BGEC:
+ if (rs == rt) {
+ gen_compute_compact_branch(ctx, OPC_BC, rs, rt, s);
+ } else {
+ gen_compute_compact_branch(ctx, OPC_BGEC, rs, rt, s);
+ }
+ break;
+ case NM_BGEUC:
+ if (rs == rt || rt == 0) {
+ gen_compute_compact_branch(ctx, OPC_BC, 0, 0, s);
+ } else if (rs == 0) {
+ gen_compute_compact_branch(ctx, OPC_BEQZC, rt, 0, s);
+ } else {
+ gen_compute_compact_branch(ctx, OPC_BGEUC, rs, rt, s);
+ }
+ break;
+ }
+ }
break;
case NM_P_BR2:
+ {
+ int32_t s = sextract32(ctx->opcode, 0, 1) << 14 |
+ extract32(ctx->opcode, 1, 13) << 1;
+ switch ((ctx->opcode >> 14) & 0x03) {
+ case NM_BNEC:
+ gen_compute_branch(ctx, OPC_BNE, 4, rs, rt, s, 0);
+ break;
+ case NM_BLTC:
+ if (rs != 0 && rt != 0 && rs == rt) {
+ /* NOP */
+ ctx->hflags |= MIPS_HFLAG_FBNSLOT;
+ } else {
+ gen_compute_compact_branch(ctx, OPC_BLTC, rs, rt, s);
+ }
+ break;
+ case NM_BLTUC:
+ if (rs == 0 || rs == rt) {
+ /* NOP */
+ ctx->hflags |= MIPS_HFLAG_FBNSLOT;
+ } else {
+ gen_compute_compact_branch(ctx, OPC_BLTUC, rs, rt, s);
+ }
+ break;
+ default:
+ generate_exception_end(ctx, EXCP_RI);
+ break;
+ }
+ }
break;
case NM_P_BRI:
+ {
+ int32_t s = sextract32(ctx->opcode, 0, 1) << 11 |
+ extract32(ctx->opcode, 1, 10) << 1;
+ uint32_t u = extract32(ctx->opcode, 11, 7);
+
+ gen_compute_imm_branch(ctx, extract32(ctx->opcode, 18, 3),
+ rt, u, s);
+ }
break;
default:
generate_exception_end(ctx, EXCP_RI);
--
1.9.1
next prev parent reply other threads:[~2018-06-20 12:11 UTC|newest]
Thread overview: 62+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-06-20 12:05 [Qemu-devel] [PATCH 00/35] nanoMIPS Yongbok Kim
2018-06-20 12:05 ` [Qemu-devel] [PATCH 01/35] target/mips: Raise a RI when given fs is n/a from CTC1 Yongbok Kim
2018-06-22 13:45 ` Aleksandar Markovic
2018-06-20 12:05 ` [Qemu-devel] [PATCH 02/35] target/mips: Fix microMIPS on reset Yongbok Kim
2018-06-22 13:45 ` Aleksandar Markovic
2018-06-20 12:05 ` [Qemu-devel] [PATCH 03/35] target/mips: Add nanoMIPS OPCODE table Yongbok Kim
2018-06-21 23:15 ` Richard Henderson
2018-06-20 12:05 ` [Qemu-devel] [PATCH 04/35] target/mips: Add decode_nanomips_opc() Yongbok Kim
2018-06-21 23:39 ` Richard Henderson
2018-06-20 12:05 ` [Qemu-devel] [PATCH 05/35] target/mips: Add nanoMIPS 16bit ld/st instructions Yongbok Kim
2018-06-21 23:48 ` Richard Henderson
2018-06-20 12:05 ` [Qemu-devel] [PATCH 06/35] target/mips: Add nanoMIPS pool16c instructions Yongbok Kim
2018-06-22 3:40 ` Richard Henderson
2018-06-20 12:05 ` [Qemu-devel] [PATCH 07/35] target/mips: Add nanoMIPS save and restore Yongbok Kim
2018-06-22 5:11 ` Richard Henderson
2018-06-20 12:05 ` [Qemu-devel] [PATCH 08/35] target/mips: Add nanoMIPS 32bit instructions Yongbok Kim
2018-06-24 23:32 ` Richard Henderson
2018-06-20 12:05 ` [Qemu-devel] [PATCH 09/35] target/mips: Add nanoMIPS 48bit instructions Yongbok Kim
2018-06-24 23:49 ` Richard Henderson
2018-06-20 12:05 ` [Qemu-devel] [PATCH 10/35] target/mips: Add nanoMIPS pool32f instructions Yongbok Kim
2018-06-20 12:05 ` [Qemu-devel] [PATCH 11/35] target/mips: Add nanoMIPS pool32a0 instructions Yongbok Kim
2018-06-24 23:59 ` Richard Henderson
2018-06-20 12:05 ` [Qemu-devel] [PATCH 12/35] target/mips: Add nanoMIPS pool32axf instructions Yongbok Kim
2018-06-20 12:05 ` [Qemu-devel] [PATCH 13/35] target/mips: Update gen_flt_ldst() Yongbok Kim
2018-06-22 4:13 ` Philippe Mathieu-Daudé
2018-06-22 13:46 ` Aleksandar Markovic
2018-06-20 12:05 ` [Qemu-devel] [PATCH 14/35] target/mips: Add nanoMIPS p_lsx instructions Yongbok Kim
2018-06-25 0:07 ` Richard Henderson
2018-06-20 12:06 ` [Qemu-devel] [PATCH 15/35] target/mips: Implement nanoMIPS EXTW instruction Yongbok Kim
2018-06-20 12:06 ` [Qemu-devel] [PATCH 16/35] target/mips: Add has_isa_mode Yongbok Kim
2018-06-20 12:06 ` [Qemu-devel] [PATCH 17/35] target/mips: Add nanoMIPS load store instructions Yongbok Kim
2018-06-20 12:06 ` Yongbok Kim [this message]
2018-06-25 0:23 ` [Qemu-devel] [PATCH 18/35] target/mips: Add nanoMIPS branch instructions Richard Henderson
2018-06-20 12:06 ` [Qemu-devel] [PATCH 19/35] target/mips: Implement nanoMIPS LLWP/SCWP pair Yongbok Kim
2018-06-25 0:27 ` Richard Henderson
2018-06-20 12:06 ` [Qemu-devel] [PATCH 20/35] target/mips: Fix not to update BadVAddr in Debug Mode Yongbok Kim
2018-06-22 4:15 ` Philippe Mathieu-Daudé
2018-06-20 12:06 ` [Qemu-devel] [PATCH 21/35] target/mips: Add nanoMIPS rotx instruction Yongbok Kim
2018-06-25 0:30 ` Richard Henderson
2018-06-20 12:06 ` [Qemu-devel] [PATCH 22/35] target/mips: Fix data type for offset Yongbok Kim
2018-06-22 4:16 ` Philippe Mathieu-Daudé
2018-06-22 13:47 ` Aleksandar Markovic
2018-06-20 12:06 ` [Qemu-devel] [PATCH 23/35] target/mips: Update BadInstr{P} regs on nanoMIPS Yongbok Kim
2018-06-20 12:06 ` [Qemu-devel] [PATCH 24/35] target/mips: Add nanoMIPS CP0_BadInstrX register Yongbok Kim
2018-06-20 12:06 ` [Qemu-devel] [PATCH 25/35] target/mips: Config3.ISAOnExc is read only in nanoMIPS Yongbok Kim
2018-06-20 12:06 ` [Qemu-devel] [PATCH 26/35] target/mips: Fix nanoMIPS exception_resume_pc Yongbok Kim
2018-06-20 12:06 ` [Qemu-devel] [PATCH 27/35] target/mips: Fix nanoMIPS set_hflags_for_handler Yongbok Kim
2018-06-20 12:06 ` [Qemu-devel] [PATCH 28/35] target/mips: Fix nanoMIPS set_pc Yongbok Kim
2018-06-20 12:06 ` [Qemu-devel] [PATCH 29/35] target/mips: Fix ERET/ERETNC can cause ADEL exception Yongbok Kim
2018-06-22 4:31 ` Philippe Mathieu-Daudé
2018-06-20 12:06 ` [Qemu-devel] [PATCH 30/35] hw/mips: Add basic nanoMIPS boot code Yongbok Kim
2018-06-20 12:06 ` [Qemu-devel] [PATCH 31/35] mips_malta: Setup GT64120 BARs in nanoMIPS bootloader Yongbok Kim
2018-06-20 12:06 ` [Qemu-devel] [PATCH 32/35] hw/mips: Fix semihosting argument passing for nanoMIPS bare metal Yongbok Kim
2018-06-20 12:06 ` [Qemu-devel] [PATCH 33/35] target/mips: Fix gdbstub to read/write 64 bit FP registers Yongbok Kim
2018-06-22 13:47 ` Aleksandar Markovic
2018-06-20 12:06 ` [Qemu-devel] [PATCH 34/35] target/mips: Disable gdbstub nanoMIPS ISA bit Yongbok Kim
2018-06-20 12:06 ` [Qemu-devel] [PATCH 35/35] target/mips: Add I7200 CPU Yongbok Kim
2018-06-22 4:26 ` [Qemu-devel] [PATCH 00/35] nanoMIPS Philippe Mathieu-Daudé
2018-06-22 14:39 ` Aleksandar Markovic
2018-06-22 15:16 ` Philippe Mathieu-Daudé
2018-06-22 15:31 ` Peter Maydell
2018-06-22 14:21 ` Aleksandar Markovic
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20180620120620.12806-19-yongbok.kim@mips.com \
--to=yongbok.kim@mips.com \
--cc=Aleksandar.Markovic@mips.com \
--cc=James.Hogan@mips.com \
--cc=Matthew.Fortune@mips.com \
--cc=Paul.Burton@mips.com \
--cc=Stefan.Markovic@mips.com \
--cc=aurelien@aurel32.net \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).