All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 00/22] target/openrisc updates
@ 2017-02-09  4:51 Richard Henderson
  2017-02-09  4:51 ` [Qemu-devel] [PATCH 01/22] target/openrisc: Rename the cpu from or32 to or1k Richard Henderson
                   ` (21 more replies)
  0 siblings, 22 replies; 30+ messages in thread
From: Richard Henderson @ 2017-02-09  4:51 UTC (permalink / raw)
  To: qemu-devel; +Cc: shorne

The bulk of this patch set is 2-3 years old, and was mostly
reviewed by Bastian Koppelmann.  But it languished because
there were reports of it not booting kernel images, and I
had problems putting together a set of tools that could even
build a kernel.

The OpenRISC community has picked up activity recently,
with Stafford Horne upstreaming some of the compiler tools.
He has even done some testing for me of this patch set.


r~


Richard Henderson (21):
  target/openrisc: Rename the cpu from or32 to or1k
  linux-user: Add MMAP_SHIFT for openrisc
  linux-user: Fix openrisc cpu_loop
  target/openrisc: Implement lwa, swa
  target/openrisc: Tidy insn dumping
  target/openrisc: Rationalize immediate extraction
  target/openrisc: Streamline arithmetic and OVE
  target/openrisc: Put SR[OVE] in TB flags
  target/openrisc: Invert the decoding in dec_calc
  target/openrisc: Keep SR_F in a separate variable
  target/openrisc: Keep SR_CY and SR_OV in a separate variables
  target/openrisc: Use movcond where appropriate
  target/openrisc: Set flags on helpers
  target/openrisc: Enable trap, csync, msync, psync for user mode
  target/openrisc: Implement msync
  target/openrisc: Represent MACHI:MACLO as a single unit
  target/openrisc: Implement muld, muldu, macu, msbu
  target/openrisc: Fix madd
  target/openrisc: Optimize l.jal to next
  target/openrisc: Tidy ppc/npc implementation
  target/openrisc: Tidy handling of delayed branches

Stafford Horne (1):
  target/openrisc: Fix exception handling status registers

 configure                            |    6 +-
 default-configs/or1k-linux-user.mak  |    1 +
 default-configs/or1k-softmmu.mak     |    4 +
 default-configs/or32-linux-user.mak  |    1 -
 default-configs/or32-softmmu.mak     |    4 -
 hw/openrisc/openrisc_sim.c           |    4 +-
 linux-user/main.c                    |   95 ++-
 linux-user/openrisc/target_syscall.h |    2 +
 target/openrisc/Makefile.objs        |    2 +-
 target/openrisc/cpu.c                |    1 +
 target/openrisc/cpu.h                |   47 +-
 target/openrisc/exception_helper.c   |   31 +
 target/openrisc/fpu_helper.c         |   68 +-
 target/openrisc/gdbstub.c            |   17 +-
 target/openrisc/helper.h             |   33 +-
 target/openrisc/int_helper.c         |   61 --
 target/openrisc/interrupt.c          |   14 +-
 target/openrisc/interrupt_helper.c   |    4 +-
 target/openrisc/machine.c            |   62 +-
 target/openrisc/mmu.c                |    1 +
 target/openrisc/sys_helper.c         |   62 +-
 target/openrisc/translate.c          | 1314 +++++++++++++++-------------------
 tests/tcg/openrisc/Makefile          |    4 +-
 23 files changed, 851 insertions(+), 987 deletions(-)
 create mode 100644 default-configs/or1k-linux-user.mak
 create mode 100644 default-configs/or1k-softmmu.mak
 delete mode 100644 default-configs/or32-linux-user.mak
 delete mode 100644 default-configs/or32-softmmu.mak
 delete mode 100644 target/openrisc/int_helper.c

-- 
2.9.3

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [Qemu-devel] [PATCH 01/22] target/openrisc: Rename the cpu from or32 to or1k
  2017-02-09  4:51 [Qemu-devel] [PATCH 00/22] target/openrisc updates Richard Henderson
@ 2017-02-09  4:51 ` Richard Henderson
  2017-02-09  4:51 ` [Qemu-devel] [PATCH 03/22] linux-user: Fix openrisc cpu_loop Richard Henderson
                   ` (20 subsequent siblings)
  21 siblings, 0 replies; 30+ messages in thread
From: Richard Henderson @ 2017-02-09  4:51 UTC (permalink / raw)
  To: qemu-devel; +Cc: shorne

This is in keeping with the toolchain and or1ksim.

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 configure                           | 6 +++---
 default-configs/or1k-linux-user.mak | 1 +
 default-configs/or1k-softmmu.mak    | 4 ++++
 default-configs/or32-linux-user.mak | 1 -
 default-configs/or32-softmmu.mak    | 4 ----
 hw/openrisc/openrisc_sim.c          | 4 ++--
 target/openrisc/cpu.h               | 2 +-
 tests/tcg/openrisc/Makefile         | 4 ++--
 8 files changed, 13 insertions(+), 13 deletions(-)
 create mode 100644 default-configs/or1k-linux-user.mak
 create mode 100644 default-configs/or1k-softmmu.mak
 delete mode 100644 default-configs/or32-linux-user.mak
 delete mode 100644 default-configs/or32-softmmu.mak

diff --git a/configure b/configure
index 6325339..1c9655e 100755
--- a/configure
+++ b/configure
@@ -5843,7 +5843,7 @@ target_name=$(echo $target | cut -d '-' -f 1)
 target_bigendian="no"
 
 case "$target_name" in
-  armeb|hppa|lm32|m68k|microblaze|mips|mipsn32|mips64|moxie|or32|ppc|ppcemb|ppc64|ppc64abi32|s390x|sh4eb|sparc|sparc64|sparc32plus|xtensaeb)
+  armeb|hppa|lm32|m68k|microblaze|mips|mipsn32|mips64|moxie|or1k|ppc|ppcemb|ppc64|ppc64abi32|s390x|sh4eb|sparc|sparc64|sparc32plus|xtensaeb)
   target_bigendian=yes
   ;;
 esac
@@ -5937,7 +5937,7 @@ case "$target_name" in
   ;;
   nios2)
   ;;
-  or32)
+  or1k)
     TARGET_ARCH=openrisc
     TARGET_BASE_ARCH=openrisc
   ;;
@@ -6145,7 +6145,7 @@ for i in $ARCH $TARGET_BASE_ARCH ; do
   nios2)
     disas_config "NIOS2"
   ;;
-  or32)
+  or1k)
     disas_config "OPENRISC"
   ;;
   ppc*)
diff --git a/default-configs/or1k-linux-user.mak b/default-configs/or1k-linux-user.mak
new file mode 100644
index 0000000..20e03c1
--- /dev/null
+++ b/default-configs/or1k-linux-user.mak
@@ -0,0 +1 @@
+# Default configuration for or1k-linux-user
diff --git a/default-configs/or1k-softmmu.mak b/default-configs/or1k-softmmu.mak
new file mode 100644
index 0000000..10bfa7a
--- /dev/null
+++ b/default-configs/or1k-softmmu.mak
@@ -0,0 +1,4 @@
+# Default configuration for or1k-softmmu
+
+CONFIG_SERIAL=y
+CONFIG_OPENCORES_ETH=y
diff --git a/default-configs/or32-linux-user.mak b/default-configs/or32-linux-user.mak
deleted file mode 100644
index 808c1f9..0000000
--- a/default-configs/or32-linux-user.mak
+++ /dev/null
@@ -1 +0,0 @@
-# Default configuration for or32-linux-user
diff --git a/default-configs/or32-softmmu.mak b/default-configs/or32-softmmu.mak
deleted file mode 100644
index cce4746..0000000
--- a/default-configs/or32-softmmu.mak
+++ /dev/null
@@ -1,4 +0,0 @@
-# Default configuration for or32-softmmu
-
-CONFIG_SERIAL=y
-CONFIG_OPENCORES_ETH=y
diff --git a/hw/openrisc/openrisc_sim.c b/hw/openrisc/openrisc_sim.c
index 6d06d5b..fc0d096 100644
--- a/hw/openrisc/openrisc_sim.c
+++ b/hw/openrisc/openrisc_sim.c
@@ -139,10 +139,10 @@ static void openrisc_sim_init(MachineState *machine)
 
 static void openrisc_sim_machine_init(MachineClass *mc)
 {
-    mc->desc = "or32 simulation";
+    mc->desc = "or1k simulation";
     mc->init = openrisc_sim_init;
     mc->max_cpus = 1;
     mc->is_default = 1;
 }
 
-DEFINE_MACHINE("or32-sim", openrisc_sim_machine_init)
+DEFINE_MACHINE("or1k-sim", openrisc_sim_machine_init)
diff --git a/target/openrisc/cpu.h b/target/openrisc/cpu.h
index 508ef56..231c163 100644
--- a/target/openrisc/cpu.h
+++ b/target/openrisc/cpu.h
@@ -32,7 +32,7 @@ struct OpenRISCCPU;
 #include "fpu/softfloat.h"
 #include "qom/cpu.h"
 
-#define TYPE_OPENRISC_CPU "or32-cpu"
+#define TYPE_OPENRISC_CPU "or1k-cpu"
 
 #define OPENRISC_CPU_CLASS(klass) \
     OBJECT_CLASS_CHECK(OpenRISCCPUClass, (klass), TYPE_OPENRISC_CPU)
diff --git a/tests/tcg/openrisc/Makefile b/tests/tcg/openrisc/Makefile
index 7e65888..fb5ceda 100644
--- a/tests/tcg/openrisc/Makefile
+++ b/tests/tcg/openrisc/Makefile
@@ -1,8 +1,8 @@
 -include ../../config-host.mak
 
-CROSS = or32-linux-
+CROSS = or1k-linux-
 
-SIM = qemu-or32
+SIM = qemu-or1k
 
 CC = $(CROSS)gcc
 
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Qemu-devel] [PATCH 03/22] linux-user: Fix openrisc cpu_loop
  2017-02-09  4:51 [Qemu-devel] [PATCH 00/22] target/openrisc updates Richard Henderson
  2017-02-09  4:51 ` [Qemu-devel] [PATCH 01/22] target/openrisc: Rename the cpu from or32 to or1k Richard Henderson
@ 2017-02-09  4:51 ` Richard Henderson
  2017-02-09  4:51   ` [OpenRISC] " Richard Henderson
                   ` (19 subsequent siblings)
  21 siblings, 0 replies; 30+ messages in thread
From: Richard Henderson @ 2017-02-09  4:51 UTC (permalink / raw)
  To: qemu-devel; +Cc: shorne

We need to handle EXCP_DEBUG and EXCP_INTERRUPT.
We need to send signals to the guest using queue_signal.

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 linux-user/main.c | 95 ++++++++++++++++++++++++-------------------------------
 1 file changed, 41 insertions(+), 54 deletions(-)

diff --git a/linux-user/main.c b/linux-user/main.c
index e588f58..001f71c 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -2574,52 +2574,17 @@ kuser_fail:
 void cpu_loop(CPUOpenRISCState *env)
 {
     CPUState *cs = CPU(openrisc_env_get_cpu(env));
-    int trapnr, gdbsig;
+    int trapnr;
     abi_long ret;
+    target_siginfo_t info;
 
     for (;;) {
         cpu_exec_start(cs);
         trapnr = cpu_exec(cs);
         cpu_exec_end(cs);
         process_queued_cpu_work(cs);
-        gdbsig = 0;
 
         switch (trapnr) {
-        case EXCP_RESET:
-            qemu_log_mask(CPU_LOG_INT, "\nReset request, exit, pc is %#x\n", env->pc);
-            exit(EXIT_FAILURE);
-            break;
-        case EXCP_BUSERR:
-            qemu_log_mask(CPU_LOG_INT, "\nBus error, exit, pc is %#x\n", env->pc);
-            gdbsig = TARGET_SIGBUS;
-            break;
-        case EXCP_DPF:
-        case EXCP_IPF:
-            cpu_dump_state(cs, stderr, fprintf, 0);
-            gdbsig = TARGET_SIGSEGV;
-            break;
-        case EXCP_TICK:
-            qemu_log_mask(CPU_LOG_INT, "\nTick time interrupt pc is %#x\n", env->pc);
-            break;
-        case EXCP_ALIGN:
-            qemu_log_mask(CPU_LOG_INT, "\nAlignment pc is %#x\n", env->pc);
-            gdbsig = TARGET_SIGBUS;
-            break;
-        case EXCP_ILLEGAL:
-            qemu_log_mask(CPU_LOG_INT, "\nIllegal instructionpc is %#x\n", env->pc);
-            gdbsig = TARGET_SIGILL;
-            break;
-        case EXCP_INT:
-            qemu_log_mask(CPU_LOG_INT, "\nExternal interruptpc is %#x\n", env->pc);
-            break;
-        case EXCP_DTLBMISS:
-        case EXCP_ITLBMISS:
-            qemu_log_mask(CPU_LOG_INT, "\nTLB miss\n");
-            break;
-        case EXCP_RANGE:
-            qemu_log_mask(CPU_LOG_INT, "\nRange\n");
-            gdbsig = TARGET_SIGSEGV;
-            break;
         case EXCP_SYSCALL:
             env->pc += 4;   /* 0xc00; */
             ret = do_syscall(env,
@@ -2636,32 +2601,54 @@ void cpu_loop(CPUOpenRISCState *env)
                 env->gpr[11] = ret;
             }
             break;
+        case EXCP_DPF:
+        case EXCP_IPF:
+        case EXCP_RANGE:
+            info.si_signo = TARGET_SIGSEGV;
+            info.si_errno = 0;
+            info.si_code = TARGET_SEGV_MAPERR;
+            info._sifields._sigfault._addr = env->pc;
+            queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
+            break;
+        case EXCP_ALIGN:
+            info.si_signo = TARGET_SIGBUS;
+            info.si_errno = 0;
+            info.si_code = TARGET_BUS_ADRALN;
+            info._sifields._sigfault._addr = env->pc;
+            queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
+            break;
+        case EXCP_ILLEGAL:
+            info.si_signo = TARGET_SIGILL;
+            info.si_errno = 0;
+            info.si_code = TARGET_ILL_ILLOPC;
+            info._sifields._sigfault._addr = env->pc;
+            queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
+            break;
         case EXCP_FPE:
-            qemu_log_mask(CPU_LOG_INT, "\nFloating point error\n");
+            info.si_signo = TARGET_SIGFPE;
+            info.si_errno = 0;
+            info.si_code = 0;
+            info._sifields._sigfault._addr = env->pc;
+            queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
             break;
-        case EXCP_TRAP:
-            qemu_log_mask(CPU_LOG_INT, "\nTrap\n");
-            gdbsig = TARGET_SIGTRAP;
+        case EXCP_INTERRUPT:
+            /* We processed the pending cpu work above.  */
             break;
-        case EXCP_NR:
-            qemu_log_mask(CPU_LOG_INT, "\nNR\n");
+        case EXCP_DEBUG:
+            trapnr = gdb_handlesig(cs, TARGET_SIGTRAP);
+            if (trapnr) {
+                info.si_signo = trapnr;
+                info.si_errno = 0;
+                info.si_code = TARGET_TRAP_BRKPT;
+                queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
+            }
             break;
         case EXCP_ATOMIC:
             cpu_exec_step_atomic(cs);
             break;
         default:
-            EXCP_DUMP(env, "\nqemu: unhandled CPU exception %#x - aborting\n",
-                     trapnr);
-            gdbsig = TARGET_SIGILL;
-            break;
-        }
-        if (gdbsig) {
-            gdb_handlesig(cs, gdbsig);
-            if (gdbsig != TARGET_SIGTRAP) {
-                exit(EXIT_FAILURE);
-            }
+            g_assert_not_reached();
         }
-
         process_pending_signals(env);
     }
 }
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Qemu-devel] [PATCH 04/22] target/openrisc: Fix exception handling status registers
  2017-02-09  4:51 [Qemu-devel] [PATCH 00/22] target/openrisc updates Richard Henderson
@ 2017-02-09  4:51   ` Richard Henderson
  2017-02-09  4:51 ` [Qemu-devel] [PATCH 03/22] linux-user: Fix openrisc cpu_loop Richard Henderson
                     ` (20 subsequent siblings)
  21 siblings, 0 replies; 30+ messages in thread
From: Richard Henderson @ 2017-02-09  4:51 UTC (permalink / raw)
  To: qemu-devel; +Cc: shorne, qemu-trivial, openrisc

From: Stafford Horne <shorne@gmail.com>

I am working on testing instruction emulation patches for the linux
kernel. During testing I found these 2 issues:

 - sets DSX (delay slot exception) but never clears it
 - EEAR for illegal insns should point to the bad exception (as per
   openrisc spec) but its not

This patch fixes these two issues by clearing the DSX flag when not in a
delay slot and by setting EEAR to exception PC when handling illegal
instruction exceptions.

After this patch the openrisc kernel with latest patches boots great on
qemu and instruction emulation works.

Cc: qemu-trivial@nongnu.org
Cc: openrisc@lists.librecores.org
Signed-off-by: Stafford Horne <shorne@gmail.com>
Message-Id: <20170113220028.29687-1-shorne@gmail.com>
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 target/openrisc/interrupt.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/target/openrisc/interrupt.c b/target/openrisc/interrupt.c
index e43fc84..a243eb2 100644
--- a/target/openrisc/interrupt.c
+++ b/target/openrisc/interrupt.c
@@ -38,10 +38,17 @@ void openrisc_cpu_do_interrupt(CPUState *cs)
         env->flags &= ~D_FLAG;
         env->sr |= SR_DSX;
         env->epcr -= 4;
+    } else {
+        env->sr &= ~SR_DSX;
     }
     if (cs->exception_index == EXCP_SYSCALL) {
         env->epcr += 4;
     }
+    /* When we have an illegal instruction the error effective address
+       shall be set to the illegal instruction address.  */
+    if (cs->exception_index == EXCP_ILLEGAL) {
+        env->eear = env->pc;
+    }
 
     /* For machine-state changed between user-mode and supervisor mode,
        we need flush TLB when we enter&exit EXCP.  */
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [OpenRISC] [PATCH 04/22] target/openrisc: Fix exception handling status registers
@ 2017-02-09  4:51   ` Richard Henderson
  0 siblings, 0 replies; 30+ messages in thread
From: Richard Henderson @ 2017-02-09  4:51 UTC (permalink / raw)
  To: openrisc

From: Stafford Horne <shorne@gmail.com>

I am working on testing instruction emulation patches for the linux
kernel. During testing I found these 2 issues:

 - sets DSX (delay slot exception) but never clears it
 - EEAR for illegal insns should point to the bad exception (as per
   openrisc spec) but its not

This patch fixes these two issues by clearing the DSX flag when not in a
delay slot and by setting EEAR to exception PC when handling illegal
instruction exceptions.

After this patch the openrisc kernel with latest patches boots great on
qemu and instruction emulation works.

Cc: qemu-trivial at nongnu.org
Cc: openrisc at lists.librecores.org
Signed-off-by: Stafford Horne <shorne@gmail.com>
Message-Id: <20170113220028.29687-1-shorne@gmail.com>
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 target/openrisc/interrupt.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/target/openrisc/interrupt.c b/target/openrisc/interrupt.c
index e43fc84..a243eb2 100644
--- a/target/openrisc/interrupt.c
+++ b/target/openrisc/interrupt.c
@@ -38,10 +38,17 @@ void openrisc_cpu_do_interrupt(CPUState *cs)
         env->flags &= ~D_FLAG;
         env->sr |= SR_DSX;
         env->epcr -= 4;
+    } else {
+        env->sr &= ~SR_DSX;
     }
     if (cs->exception_index == EXCP_SYSCALL) {
         env->epcr += 4;
     }
+    /* When we have an illegal instruction the error effective address
+       shall be set to the illegal instruction address.  */
+    if (cs->exception_index == EXCP_ILLEGAL) {
+        env->eear = env->pc;
+    }
 
     /* For machine-state changed between user-mode and supervisor mode,
        we need flush TLB when we enter&exit EXCP.  */
-- 
2.9.3


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Qemu-devel] [PATCH 05/22] target/openrisc: Implement lwa, swa
  2017-02-09  4:51 [Qemu-devel] [PATCH 00/22] target/openrisc updates Richard Henderson
                   ` (2 preceding siblings ...)
  2017-02-09  4:51   ` [OpenRISC] " Richard Henderson
@ 2017-02-09  4:51 ` Richard Henderson
  2017-02-09  4:51 ` [Qemu-devel] [PATCH 06/22] target/openrisc: Tidy insn dumping Richard Henderson
                   ` (17 subsequent siblings)
  21 siblings, 0 replies; 30+ messages in thread
From: Richard Henderson @ 2017-02-09  4:51 UTC (permalink / raw)
  To: qemu-devel; +Cc: shorne

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 target/openrisc/cpu.c              |  1 +
 target/openrisc/cpu.h              |  3 ++
 target/openrisc/interrupt.c        |  1 +
 target/openrisc/interrupt_helper.c |  1 +
 target/openrisc/machine.c          | 24 ++++++++++------
 target/openrisc/mmu.c              |  1 +
 target/openrisc/translate.c        | 58 ++++++++++++++++++++++++++++++++++++++
 7 files changed, 81 insertions(+), 8 deletions(-)

diff --git a/target/openrisc/cpu.c b/target/openrisc/cpu.c
index 422139d..7fd2b9a 100644
--- a/target/openrisc/cpu.c
+++ b/target/openrisc/cpu.c
@@ -48,6 +48,7 @@ static void openrisc_cpu_reset(CPUState *s)
 
     cpu->env.pc = 0x100;
     cpu->env.sr = SR_FO | SR_SM;
+    cpu->env.lock_addr = -1;
     s->exception_index = -1;
 
     cpu->env.upr = UPR_UP | UPR_DMP | UPR_IMP | UPR_PICP | UPR_TTP;
diff --git a/target/openrisc/cpu.h b/target/openrisc/cpu.h
index 231c163..06d0e89 100644
--- a/target/openrisc/cpu.h
+++ b/target/openrisc/cpu.h
@@ -296,6 +296,9 @@ typedef struct CPUOpenRISCState {
     uint32_t fpcsr;           /* Float register */
     float_status fp_status;
 
+    target_ulong lock_addr;
+    target_ulong lock_value;
+
     uint32_t flags;           /* cpu_flags, we only use it for exception
                                  in solt so far.  */
     uint32_t btaken;          /* the SR_F bit */
diff --git a/target/openrisc/interrupt.c b/target/openrisc/interrupt.c
index a243eb2..a981638 100644
--- a/target/openrisc/interrupt.c
+++ b/target/openrisc/interrupt.c
@@ -62,6 +62,7 @@ void openrisc_cpu_do_interrupt(CPUState *cs)
     env->sr &= ~SR_TEE;
     env->tlb->cpu_openrisc_map_address_data = &cpu_openrisc_get_phys_nommu;
     env->tlb->cpu_openrisc_map_address_code = &cpu_openrisc_get_phys_nommu;
+    env->lock_addr = -1;
 
     if (cs->exception_index > 0 && cs->exception_index < EXCP_NR) {
         env->pc = (cs->exception_index << 8);
diff --git a/target/openrisc/interrupt_helper.c b/target/openrisc/interrupt_helper.c
index 0ed5146..a6d4df3 100644
--- a/target/openrisc/interrupt_helper.c
+++ b/target/openrisc/interrupt_helper.c
@@ -34,6 +34,7 @@ void HELPER(rfe)(CPUOpenRISCState *env)
     cpu->env.pc = cpu->env.epcr;
     cpu->env.npc = cpu->env.epcr;
     cpu->env.sr = cpu->env.esr;
+    cpu->env.lock_addr = -1;
 
 #ifndef CONFIG_USER_ONLY
     if (cpu->env.sr & SR_DME) {
diff --git a/target/openrisc/machine.c b/target/openrisc/machine.c
index 17b0c77..d0b47ef 100644
--- a/target/openrisc/machine.c
+++ b/target/openrisc/machine.c
@@ -26,18 +26,26 @@
 
 static const VMStateDescription vmstate_env = {
     .name = "env",
-    .version_id = 1,
-    .minimum_version_id = 1,
+    .version_id = 2,
+    .minimum_version_id = 2,
     .fields = (VMStateField[]) {
-        VMSTATE_UINT32_ARRAY(gpr, CPUOpenRISCState, 32),
+        VMSTATE_UINTTL_ARRAY(gpr, CPUOpenRISCState, 32),
+        VMSTATE_UINTTL(pc, CPUOpenRISCState),
+        VMSTATE_UINTTL(npc, CPUOpenRISCState),
+        VMSTATE_UINTTL(ppc, CPUOpenRISCState),
+        VMSTATE_UINTTL(jmp_pc, CPUOpenRISCState),
+        VMSTATE_UINTTL(lock_addr, CPUOpenRISCState),
+        VMSTATE_UINTTL(lock_value, CPUOpenRISCState),
+        VMSTATE_UINTTL(epcr, CPUOpenRISCState),
+        VMSTATE_UINTTL(eear, CPUOpenRISCState),
         VMSTATE_UINT32(sr, CPUOpenRISCState),
-        VMSTATE_UINT32(epcr, CPUOpenRISCState),
-        VMSTATE_UINT32(eear, CPUOpenRISCState),
+        VMSTATE_UINT32(vr, CPUOpenRISCState),
+        VMSTATE_UINT32(upr, CPUOpenRISCState),
+        VMSTATE_UINT32(cpucfgr, CPUOpenRISCState),
+        VMSTATE_UINT32(dmmucfgr, CPUOpenRISCState),
+        VMSTATE_UINT32(immucfgr, CPUOpenRISCState),
         VMSTATE_UINT32(esr, CPUOpenRISCState),
         VMSTATE_UINT32(fpcsr, CPUOpenRISCState),
-        VMSTATE_UINT32(pc, CPUOpenRISCState),
-        VMSTATE_UINT32(npc, CPUOpenRISCState),
-        VMSTATE_UINT32(ppc, CPUOpenRISCState),
         VMSTATE_END_OF_LIST()
     }
 };
diff --git a/target/openrisc/mmu.c b/target/openrisc/mmu.c
index 505dcdc..56b11d3 100644
--- a/target/openrisc/mmu.c
+++ b/target/openrisc/mmu.c
@@ -174,6 +174,7 @@ static void cpu_openrisc_raise_mmu_exception(OpenRISCCPU *cpu,
 
     cs->exception_index = exception;
     cpu->env.eear = address;
+    cpu->env.lock_addr = -1;
 }
 
 #ifndef CONFIG_USER_ONLY
diff --git a/target/openrisc/translate.c b/target/openrisc/translate.c
index 03fa7db..c207875 100644
--- a/target/openrisc/translate.c
+++ b/target/openrisc/translate.c
@@ -61,6 +61,8 @@ static TCGv jmp_pc;            /* l.jr/l.jalr temp pc */
 static TCGv cpu_npc;
 static TCGv cpu_ppc;
 static TCGv_i32 env_btaken;    /* bf/bnf , F flag taken */
+static TCGv cpu_lock_addr;
+static TCGv cpu_lock_value;
 static TCGv_i32 fpcsr;
 static TCGv machi, maclo;
 static TCGv fpmaddhi, fpmaddlo;
@@ -95,6 +97,12 @@ void openrisc_translate_init(void)
     env_btaken = tcg_global_mem_new_i32(cpu_env,
                                         offsetof(CPUOpenRISCState, btaken),
                                         "btaken");
+    cpu_lock_addr = tcg_global_mem_new(cpu_env,
+                                       offsetof(CPUOpenRISCState, lock_addr),
+                                       "lock_addr");
+    cpu_lock_value = tcg_global_mem_new(cpu_env,
+                                        offsetof(CPUOpenRISCState, lock_value),
+                                        "lock_value");
     fpcsr = tcg_global_mem_new_i32(cpu_env,
                                    offsetof(CPUOpenRISCState, fpcsr),
                                    "fpcsr");
@@ -265,6 +273,46 @@ static void gen_jump(DisasContext *dc, uint32_t imm, uint32_t reg, uint32_t op0)
 }
 
 
+static void gen_lwa(DisasContext *dc, TCGv rd, TCGv ra, int32_t ofs)
+{
+    TCGv ea = tcg_temp_new();
+
+    tcg_gen_addi_tl(ea, ra, ofs);
+    tcg_gen_qemu_ld_tl(rd, ea, dc->mem_idx, MO_TEUL);
+    tcg_gen_mov_tl(cpu_lock_addr, ea);
+    tcg_gen_mov_tl(cpu_lock_value, rd);
+    tcg_temp_free(ea);
+}
+
+static void gen_swa(DisasContext *dc, TCGv rb, TCGv ra, int32_t ofs)
+{
+    TCGv ea, val;
+    TCGLabel *lab_fail, *lab_done;
+
+    ea = tcg_temp_new();
+    tcg_gen_addi_tl(ea, ra, ofs);
+
+    lab_fail = gen_new_label();
+    lab_done = gen_new_label();
+    tcg_gen_brcond_tl(TCG_COND_NE, ea, cpu_lock_addr, lab_fail);
+    tcg_temp_free(ea);
+
+    val = tcg_temp_new();
+    tcg_gen_atomic_cmpxchg_tl(val, cpu_lock_addr, cpu_lock_value,
+                              rb, dc->mem_idx, MO_TEUL);
+    tcg_gen_setcond_tl(TCG_COND_EQ, env_btaken, val, cpu_lock_value);
+    tcg_temp_free(val);
+
+    tcg_gen_br(lab_done);
+
+    gen_set_label(lab_fail);
+    tcg_gen_movi_tl(env_btaken, 0);
+
+    gen_set_label(lab_done);
+    tcg_gen_movi_tl(cpu_lock_addr, -1);
+    wb_SR_F();
+}
+
 static void dec_calc(DisasContext *dc, uint32_t insn)
 {
     uint32_t op0, op1, op2;
@@ -819,6 +867,11 @@ static void dec_misc(DisasContext *dc, uint32_t insn)
         }
         break;
 
+    case 0x1b: /* l.lwa */
+        LOG_DIS("l.lwa r%d, r%d, %d\n", rd, ra, I16);
+        gen_lwa(dc, cpu_R[rd], cpu_R[ra], I16);
+        break;
+
     case 0x1c:    /* l.cust1 */
         LOG_DIS("l.cust1\n");
         break;
@@ -1029,6 +1082,11 @@ static void dec_misc(DisasContext *dc, uint32_t insn)
         }
         break;
 
+    case 0x33: /* l.swa */
+        LOG_DIS("l.swa %d, r%d, r%d, %d\n", I5, ra, rb, I11);
+        gen_swa(dc, cpu_R[rb], cpu_R[ra], sign_extend(tmp, 16));
+        break;
+
 /* not used yet, open it when we need or64.  */
 /*#ifdef TARGET_OPENRISC64
     case 0x34:     l.sd
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Qemu-devel] [PATCH 06/22] target/openrisc: Tidy insn dumping
  2017-02-09  4:51 [Qemu-devel] [PATCH 00/22] target/openrisc updates Richard Henderson
                   ` (3 preceding siblings ...)
  2017-02-09  4:51 ` [Qemu-devel] [PATCH 05/22] target/openrisc: Implement lwa, swa Richard Henderson
@ 2017-02-09  4:51 ` Richard Henderson
  2017-02-09  5:14   ` Philippe Mathieu-Daudé
  2017-02-09  4:51 ` [Qemu-devel] [PATCH 07/22] target/openrisc: Rationalize immediate extraction Richard Henderson
                   ` (16 subsequent siblings)
  21 siblings, 1 reply; 30+ messages in thread
From: Richard Henderson @ 2017-02-09  4:51 UTC (permalink / raw)
  To: qemu-devel; +Cc: shorne

Avoids warnings from unused variables etc.

Reviewed-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 target/openrisc/translate.c | 36 ++++++++++++------------------------
 1 file changed, 12 insertions(+), 24 deletions(-)

diff --git a/target/openrisc/translate.c b/target/openrisc/translate.c
index c207875..ac0c409 100644
--- a/target/openrisc/translate.c
+++ b/target/openrisc/translate.c
@@ -34,14 +34,8 @@
 #include "trace-tcg.h"
 #include "exec/log.h"
 
-
-#define OPENRISC_DISAS
-
-#ifdef OPENRISC_DISAS
-#  define LOG_DIS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__)
-#else
-#  define LOG_DIS(...) do { } while (0)
-#endif
+#define LOG_DIS(str, ...) \
+    qemu_log_mask(CPU_LOG_TB_IN_ASM, "%08x: " str, dc->pc, ## __VA_ARGS__)
 
 typedef struct DisasContext {
     TranslationBlock *tb;
@@ -766,9 +760,7 @@ static void dec_misc(DisasContext *dc, uint32_t insn)
 {
     uint32_t op0, op1;
     uint32_t ra, rb, rd;
-#ifdef OPENRISC_DISAS
     uint32_t L6, K5;
-#endif
     uint32_t I16, I5, I11, N26, tmp;
     TCGMemOp mop;
 
@@ -777,10 +769,8 @@ static void dec_misc(DisasContext *dc, uint32_t insn)
     ra = extract32(insn, 16, 5);
     rb = extract32(insn, 11, 5);
     rd = extract32(insn, 21, 5);
-#ifdef OPENRISC_DISAS
     L6 = extract32(insn, 5, 6);
     K5 = extract32(insn, 0, 5);
-#endif
     I16 = extract32(insn, 0, 16);
     I5 = extract32(insn, 21, 5);
     I11 = extract32(insn, 0, 11);
@@ -1387,13 +1377,10 @@ static void dec_compi(DisasContext *dc, uint32_t insn)
 static void dec_sys(DisasContext *dc, uint32_t insn)
 {
     uint32_t op0;
-#ifdef OPENRISC_DISAS
     uint32_t K16;
-#endif
+
     op0 = extract32(insn, 16, 10);
-#ifdef OPENRISC_DISAS
     K16 = extract32(insn, 0, 16);
-#endif
 
     switch (op0) {
     case 0x000:    /* l.sys */
@@ -1723,6 +1710,13 @@ void gen_intermediate_code(CPUOpenRISCState *env, struct TranslationBlock *tb)
         max_insns = TCG_MAX_INSNS;
     }
 
+    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
+        && qemu_log_in_addr_range(pc_start)) {
+        qemu_log_lock();
+        qemu_log("----------------\n");
+        qemu_log("IN: %s\n", lookup_symbol(pc_start));
+    }
+
     gen_tb_start(tb);
 
     do {
@@ -1807,18 +1801,12 @@ void gen_intermediate_code(CPUOpenRISCState *env, struct TranslationBlock *tb)
     tb->size = dc->pc - pc_start;
     tb->icount = num_insns;
 
-#ifdef DEBUG_DISAS
     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
         && qemu_log_in_addr_range(pc_start)) {
-        qemu_log_lock();
-        qemu_log("----------------\n");
-        qemu_log("IN: %s\n", lookup_symbol(pc_start));
-        log_target_disas(cs, pc_start, dc->pc - pc_start, 0);
-        qemu_log("\nisize=%d osize=%d\n",
-                 dc->pc - pc_start, tcg_op_buf_count());
+        log_target_disas(cs, pc_start, tb->size, 0);
+        qemu_log("\n");
         qemu_log_unlock();
     }
-#endif
 }
 
 void openrisc_cpu_dump_state(CPUState *cs, FILE *f,
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Qemu-devel] [PATCH 07/22] target/openrisc: Rationalize immediate extraction
  2017-02-09  4:51 [Qemu-devel] [PATCH 00/22] target/openrisc updates Richard Henderson
                   ` (4 preceding siblings ...)
  2017-02-09  4:51 ` [Qemu-devel] [PATCH 06/22] target/openrisc: Tidy insn dumping Richard Henderson
@ 2017-02-09  4:51 ` Richard Henderson
  2017-02-09  4:51 ` [Qemu-devel] [PATCH 08/22] target/openrisc: Streamline arithmetic and OVE Richard Henderson
                   ` (15 subsequent siblings)
  21 siblings, 0 replies; 30+ messages in thread
From: Richard Henderson @ 2017-02-09  4:51 UTC (permalink / raw)
  To: qemu-devel; +Cc: shorne

The architecture manual is consistent in using "I" for signed
fields and "K" for unsigned fields.  Mirror that.

Reviewed-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 target/openrisc/translate.c | 98 ++++++++++++++++++---------------------------
 1 file changed, 40 insertions(+), 58 deletions(-)

diff --git a/target/openrisc/translate.c b/target/openrisc/translate.c
index ac0c409..d999d2f 100644
--- a/target/openrisc/translate.c
+++ b/target/openrisc/translate.c
@@ -129,23 +129,6 @@ static inline void wb_SR_F(void)
     gen_set_label(label);
 }
 
-static inline int zero_extend(unsigned int val, int width)
-{
-    return val & ((1 << width) - 1);
-}
-
-static inline int sign_extend(unsigned int val, int width)
-{
-    int sval;
-
-    /* LSL */
-    val <<= TARGET_LONG_BITS - width;
-    sval = val;
-    /* ASR.  */
-    sval >>= TARGET_LONG_BITS - width;
-    return sval;
-}
-
 static inline void gen_sync_flags(DisasContext *dc)
 {
     /* Sync the tb dependent flag between translate and runtime.  */
@@ -221,11 +204,9 @@ static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
     }
 }
 
-static void gen_jump(DisasContext *dc, uint32_t imm, uint32_t reg, uint32_t op0)
+static void gen_jump(DisasContext *dc, int32_t n26, uint32_t reg, uint32_t op0)
 {
-    target_ulong tmp_pc;
-    /* N26, 26bits imm */
-    tmp_pc = sign_extend((imm<<2), 26) + dc->pc;
+    target_ulong tmp_pc = dc->pc + n26 * 4;
 
     switch (op0) {
     case 0x00:     /* l.j */
@@ -760,8 +741,8 @@ static void dec_misc(DisasContext *dc, uint32_t insn)
 {
     uint32_t op0, op1;
     uint32_t ra, rb, rd;
-    uint32_t L6, K5;
-    uint32_t I16, I5, I11, N26, tmp;
+    uint32_t L6, K5, K16, K5_11;
+    int32_t I16, I5_11, N26;
     TCGMemOp mop;
 
     op0 = extract32(insn, 26, 6);
@@ -771,11 +752,11 @@ static void dec_misc(DisasContext *dc, uint32_t insn)
     rd = extract32(insn, 21, 5);
     L6 = extract32(insn, 5, 6);
     K5 = extract32(insn, 0, 5);
-    I16 = extract32(insn, 0, 16);
-    I5 = extract32(insn, 21, 5);
-    I11 = extract32(insn, 0, 11);
-    N26 = extract32(insn, 0, 26);
-    tmp = (I5<<11) + I11;
+    K16 = extract32(insn, 0, 16);
+    I16 = (int16_t)K16;
+    N26 = sextract32(insn, 0, 26);
+    K5_11 = (extract32(insn, 21, 5) << 11) | extract32(insn, 0, 11);
+    I5_11 = (int16_t)K5_11;
 
     switch (op0) {
     case 0x00:    /* l.j */
@@ -821,12 +802,12 @@ static void dec_misc(DisasContext *dc, uint32_t insn)
         break;
 
     case 0x13:    /* l.maci */
-        LOG_DIS("l.maci %d, r%d, %d\n", I5, ra, I11);
+        LOG_DIS("l.maci r%d, %d\n", ra, I16);
         {
             TCGv_i64 t1 = tcg_temp_new_i64();
             TCGv_i64 t2 = tcg_temp_new_i64();
             TCGv_i32 dst = tcg_temp_new_i32();
-            TCGv ttmp = tcg_const_tl(tmp);
+            TCGv ttmp = tcg_const_tl(I16);
             tcg_gen_mul_tl(dst, cpu_R[ra], ttmp);
             tcg_gen_ext_i32_i64(t1, dst);
             tcg_gen_concat_i32_i64(t2, maclo, machi);
@@ -936,7 +917,7 @@ static void dec_misc(DisasContext *dc, uint32_t insn)
     do_load:
         {
             TCGv t0 = tcg_temp_new();
-            tcg_gen_addi_tl(t0, cpu_R[ra], sign_extend(I16, 16));
+            tcg_gen_addi_tl(t0, cpu_R[ra], I16);
             tcg_gen_qemu_ld_tl(cpu_R[rd], t0, dc->mem_idx, mop);
             tcg_temp_free(t0);
         }
@@ -954,7 +935,7 @@ static void dec_misc(DisasContext *dc, uint32_t insn)
                 TCGv_i32 res = tcg_temp_local_new_i32();
                 TCGv_i32 sr_ove = tcg_temp_local_new_i32();
                 tcg_gen_extu_i32_i64(ta, cpu_R[ra]);
-                tcg_gen_addi_i64(td, ta, sign_extend(I16, 16));
+                tcg_gen_addi_i64(td, ta, I16);
                 tcg_gen_extrl_i64_i32(res, td);
                 tcg_gen_shri_i64(td, td, 32);
                 tcg_gen_andi_i64(td, td, 0x3);
@@ -989,7 +970,7 @@ static void dec_misc(DisasContext *dc, uint32_t insn)
             tcg_gen_andi_i32(sr_cy, cpu_sr, SR_CY);
             tcg_gen_shri_i32(sr_cy, sr_cy, 10);
             tcg_gen_extu_i32_i64(tcy, sr_cy);
-            tcg_gen_addi_i64(td, ta, sign_extend(I16, 16));
+            tcg_gen_addi_i64(td, ta, I16);
             tcg_gen_add_i64(td, td, tcy);
             tcg_gen_extrl_i64_i32(res, td);
             tcg_gen_shri_i64(td, td, 32);
@@ -1013,18 +994,18 @@ static void dec_misc(DisasContext *dc, uint32_t insn)
         break;
 
     case 0x29:    /* l.andi */
-        LOG_DIS("l.andi r%d, r%d, %d\n", rd, ra, I16);
-        tcg_gen_andi_tl(cpu_R[rd], cpu_R[ra], zero_extend(I16, 16));
+        LOG_DIS("l.andi r%d, r%d, %d\n", rd, ra, K16);
+        tcg_gen_andi_tl(cpu_R[rd], cpu_R[ra], K16);
         break;
 
     case 0x2a:    /* l.ori */
-        LOG_DIS("l.ori r%d, r%d, %d\n", rd, ra, I16);
-        tcg_gen_ori_tl(cpu_R[rd], cpu_R[ra], zero_extend(I16, 16));
+        LOG_DIS("l.ori r%d, r%d, %d\n", rd, ra, K16);
+        tcg_gen_ori_tl(cpu_R[rd], cpu_R[ra], K16);
         break;
 
     case 0x2b:    /* l.xori */
         LOG_DIS("l.xori r%d, r%d, %d\n", rd, ra, I16);
-        tcg_gen_xori_tl(cpu_R[rd], cpu_R[ra], sign_extend(I16, 16));
+        tcg_gen_xori_tl(cpu_R[rd], cpu_R[ra], I16);
         break;
 
     case 0x2c:    /* l.muli */
@@ -1039,12 +1020,12 @@ static void dec_misc(DisasContext *dc, uint32_t insn)
         break;
 
     case 0x2d:    /* l.mfspr */
-        LOG_DIS("l.mfspr r%d, r%d, %d\n", rd, ra, I16);
+        LOG_DIS("l.mfspr r%d, r%d, %d\n", rd, ra, K16);
         {
 #if defined(CONFIG_USER_ONLY)
             return;
 #else
-            TCGv_i32 ti = tcg_const_i32(I16);
+            TCGv_i32 ti = tcg_const_i32(K16);
             if (dc->mem_idx == MMU_USER_IDX) {
                 gen_illegal_exception(dc);
                 return;
@@ -1056,12 +1037,12 @@ static void dec_misc(DisasContext *dc, uint32_t insn)
         break;
 
     case 0x30:    /* l.mtspr */
-        LOG_DIS("l.mtspr %d, r%d, r%d, %d\n", I5, ra, rb, I11);
+        LOG_DIS("l.mtspr r%d, r%d, %d\n", ra, rb, K5_11);
         {
 #if defined(CONFIG_USER_ONLY)
             return;
 #else
-            TCGv_i32 im = tcg_const_i32(tmp);
+            TCGv_i32 im = tcg_const_i32(K5_11);
             if (dc->mem_idx == MMU_USER_IDX) {
                 gen_illegal_exception(dc);
                 return;
@@ -1073,38 +1054,38 @@ static void dec_misc(DisasContext *dc, uint32_t insn)
         break;
 
     case 0x33: /* l.swa */
-        LOG_DIS("l.swa %d, r%d, r%d, %d\n", I5, ra, rb, I11);
-        gen_swa(dc, cpu_R[rb], cpu_R[ra], sign_extend(tmp, 16));
+        LOG_DIS("l.swa r%d, r%d, %d\n", ra, rb, I5_11);
+        gen_swa(dc, cpu_R[rb], cpu_R[ra], I5_11);
         break;
 
 /* not used yet, open it when we need or64.  */
 /*#ifdef TARGET_OPENRISC64
     case 0x34:     l.sd
-        LOG_DIS("l.sd %d, r%d, r%d, %d\n", I5, ra, rb, I11);
+        LOG_DIS("l.sd r%d, r%d, %d\n", ra, rb, I5_11);
         check_ob64s(dc);
         mop = MO_TEQ;
         goto do_store;
 #endif*/
 
     case 0x35:    /* l.sw */
-        LOG_DIS("l.sw %d, r%d, r%d, %d\n", I5, ra, rb, I11);
+        LOG_DIS("l.sw r%d, r%d, %d\n", ra, rb, I5_11);
         mop = MO_TEUL;
         goto do_store;
 
     case 0x36:    /* l.sb */
-        LOG_DIS("l.sb %d, r%d, r%d, %d\n", I5, ra, rb, I11);
+        LOG_DIS("l.sb r%d, r%d, %d\n", ra, rb, I5_11);
         mop = MO_UB;
         goto do_store;
 
     case 0x37:    /* l.sh */
-        LOG_DIS("l.sh %d, r%d, r%d, %d\n", I5, ra, rb, I11);
+        LOG_DIS("l.sh r%d, r%d, %d\n", ra, rb, I5_11);
         mop = MO_TEUW;
         goto do_store;
 
     do_store:
         {
             TCGv t0 = tcg_temp_new();
-            tcg_gen_addi_tl(t0, cpu_R[ra], sign_extend(tmp, 16));
+            tcg_gen_addi_tl(t0, cpu_R[ra], I5_11);
             tcg_gen_qemu_st_tl(cpu_R[rb], t0, dc->mem_idx, mop);
             tcg_temp_free(t0);
         }
@@ -1172,30 +1153,32 @@ static void dec_mac(DisasContext *dc, uint32_t insn)
 static void dec_logic(DisasContext *dc, uint32_t insn)
 {
     uint32_t op0;
-    uint32_t rd, ra, L6;
+    uint32_t rd, ra, L6, S6;
     op0 = extract32(insn, 6, 2);
     rd = extract32(insn, 21, 5);
     ra = extract32(insn, 16, 5);
     L6 = extract32(insn, 0, 6);
+    S6 = L6 & (TARGET_LONG_BITS - 1);
 
     switch (op0) {
     case 0x00:    /* l.slli */
         LOG_DIS("l.slli r%d, r%d, %d\n", rd, ra, L6);
-        tcg_gen_shli_tl(cpu_R[rd], cpu_R[ra], (L6 & 0x1f));
+        tcg_gen_shli_tl(cpu_R[rd], cpu_R[ra], S6);
         break;
 
     case 0x01:    /* l.srli */
         LOG_DIS("l.srli r%d, r%d, %d\n", rd, ra, L6);
-        tcg_gen_shri_tl(cpu_R[rd], cpu_R[ra], (L6 & 0x1f));
+        tcg_gen_shri_tl(cpu_R[rd], cpu_R[ra], S6);
         break;
 
     case 0x02:    /* l.srai */
         LOG_DIS("l.srai r%d, r%d, %d\n", rd, ra, L6);
-        tcg_gen_sari_tl(cpu_R[rd], cpu_R[ra], (L6 & 0x1f)); break;
+        tcg_gen_sari_tl(cpu_R[rd], cpu_R[ra], S6);
+        break;
 
     case 0x03:    /* l.rori */
         LOG_DIS("l.rori r%d, r%d, %d\n", rd, ra, L6);
-        tcg_gen_rotri_tl(cpu_R[rd], cpu_R[ra], (L6 & 0x1f));
+        tcg_gen_rotri_tl(cpu_R[rd], cpu_R[ra], S6);
         break;
 
     default:
@@ -1306,15 +1289,14 @@ static void dec_comp(DisasContext *dc, uint32_t insn)
 
 static void dec_compi(DisasContext *dc, uint32_t insn)
 {
-    uint32_t op0;
-    uint32_t ra, I16;
+    uint32_t op0, ra;
+    int32_t I16;
 
     op0 = extract32(insn, 21, 5);
     ra = extract32(insn, 16, 5);
-    I16 = extract32(insn, 0, 16);
+    I16 = sextract32(insn, 0, 16);
 
     tcg_gen_movi_i32(env_btaken, 0x0);
-    I16 = sign_extend(I16, 16);
 
     switch (op0) {
     case 0x0:    /* l.sfeqi */
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Qemu-devel] [PATCH 08/22] target/openrisc: Streamline arithmetic and OVE
  2017-02-09  4:51 [Qemu-devel] [PATCH 00/22] target/openrisc updates Richard Henderson
                   ` (5 preceding siblings ...)
  2017-02-09  4:51 ` [Qemu-devel] [PATCH 07/22] target/openrisc: Rationalize immediate extraction Richard Henderson
@ 2017-02-09  4:51 ` Richard Henderson
  2017-02-09  4:51 ` [Qemu-devel] [PATCH 09/22] target/openrisc: Put SR[OVE] in TB flags Richard Henderson
                   ` (14 subsequent siblings)
  21 siblings, 0 replies; 30+ messages in thread
From: Richard Henderson @ 2017-02-09  4:51 UTC (permalink / raw)
  To: qemu-devel; +Cc: shorne

Fix incorrect overflow calculation.  Move overflow exception check
to a helper function, to eliminate inline branches.  Remove some
incorrect special casing of R0.  Implement multiply inline.

Reviewed-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 target/openrisc/Makefile.objs      |   2 +-
 target/openrisc/exception_helper.c |  12 ++
 target/openrisc/helper.h           |   4 +-
 target/openrisc/int_helper.c       |  61 ------
 target/openrisc/translate.c        | 426 +++++++++++++++----------------------
 5 files changed, 191 insertions(+), 314 deletions(-)
 delete mode 100644 target/openrisc/int_helper.c

diff --git a/target/openrisc/Makefile.objs b/target/openrisc/Makefile.objs
index 397d016..918b1c6 100644
--- a/target/openrisc/Makefile.objs
+++ b/target/openrisc/Makefile.objs
@@ -1,5 +1,5 @@
 obj-$(CONFIG_SOFTMMU) += machine.o
 obj-y += cpu.o exception.o interrupt.o mmu.o translate.o
-obj-y += exception_helper.o fpu_helper.o int_helper.o \
+obj-y += exception_helper.o fpu_helper.o \
          interrupt_helper.o mmu_helper.o sys_helper.o
 obj-y += gdbstub.o
diff --git a/target/openrisc/exception_helper.c b/target/openrisc/exception_helper.c
index 329a9e4..7e54c97 100644
--- a/target/openrisc/exception_helper.c
+++ b/target/openrisc/exception_helper.c
@@ -20,6 +20,7 @@
 #include "qemu/osdep.h"
 #include "cpu.h"
 #include "exec/helper-proto.h"
+#include "exec/exec-all.h"
 #include "exception.h"
 
 void HELPER(exception)(CPUOpenRISCState *env, uint32_t excp)
@@ -28,3 +29,14 @@ void HELPER(exception)(CPUOpenRISCState *env, uint32_t excp)
 
     raise_exception(cpu, excp);
 }
+
+void HELPER(ove)(CPUOpenRISCState *env, target_ulong test)
+{
+    if (unlikely(test) && (env->sr & SR_OVE)) {
+        OpenRISCCPU *cpu = openrisc_env_get_cpu(env);
+        CPUState *cs = CPU(cpu);
+
+        cs->exception_index = EXCP_RANGE;
+        cpu_loop_exit_restore(cs, GETPC());
+    }
+}
diff --git a/target/openrisc/helper.h b/target/openrisc/helper.h
index bcc7245..c2c8098 100644
--- a/target/openrisc/helper.h
+++ b/target/openrisc/helper.h
@@ -19,6 +19,7 @@
 
 /* exception */
 DEF_HELPER_FLAGS_2(exception, 0, void, env, i32)
+DEF_HELPER_FLAGS_2(ove, TCG_CALL_NO_WG, void, env, tl)
 
 /* float */
 DEF_HELPER_FLAGS_2(itofd, 0, i64, env, i64)
@@ -53,9 +54,6 @@ FOP_CMP(gt)
 FOP_CMP(ge)
 #undef FOP_CMP
 
-/* int */
-DEF_HELPER_FLAGS_3(mul32, 0, i32, env, i32, i32)
-
 /* interrupt */
 DEF_HELPER_FLAGS_1(rfe, 0, void, env)
 
diff --git a/target/openrisc/int_helper.c b/target/openrisc/int_helper.c
deleted file mode 100644
index ba0fd27..0000000
--- a/target/openrisc/int_helper.c
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * OpenRISC int helper routines
- *
- * Copyright (c) 2011-2012 Jia Liu <proljc@gmail.com>
- *                         Feng Gao <gf91597@gmail.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "qemu/osdep.h"
-#include "cpu.h"
-#include "exec/helper-proto.h"
-#include "exception.h"
-#include "qemu/host-utils.h"
-
-uint32_t HELPER(mul32)(CPUOpenRISCState *env,
-                       uint32_t ra, uint32_t rb)
-{
-    uint64_t result;
-    uint32_t high, cy;
-
-    OpenRISCCPU *cpu = openrisc_env_get_cpu(env);
-
-    result = (uint64_t)ra * rb;
-    /* regisiers in or32 is 32bit, so 32 is NOT a magic number.
-       or64 is not handled in this function, and not implement yet,
-       TARGET_LONG_BITS for or64 is 64, it will break this function,
-       so, we didn't use TARGET_LONG_BITS here.  */
-    high = result >> 32;
-    cy = result >> (32 - 1);
-
-    if ((cy & 0x1) == 0x0) {
-        if (high == 0x0) {
-            return result;
-        }
-    }
-
-    if ((cy & 0x1) == 0x1) {
-        if (high == 0xffffffff) {
-            return result;
-        }
-    }
-
-    cpu->env.sr |= (SR_OV | SR_CY);
-    if (cpu->env.sr & SR_OVE) {
-        raise_exception(cpu, EXCP_RANGE);
-    }
-
-    return result;
-}
diff --git a/target/openrisc/translate.c b/target/openrisc/translate.c
index d999d2f..7c6cd1c 100644
--- a/target/openrisc/translate.c
+++ b/target/openrisc/translate.c
@@ -247,6 +247,166 @@ static void gen_jump(DisasContext *dc, int32_t n26, uint32_t reg, uint32_t op0)
     gen_sync_flags(dc);
 }
 
+static void gen_ove_cy(DisasContext *dc, TCGv cy)
+{
+    gen_helper_ove(cpu_env, cy);
+}
+
+static void gen_ove_ov(DisasContext *dc, TCGv ov)
+{
+    gen_helper_ove(cpu_env, ov);
+}
+
+static void gen_ove_cyov(DisasContext *dc, TCGv cy, TCGv ov)
+{
+    TCGv t0 = tcg_temp_new();
+    tcg_gen_or_tl(t0, cy, ov);
+    gen_helper_ove(cpu_env, t0);
+    tcg_temp_free(t0);
+}
+
+static void gen_add(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb)
+{
+    TCGv t0 = tcg_const_tl(0);
+    TCGv res = tcg_temp_new();
+    TCGv sr_cy = tcg_temp_new();
+    TCGv sr_ov = tcg_temp_new();
+
+    tcg_gen_add2_tl(res, sr_cy, srca, t0, srcb, t0);
+    tcg_gen_xor_tl(sr_ov, srca, srcb);
+    tcg_gen_xor_tl(t0, res, srcb);
+    tcg_gen_andc_tl(sr_ov, t0, sr_ov);
+    tcg_temp_free(t0);
+
+    tcg_gen_mov_tl(dest, res);
+    tcg_temp_free(res);
+
+    tcg_gen_shri_tl(sr_ov, sr_ov, TARGET_LONG_BITS - 1);
+    tcg_gen_deposit_tl(cpu_sr, cpu_sr, sr_cy, ctz32(SR_CY), 1);
+    tcg_gen_deposit_tl(cpu_sr, cpu_sr, sr_ov, ctz32(SR_OV), 1);
+
+    gen_ove_cyov(dc, sr_ov, sr_cy);
+    tcg_temp_free(sr_ov);
+    tcg_temp_free(sr_cy);
+}
+
+static void gen_addc(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb)
+{
+    TCGv t0 = tcg_const_tl(0);
+    TCGv res = tcg_temp_new();
+    TCGv sr_cy = tcg_temp_new();
+    TCGv sr_ov = tcg_temp_new();
+
+    tcg_gen_shri_tl(sr_cy, cpu_sr, ctz32(SR_CY));
+    tcg_gen_andi_tl(sr_cy, sr_cy, 1);
+
+    tcg_gen_add2_tl(res, sr_cy, srca, t0, sr_cy, t0);
+    tcg_gen_add2_tl(res, sr_cy, res, sr_cy, srcb, t0);
+    tcg_gen_xor_tl(sr_ov, srca, srcb);
+    tcg_gen_xor_tl(t0, res, srcb);
+    tcg_gen_andc_tl(sr_ov, t0, sr_ov);
+    tcg_temp_free(t0);
+
+    tcg_gen_mov_tl(dest, res);
+    tcg_temp_free(res);
+
+    tcg_gen_shri_tl(sr_ov, sr_ov, TARGET_LONG_BITS - 1);
+    tcg_gen_deposit_tl(cpu_sr, cpu_sr, sr_cy, ctz32(SR_CY), 1);
+    tcg_gen_deposit_tl(cpu_sr, cpu_sr, sr_ov, ctz32(SR_OV), 1);
+
+    gen_ove_cyov(dc, sr_ov, sr_cy);
+    tcg_temp_free(sr_ov);
+    tcg_temp_free(sr_cy);
+}
+
+static void gen_sub(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb)
+{
+    TCGv res = tcg_temp_new();
+    TCGv sr_cy = tcg_temp_new();
+    TCGv sr_ov = tcg_temp_new();
+
+    tcg_gen_sub_tl(res, srca, srcb);
+    tcg_gen_xor_tl(sr_cy, srca, srcb);
+    tcg_gen_xor_tl(sr_ov, res, srcb);
+    tcg_gen_and_tl(sr_ov, sr_ov, sr_cy);
+    tcg_gen_setcond_tl(TCG_COND_LTU, sr_cy, srca, srcb);
+
+    tcg_gen_mov_tl(dest, res);
+    tcg_temp_free(res);
+
+    tcg_gen_shri_tl(sr_ov, sr_ov, TARGET_LONG_BITS - 1);
+    tcg_gen_deposit_tl(cpu_sr, cpu_sr, sr_cy, ctz32(SR_CY), 1);
+    tcg_gen_deposit_tl(cpu_sr, cpu_sr, sr_ov, ctz32(SR_OV), 1);
+
+    gen_ove_cyov(dc, sr_ov, sr_cy);
+    tcg_temp_free(sr_ov);
+    tcg_temp_free(sr_cy);
+}
+
+static void gen_mul(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb)
+{
+    TCGv sr_ov = tcg_temp_new();
+    TCGv t0 = tcg_temp_new();
+
+    tcg_gen_muls2_tl(dest, sr_ov, srca, srcb);
+    tcg_gen_sari_tl(t0, dest, TARGET_LONG_BITS - 1);
+    tcg_gen_setcond_tl(TCG_COND_NE, sr_ov, sr_ov, t0);
+    tcg_temp_free(t0);
+
+    tcg_gen_deposit_tl(cpu_sr, cpu_sr, sr_ov, ctz32(SR_OV), 1);
+
+    gen_ove_ov(dc, sr_ov);
+    tcg_temp_free(sr_ov);
+}
+
+static void gen_mulu(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb)
+{
+    TCGv sr_cy = tcg_temp_new();
+
+    tcg_gen_muls2_tl(dest, sr_cy, srca, srcb);
+    tcg_gen_setcondi_tl(TCG_COND_NE, sr_cy, sr_cy, 0);
+
+    tcg_gen_deposit_tl(cpu_sr, cpu_sr, sr_cy, ctz32(SR_CY), 1);
+
+    gen_ove_cy(dc, sr_cy);
+    tcg_temp_free(sr_cy);
+}
+
+static void gen_div(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb)
+{
+    TCGv sr_ov = tcg_temp_new();
+    TCGv t0 = tcg_temp_new();
+
+    tcg_gen_setcondi_tl(TCG_COND_EQ, sr_ov, srcb, 0);
+    /* The result of divide-by-zero is undefined.
+       Supress the host-side exception by dividing by 1.  */
+    tcg_gen_or_tl(t0, srcb, sr_ov);
+    tcg_gen_div_tl(dest, srca, t0);
+    tcg_temp_free(t0);
+
+    tcg_gen_deposit_tl(cpu_sr, cpu_sr, sr_ov, ctz32(SR_OV), 1);
+
+    gen_ove_ov(dc, sr_ov);
+    tcg_temp_free(sr_ov);
+}
+
+static void gen_divu(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb)
+{
+    TCGv sr_cy = tcg_temp_new();
+    TCGv t0 = tcg_temp_new();
+
+    tcg_gen_setcondi_tl(TCG_COND_EQ, sr_cy, srcb, 0);
+    /* The result of divide-by-zero is undefined.
+       Supress the host-side exception by dividing by 1.  */
+    tcg_gen_or_tl(t0, srcb, sr_cy);
+    tcg_gen_divu_tl(dest, srca, t0);
+    tcg_temp_free(t0);
+
+    tcg_gen_deposit_tl(cpu_sr, cpu_sr, sr_cy, ctz32(SR_CY), 1);
+
+    gen_ove_cy(dc, sr_cy);
+    tcg_temp_free(sr_cy);
+}
 
 static void gen_lwa(DisasContext *dc, TCGv rd, TCGv ra, int32_t ofs)
 {
@@ -304,34 +464,7 @@ static void dec_calc(DisasContext *dc, uint32_t insn)
         switch (op1) {
         case 0x00:    /* l.add */
             LOG_DIS("l.add r%d, r%d, r%d\n", rd, ra, rb);
-            {
-                TCGLabel *lab = gen_new_label();
-                TCGv_i64 ta = tcg_temp_new_i64();
-                TCGv_i64 tb = tcg_temp_new_i64();
-                TCGv_i64 td = tcg_temp_local_new_i64();
-                TCGv_i32 res = tcg_temp_local_new_i32();
-                TCGv_i32 sr_ove = tcg_temp_local_new_i32();
-                tcg_gen_extu_i32_i64(ta, cpu_R[ra]);
-                tcg_gen_extu_i32_i64(tb, cpu_R[rb]);
-                tcg_gen_add_i64(td, ta, tb);
-                tcg_gen_extrl_i64_i32(res, td);
-                tcg_gen_shri_i64(td, td, 31);
-                tcg_gen_andi_i64(td, td, 0x3);
-                /* Jump to lab when no overflow.  */
-                tcg_gen_brcondi_i64(TCG_COND_EQ, td, 0x0, lab);
-                tcg_gen_brcondi_i64(TCG_COND_EQ, td, 0x3, lab);
-                tcg_gen_ori_i32(cpu_sr, cpu_sr, (SR_OV | SR_CY));
-                tcg_gen_andi_i32(sr_ove, cpu_sr, SR_OVE);
-                tcg_gen_brcondi_i32(TCG_COND_NE, sr_ove, SR_OVE, lab);
-                gen_exception(dc, EXCP_RANGE);
-                gen_set_label(lab);
-                tcg_gen_mov_i32(cpu_R[rd], res);
-                tcg_temp_free_i64(ta);
-                tcg_temp_free_i64(tb);
-                tcg_temp_free_i64(td);
-                tcg_temp_free_i32(res);
-                tcg_temp_free_i32(sr_ove);
-            }
+            gen_add(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]);
             break;
         default:
             gen_illegal_exception(dc);
@@ -343,42 +476,7 @@ static void dec_calc(DisasContext *dc, uint32_t insn)
         switch (op1) {
         case 0x00:
             LOG_DIS("l.addc r%d, r%d, r%d\n", rd, ra, rb);
-            {
-                TCGLabel *lab = gen_new_label();
-                TCGv_i64 ta = tcg_temp_new_i64();
-                TCGv_i64 tb = tcg_temp_new_i64();
-                TCGv_i64 tcy = tcg_temp_local_new_i64();
-                TCGv_i64 td = tcg_temp_local_new_i64();
-                TCGv_i32 res = tcg_temp_local_new_i32();
-                TCGv_i32 sr_cy = tcg_temp_local_new_i32();
-                TCGv_i32 sr_ove = tcg_temp_local_new_i32();
-                tcg_gen_extu_i32_i64(ta, cpu_R[ra]);
-                tcg_gen_extu_i32_i64(tb, cpu_R[rb]);
-                tcg_gen_andi_i32(sr_cy, cpu_sr, SR_CY);
-                tcg_gen_extu_i32_i64(tcy, sr_cy);
-                tcg_gen_shri_i64(tcy, tcy, 10);
-                tcg_gen_add_i64(td, ta, tb);
-                tcg_gen_add_i64(td, td, tcy);
-                tcg_gen_extrl_i64_i32(res, td);
-                tcg_gen_shri_i64(td, td, 32);
-                tcg_gen_andi_i64(td, td, 0x3);
-                /* Jump to lab when no overflow.  */
-                tcg_gen_brcondi_i64(TCG_COND_EQ, td, 0x0, lab);
-                tcg_gen_brcondi_i64(TCG_COND_EQ, td, 0x3, lab);
-                tcg_gen_ori_i32(cpu_sr, cpu_sr, (SR_OV | SR_CY));
-                tcg_gen_andi_i32(sr_ove, cpu_sr, SR_OVE);
-                tcg_gen_brcondi_i32(TCG_COND_NE, sr_ove, SR_OVE, lab);
-                gen_exception(dc, EXCP_RANGE);
-                gen_set_label(lab);
-                tcg_gen_mov_i32(cpu_R[rd], res);
-                tcg_temp_free_i64(ta);
-                tcg_temp_free_i64(tb);
-                tcg_temp_free_i64(tcy);
-                tcg_temp_free_i64(td);
-                tcg_temp_free_i32(res);
-                tcg_temp_free_i32(sr_cy);
-                tcg_temp_free_i32(sr_ove);
-            }
+            gen_addc(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]);
             break;
         default:
             gen_illegal_exception(dc);
@@ -390,35 +488,7 @@ static void dec_calc(DisasContext *dc, uint32_t insn)
         switch (op1) {
         case 0x00:
             LOG_DIS("l.sub r%d, r%d, r%d\n", rd, ra, rb);
-            {
-                TCGLabel *lab = gen_new_label();
-                TCGv_i64 ta = tcg_temp_new_i64();
-                TCGv_i64 tb = tcg_temp_new_i64();
-                TCGv_i64 td = tcg_temp_local_new_i64();
-                TCGv_i32 res = tcg_temp_local_new_i32();
-                TCGv_i32 sr_ove = tcg_temp_local_new_i32();
-
-                tcg_gen_extu_i32_i64(ta, cpu_R[ra]);
-                tcg_gen_extu_i32_i64(tb, cpu_R[rb]);
-                tcg_gen_sub_i64(td, ta, tb);
-                tcg_gen_extrl_i64_i32(res, td);
-                tcg_gen_shri_i64(td, td, 31);
-                tcg_gen_andi_i64(td, td, 0x3);
-                /* Jump to lab when no overflow.  */
-                tcg_gen_brcondi_i64(TCG_COND_EQ, td, 0x0, lab);
-                tcg_gen_brcondi_i64(TCG_COND_EQ, td, 0x3, lab);
-                tcg_gen_ori_i32(cpu_sr, cpu_sr, (SR_OV | SR_CY));
-                tcg_gen_andi_i32(sr_ove, cpu_sr, SR_OVE);
-                tcg_gen_brcondi_i32(TCG_COND_NE, sr_ove, SR_OVE, lab);
-                gen_exception(dc, EXCP_RANGE);
-                gen_set_label(lab);
-                tcg_gen_mov_i32(cpu_R[rd], res);
-                tcg_temp_free_i64(ta);
-                tcg_temp_free_i64(tb);
-                tcg_temp_free_i64(td);
-                tcg_temp_free_i32(res);
-                tcg_temp_free_i32(sr_ove);
-            }
+            gen_sub(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]);
             break;
         default:
             gen_illegal_exception(dc);
@@ -466,11 +536,7 @@ static void dec_calc(DisasContext *dc, uint32_t insn)
         switch (op1) {
         case 0x03:    /* l.mul */
             LOG_DIS("l.mul r%d, r%d, r%d\n", rd, ra, rb);
-            if (ra != 0 && rb != 0) {
-                gen_helper_mul32(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
-            } else {
-                tcg_gen_movi_tl(cpu_R[rd], 0x0);
-            }
+            gen_mul(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]);
             break;
         default:
             gen_illegal_exception(dc);
@@ -482,36 +548,7 @@ static void dec_calc(DisasContext *dc, uint32_t insn)
         switch (op1) {
         case 0x03:    /* l.div */
             LOG_DIS("l.div r%d, r%d, r%d\n", rd, ra, rb);
-            {
-                TCGLabel *lab0 = gen_new_label();
-                TCGLabel *lab1 = gen_new_label();
-                TCGLabel *lab2 = gen_new_label();
-                TCGLabel *lab3 = gen_new_label();
-                TCGv_i32 sr_ove = tcg_temp_local_new_i32();
-                if (rb == 0) {
-                    tcg_gen_ori_tl(cpu_sr, cpu_sr, (SR_OV | SR_CY));
-                    tcg_gen_andi_tl(sr_ove, cpu_sr, SR_OVE);
-                    tcg_gen_brcondi_tl(TCG_COND_NE, sr_ove, SR_OVE, lab0);
-                    gen_exception(dc, EXCP_RANGE);
-                    gen_set_label(lab0);
-                } else {
-                    tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_R[rb],
-                                       0x00000000, lab1);
-                    tcg_gen_brcondi_tl(TCG_COND_NE, cpu_R[ra],
-                                       0x80000000, lab2);
-                    tcg_gen_brcondi_tl(TCG_COND_NE, cpu_R[rb],
-                                       0xffffffff, lab2);
-                    gen_set_label(lab1);
-                    tcg_gen_ori_tl(cpu_sr, cpu_sr, (SR_OV | SR_CY));
-                    tcg_gen_andi_tl(sr_ove, cpu_sr, SR_OVE);
-                    tcg_gen_brcondi_tl(TCG_COND_NE, sr_ove, SR_OVE, lab3);
-                    gen_exception(dc, EXCP_RANGE);
-                    gen_set_label(lab2);
-                    tcg_gen_div_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);
-                    gen_set_label(lab3);
-                }
-                tcg_temp_free_i32(sr_ove);
-            }
+            gen_div(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]);
             break;
 
         default:
@@ -524,30 +561,7 @@ static void dec_calc(DisasContext *dc, uint32_t insn)
         switch (op1) {
         case 0x03:    /* l.divu */
             LOG_DIS("l.divu r%d, r%d, r%d\n", rd, ra, rb);
-            {
-                TCGLabel *lab0 = gen_new_label();
-                TCGLabel *lab1 = gen_new_label();
-                TCGLabel *lab2 = gen_new_label();
-                TCGv_i32 sr_ove = tcg_temp_local_new_i32();
-                if (rb == 0) {
-                    tcg_gen_ori_tl(cpu_sr, cpu_sr, (SR_OV | SR_CY));
-                    tcg_gen_andi_tl(sr_ove, cpu_sr, SR_OVE);
-                    tcg_gen_brcondi_tl(TCG_COND_NE, sr_ove, SR_OVE, lab0);
-                    gen_exception(dc, EXCP_RANGE);
-                    gen_set_label(lab0);
-                } else {
-                    tcg_gen_brcondi_tl(TCG_COND_NE, cpu_R[rb],
-                                       0x00000000, lab1);
-                    tcg_gen_ori_tl(cpu_sr, cpu_sr, (SR_OV | SR_CY));
-                    tcg_gen_andi_tl(sr_ove, cpu_sr, SR_OVE);
-                    tcg_gen_brcondi_tl(TCG_COND_NE, sr_ove, SR_OVE, lab2);
-                    gen_exception(dc, EXCP_RANGE);
-                    gen_set_label(lab1);
-                    tcg_gen_divu_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);
-                    gen_set_label(lab2);
-                }
-                tcg_temp_free_i32(sr_ove);
-            }
+            gen_divu(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]);
             break;
 
         default:
@@ -560,34 +574,7 @@ static void dec_calc(DisasContext *dc, uint32_t insn)
         switch (op1) {
         case 0x03:    /* l.mulu */
             LOG_DIS("l.mulu r%d, r%d, r%d\n", rd, ra, rb);
-            if (rb != 0 && ra != 0) {
-                TCGv_i64 result = tcg_temp_local_new_i64();
-                TCGv_i64 tra = tcg_temp_local_new_i64();
-                TCGv_i64 trb = tcg_temp_local_new_i64();
-                TCGv_i64 high = tcg_temp_new_i64();
-                TCGv_i32 sr_ove = tcg_temp_local_new_i32();
-                TCGLabel *lab = gen_new_label();
-                /* Calculate each result. */
-                tcg_gen_extu_i32_i64(tra, cpu_R[ra]);
-                tcg_gen_extu_i32_i64(trb, cpu_R[rb]);
-                tcg_gen_mul_i64(result, tra, trb);
-                tcg_temp_free_i64(tra);
-                tcg_temp_free_i64(trb);
-                tcg_gen_shri_i64(high, result, TARGET_LONG_BITS);
-                /* Overflow or not. */
-                tcg_gen_brcondi_i64(TCG_COND_EQ, high, 0x00000000, lab);
-                tcg_gen_ori_tl(cpu_sr, cpu_sr, (SR_OV | SR_CY));
-                tcg_gen_andi_tl(sr_ove, cpu_sr, SR_OVE);
-                tcg_gen_brcondi_tl(TCG_COND_NE, sr_ove, SR_OVE, lab);
-                gen_exception(dc, EXCP_RANGE);
-                gen_set_label(lab);
-                tcg_temp_free_i64(high);
-                tcg_gen_trunc_i64_tl(cpu_R[rd], result);
-                tcg_temp_free_i64(result);
-                tcg_temp_free_i32(sr_ove);
-            } else {
-                tcg_gen_movi_tl(cpu_R[rd], 0);
-            }
+            gen_mulu(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]);
             break;
 
         default:
@@ -744,6 +731,7 @@ static void dec_misc(DisasContext *dc, uint32_t insn)
     uint32_t L6, K5, K16, K5_11;
     int32_t I16, I5_11, N26;
     TCGMemOp mop;
+    TCGv t0;
 
     op0 = extract32(insn, 26, 6);
     op1 = extract32(insn, 24, 2);
@@ -925,72 +913,16 @@ static void dec_misc(DisasContext *dc, uint32_t insn)
 
     case 0x27:    /* l.addi */
         LOG_DIS("l.addi r%d, r%d, %d\n", rd, ra, I16);
-        {
-            if (I16 == 0) {
-                tcg_gen_mov_tl(cpu_R[rd], cpu_R[ra]);
-            } else {
-                TCGLabel *lab = gen_new_label();
-                TCGv_i64 ta = tcg_temp_new_i64();
-                TCGv_i64 td = tcg_temp_local_new_i64();
-                TCGv_i32 res = tcg_temp_local_new_i32();
-                TCGv_i32 sr_ove = tcg_temp_local_new_i32();
-                tcg_gen_extu_i32_i64(ta, cpu_R[ra]);
-                tcg_gen_addi_i64(td, ta, I16);
-                tcg_gen_extrl_i64_i32(res, td);
-                tcg_gen_shri_i64(td, td, 32);
-                tcg_gen_andi_i64(td, td, 0x3);
-                /* Jump to lab when no overflow.  */
-                tcg_gen_brcondi_i64(TCG_COND_EQ, td, 0x0, lab);
-                tcg_gen_brcondi_i64(TCG_COND_EQ, td, 0x3, lab);
-                tcg_gen_ori_i32(cpu_sr, cpu_sr, (SR_OV | SR_CY));
-                tcg_gen_andi_i32(sr_ove, cpu_sr, SR_OVE);
-                tcg_gen_brcondi_i32(TCG_COND_NE, sr_ove, SR_OVE, lab);
-                gen_exception(dc, EXCP_RANGE);
-                gen_set_label(lab);
-                tcg_gen_mov_i32(cpu_R[rd], res);
-                tcg_temp_free_i64(ta);
-                tcg_temp_free_i64(td);
-                tcg_temp_free_i32(res);
-                tcg_temp_free_i32(sr_ove);
-            }
-        }
+        t0 = tcg_const_tl(I16);
+        gen_add(dc, cpu_R[rd], cpu_R[ra], t0);
+        tcg_temp_free(t0);
         break;
 
     case 0x28:    /* l.addic */
         LOG_DIS("l.addic r%d, r%d, %d\n", rd, ra, I16);
-        {
-            TCGLabel *lab = gen_new_label();
-            TCGv_i64 ta = tcg_temp_new_i64();
-            TCGv_i64 td = tcg_temp_local_new_i64();
-            TCGv_i64 tcy = tcg_temp_local_new_i64();
-            TCGv_i32 res = tcg_temp_local_new_i32();
-            TCGv_i32 sr_cy = tcg_temp_local_new_i32();
-            TCGv_i32 sr_ove = tcg_temp_local_new_i32();
-            tcg_gen_extu_i32_i64(ta, cpu_R[ra]);
-            tcg_gen_andi_i32(sr_cy, cpu_sr, SR_CY);
-            tcg_gen_shri_i32(sr_cy, sr_cy, 10);
-            tcg_gen_extu_i32_i64(tcy, sr_cy);
-            tcg_gen_addi_i64(td, ta, I16);
-            tcg_gen_add_i64(td, td, tcy);
-            tcg_gen_extrl_i64_i32(res, td);
-            tcg_gen_shri_i64(td, td, 32);
-            tcg_gen_andi_i64(td, td, 0x3);
-            /* Jump to lab when no overflow.  */
-            tcg_gen_brcondi_i64(TCG_COND_EQ, td, 0x0, lab);
-            tcg_gen_brcondi_i64(TCG_COND_EQ, td, 0x3, lab);
-            tcg_gen_ori_i32(cpu_sr, cpu_sr, (SR_OV | SR_CY));
-            tcg_gen_andi_i32(sr_ove, cpu_sr, SR_OVE);
-            tcg_gen_brcondi_i32(TCG_COND_NE, sr_ove, SR_OVE, lab);
-            gen_exception(dc, EXCP_RANGE);
-            gen_set_label(lab);
-            tcg_gen_mov_i32(cpu_R[rd], res);
-            tcg_temp_free_i64(ta);
-            tcg_temp_free_i64(td);
-            tcg_temp_free_i64(tcy);
-            tcg_temp_free_i32(res);
-            tcg_temp_free_i32(sr_cy);
-            tcg_temp_free_i32(sr_ove);
-        }
+        t0 = tcg_const_tl(I16);
+        gen_addc(dc, cpu_R[rd], cpu_R[ra], t0);
+        tcg_temp_free(t0);
         break;
 
     case 0x29:    /* l.andi */
@@ -1010,13 +942,9 @@ static void dec_misc(DisasContext *dc, uint32_t insn)
 
     case 0x2c:    /* l.muli */
         LOG_DIS("l.muli r%d, r%d, %d\n", rd, ra, I16);
-        if (ra != 0 && I16 != 0) {
-            TCGv_i32 im = tcg_const_i32(I16);
-            gen_helper_mul32(cpu_R[rd], cpu_env, cpu_R[ra], im);
-            tcg_temp_free_i32(im);
-        } else {
-            tcg_gen_movi_tl(cpu_R[rd], 0x0);
-        }
+        t0 = tcg_const_tl(I16);
+        gen_mul(dc, cpu_R[rd], cpu_R[ra], t0);
+        tcg_temp_free(t0);
         break;
 
     case 0x2d:    /* l.mfspr */
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Qemu-devel] [PATCH 09/22] target/openrisc: Put SR[OVE] in TB flags
  2017-02-09  4:51 [Qemu-devel] [PATCH 00/22] target/openrisc updates Richard Henderson
                   ` (6 preceding siblings ...)
  2017-02-09  4:51 ` [Qemu-devel] [PATCH 08/22] target/openrisc: Streamline arithmetic and OVE Richard Henderson
@ 2017-02-09  4:51 ` Richard Henderson
  2017-02-09  4:51 ` [Qemu-devel] [PATCH 10/22] target/openrisc: Invert the decoding in dec_calc Richard Henderson
                   ` (13 subsequent siblings)
  21 siblings, 0 replies; 30+ messages in thread
From: Richard Henderson @ 2017-02-09  4:51 UTC (permalink / raw)
  To: qemu-devel; +Cc: shorne

Removes a call at execution time for overflow exceptions.

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 target/openrisc/cpu.h              |  4 ++--
 target/openrisc/exception_helper.c |  2 +-
 target/openrisc/translate.c        | 24 +++++++++++++++---------
 3 files changed, 18 insertions(+), 12 deletions(-)

diff --git a/target/openrisc/cpu.h b/target/openrisc/cpu.h
index 06d0e89..ef90e49 100644
--- a/target/openrisc/cpu.h
+++ b/target/openrisc/cpu.h
@@ -400,8 +400,8 @@ static inline void cpu_get_tb_cpu_state(CPUOpenRISCState *env,
 {
     *pc = env->pc;
     *cs_base = 0;
-    /* D_FLAG -- branch instruction exception */
-    *flags = (env->flags & D_FLAG);
+    /* D_FLAG -- branch instruction exception, OVE overflow trap enable.  */
+    *flags = (env->flags & D_FLAG) | (env->sr & SR_OVE);
 }
 
 static inline int cpu_mmu_index(CPUOpenRISCState *env, bool ifetch)
diff --git a/target/openrisc/exception_helper.c b/target/openrisc/exception_helper.c
index 7e54c97..5147da6 100644
--- a/target/openrisc/exception_helper.c
+++ b/target/openrisc/exception_helper.c
@@ -32,7 +32,7 @@ void HELPER(exception)(CPUOpenRISCState *env, uint32_t excp)
 
 void HELPER(ove)(CPUOpenRISCState *env, target_ulong test)
 {
-    if (unlikely(test) && (env->sr & SR_OVE)) {
+    if (unlikely(test)) {
         OpenRISCCPU *cpu = openrisc_env_get_cpu(env);
         CPUState *cs = CPU(cpu);
 
diff --git a/target/openrisc/translate.c b/target/openrisc/translate.c
index 7c6cd1c..b8116ba 100644
--- a/target/openrisc/translate.c
+++ b/target/openrisc/translate.c
@@ -132,8 +132,8 @@ static inline void wb_SR_F(void)
 static inline void gen_sync_flags(DisasContext *dc)
 {
     /* Sync the tb dependent flag between translate and runtime.  */
-    if (dc->tb_flags != dc->synced_flags) {
-        tcg_gen_movi_tl(env_flags, dc->tb_flags);
+    if ((dc->tb_flags ^ dc->synced_flags) & D_FLAG) {
+        tcg_gen_movi_tl(env_flags, dc->tb_flags & D_FLAG);
         dc->synced_flags = dc->tb_flags;
     }
 }
@@ -249,20 +249,26 @@ static void gen_jump(DisasContext *dc, int32_t n26, uint32_t reg, uint32_t op0)
 
 static void gen_ove_cy(DisasContext *dc, TCGv cy)
 {
-    gen_helper_ove(cpu_env, cy);
+    if (dc->tb_flags & SR_OVE) {
+        gen_helper_ove(cpu_env, cy);
+    }
 }
 
 static void gen_ove_ov(DisasContext *dc, TCGv ov)
 {
-    gen_helper_ove(cpu_env, ov);
+    if (dc->tb_flags & SR_OVE) {
+        gen_helper_ove(cpu_env, ov);
+    }
 }
 
 static void gen_ove_cyov(DisasContext *dc, TCGv cy, TCGv ov)
 {
-    TCGv t0 = tcg_temp_new();
-    tcg_gen_or_tl(t0, cy, ov);
-    gen_helper_ove(cpu_env, t0);
-    tcg_temp_free(t0);
+    if (dc->tb_flags & SR_OVE) {
+        TCGv t0 = tcg_temp_new();
+        tcg_gen_or_tl(t0, cy, ov);
+        gen_helper_ove(cpu_env, t0);
+        tcg_temp_free(t0);
+    }
 }
 
 static void gen_add(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb)
@@ -1606,7 +1612,7 @@ void gen_intermediate_code(CPUOpenRISCState *env, struct TranslationBlock *tb)
     dc->flags = cpu->env.cpucfgr;
     dc->mem_idx = cpu_mmu_index(&cpu->env, false);
     dc->synced_flags = dc->tb_flags = tb->flags;
-    dc->delayed_branch = !!(dc->tb_flags & D_FLAG);
+    dc->delayed_branch = (dc->tb_flags & D_FLAG) != 0;
     dc->singlestep_enabled = cs->singlestep_enabled;
 
     next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Qemu-devel] [PATCH 10/22] target/openrisc: Invert the decoding in dec_calc
  2017-02-09  4:51 [Qemu-devel] [PATCH 00/22] target/openrisc updates Richard Henderson
                   ` (7 preceding siblings ...)
  2017-02-09  4:51 ` [Qemu-devel] [PATCH 09/22] target/openrisc: Put SR[OVE] in TB flags Richard Henderson
@ 2017-02-09  4:51 ` Richard Henderson
  2017-02-09  4:51 ` [Qemu-devel] [PATCH 11/22] target/openrisc: Keep SR_F in a separate variable Richard Henderson
                   ` (12 subsequent siblings)
  21 siblings, 0 replies; 30+ messages in thread
From: Richard Henderson @ 2017-02-09  4:51 UTC (permalink / raw)
  To: qemu-devel; +Cc: shorne

Decoding the opcodes in the right order reduces by 100+ lines.
Also, it happens to put the opcodes in the same order as Chapter 17.

Reviewed-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 target/openrisc/translate.c | 302 ++++++++++++++------------------------------
 1 file changed, 95 insertions(+), 207 deletions(-)

diff --git a/target/openrisc/translate.c b/target/openrisc/translate.c
index b8116ba..1f3f22c 100644
--- a/target/openrisc/translate.c
+++ b/target/openrisc/translate.c
@@ -465,133 +465,95 @@ static void dec_calc(DisasContext *dc, uint32_t insn)
     rb = extract32(insn, 11, 5);
     rd = extract32(insn, 21, 5);
 
-    switch (op0) {
-    case 0x0000:
-        switch (op1) {
-        case 0x00:    /* l.add */
+    switch (op1) {
+    case 0:
+        switch (op0) {
+        case 0x0: /* l.add */
             LOG_DIS("l.add r%d, r%d, r%d\n", rd, ra, rb);
             gen_add(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]);
-            break;
-        default:
-            gen_illegal_exception(dc);
-            break;
-        }
-        break;
+            return;
 
-    case 0x0001:    /* l.addc */
-        switch (op1) {
-        case 0x00:
+        case 0x1: /* l.addc */
             LOG_DIS("l.addc r%d, r%d, r%d\n", rd, ra, rb);
             gen_addc(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]);
-            break;
-        default:
-            gen_illegal_exception(dc);
-            break;
-        }
-        break;
+            return;
 
-    case 0x0002:    /* l.sub */
-        switch (op1) {
-        case 0x00:
+        case 0x2: /* l.sub */
             LOG_DIS("l.sub r%d, r%d, r%d\n", rd, ra, rb);
             gen_sub(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]);
-            break;
-        default:
-            gen_illegal_exception(dc);
-            break;
-        }
-        break;
+            return;
 
-    case 0x0003:    /* l.and */
-        switch (op1) {
-        case 0x00:
+        case 0x3: /* l.and */
             LOG_DIS("l.and r%d, r%d, r%d\n", rd, ra, rb);
             tcg_gen_and_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);
-            break;
-        default:
-            gen_illegal_exception(dc);
-            break;
-        }
-        break;
+            return;
 
-    case 0x0004:    /* l.or */
-        switch (op1) {
-        case 0x00:
+        case 0x4: /* l.or */
             LOG_DIS("l.or r%d, r%d, r%d\n", rd, ra, rb);
             tcg_gen_or_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);
-            break;
-        default:
-            gen_illegal_exception(dc);
-            break;
-        }
-        break;
+            return;
 
-    case 0x0005:
-        switch (op1) {
-        case 0x00:    /* l.xor */
+        case 0x5: /* l.xor */
             LOG_DIS("l.xor r%d, r%d, r%d\n", rd, ra, rb);
             tcg_gen_xor_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);
-            break;
-        default:
-            gen_illegal_exception(dc);
-            break;
-        }
-        break;
-
-    case 0x0006:
-        switch (op1) {
-        case 0x03:    /* l.mul */
-            LOG_DIS("l.mul r%d, r%d, r%d\n", rd, ra, rb);
-            gen_mul(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]);
-            break;
-        default:
-            gen_illegal_exception(dc);
-            break;
-        }
-        break;
-
-    case 0x0009:
-        switch (op1) {
-        case 0x03:    /* l.div */
-            LOG_DIS("l.div r%d, r%d, r%d\n", rd, ra, rb);
-            gen_div(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]);
-            break;
-
-        default:
-            gen_illegal_exception(dc);
-            break;
-        }
-        break;
-
-    case 0x000a:
-        switch (op1) {
-        case 0x03:    /* l.divu */
-            LOG_DIS("l.divu r%d, r%d, r%d\n", rd, ra, rb);
-            gen_divu(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]);
-            break;
+            return;
 
-        default:
-            gen_illegal_exception(dc);
+        case 0x8:
+            switch (op2) {
+            case 0: /* l.sll */
+                LOG_DIS("l.sll r%d, r%d, r%d\n", rd, ra, rb);
+                tcg_gen_shl_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);
+                return;
+            case 1: /* l.srl */
+                LOG_DIS("l.srl r%d, r%d, r%d\n", rd, ra, rb);
+                tcg_gen_shr_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);
+                return;
+            case 2: /* l.sra */
+                LOG_DIS("l.sra r%d, r%d, r%d\n", rd, ra, rb);
+                tcg_gen_sar_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);
+                return;
+            case 3: /* l.ror */
+                LOG_DIS("l.ror r%d, r%d, r%d\n", rd, ra, rb);
+                tcg_gen_rotr_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);
+                return;
+            }
             break;
-        }
-        break;
 
-    case 0x000b:
-        switch (op1) {
-        case 0x03:    /* l.mulu */
-            LOG_DIS("l.mulu r%d, r%d, r%d\n", rd, ra, rb);
-            gen_mulu(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]);
+        case 0xc:
+            switch (op2) {
+            case 0: /* l.exths */
+                LOG_DIS("l.exths r%d, r%d\n", rd, ra);
+                tcg_gen_ext16s_tl(cpu_R[rd], cpu_R[ra]);
+                return;
+            case 1: /* l.extbs */
+                LOG_DIS("l.extbs r%d, r%d\n", rd, ra);
+                tcg_gen_ext8s_tl(cpu_R[rd], cpu_R[ra]);
+                return;
+            case 2: /* l.exthz */
+                LOG_DIS("l.exthz r%d, r%d\n", rd, ra);
+                tcg_gen_ext16u_tl(cpu_R[rd], cpu_R[ra]);
+                return;
+            case 3: /* l.extbz */
+                LOG_DIS("l.extbz r%d, r%d\n", rd, ra);
+                tcg_gen_ext8u_tl(cpu_R[rd], cpu_R[ra]);
+                return;
+            }
             break;
 
-        default:
-            gen_illegal_exception(dc);
+        case 0xd:
+            switch (op2) {
+            case 0: /* l.extws */
+                LOG_DIS("l.extws r%d, r%d\n", rd, ra);
+                tcg_gen_ext32s_tl(cpu_R[rd], cpu_R[ra]);
+                return;
+            case 1: /* l.extwz */
+                LOG_DIS("l.extwz r%d, r%d\n", rd, ra);
+                tcg_gen_ext32u_tl(cpu_R[rd], cpu_R[ra]);
+                return;
+            }
             break;
-        }
-        break;
 
-    case 0x000e:
-        switch (op1) {
-        case 0x00:    /* l.cmov */
+        case 0xe: /* l.cmov */
             LOG_DIS("l.cmov r%d, r%d, r%d\n", rd, ra, rb);
             {
                 TCGLabel *lab = gen_new_label();
@@ -606,128 +568,54 @@ static void dec_calc(DisasContext *dc, uint32_t insn)
                 tcg_temp_free(sr_f);
                 tcg_temp_free(res);
             }
-            break;
-
-        default:
-            gen_illegal_exception(dc);
-            break;
-        }
-        break;
+            return;
 
-    case 0x000f:
-        switch (op1) {
-        case 0x00:    /* l.ff1 */
+        case 0xf: /* l.ff1 */
             LOG_DIS("l.ff1 r%d, r%d, r%d\n", rd, ra, rb);
             tcg_gen_ctzi_tl(cpu_R[rd], cpu_R[ra], -1);
             tcg_gen_addi_tl(cpu_R[rd], cpu_R[rd], 1);
-            break;
-        case 0x01:    /* l.fl1 */
+            return;
+        }
+        break;
+
+    case 1:
+        switch (op0) {
+        case 0xf: /* l.fl1 */
             LOG_DIS("l.fl1 r%d, r%d, r%d\n", rd, ra, rb);
             tcg_gen_clzi_tl(cpu_R[rd], cpu_R[ra], TARGET_LONG_BITS);
             tcg_gen_subfi_tl(cpu_R[rd], TARGET_LONG_BITS, cpu_R[rd]);
-            break;
-
-        default:
-            gen_illegal_exception(dc);
-            break;
+            return;
         }
         break;
 
-    case 0x0008:
-        switch (op1) {
-        case 0x00:
-            switch (op2) {
-            case 0x00:    /* l.sll */
-                LOG_DIS("l.sll r%d, r%d, r%d\n", rd, ra, rb);
-                tcg_gen_shl_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);
-                break;
-            case 0x01:    /* l.srl */
-                LOG_DIS("l.srl r%d, r%d, r%d\n", rd, ra, rb);
-                tcg_gen_shr_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);
-                break;
-            case 0x02:    /* l.sra */
-                LOG_DIS("l.sra r%d, r%d, r%d\n", rd, ra, rb);
-                tcg_gen_sar_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);
-                break;
-            case 0x03:    /* l.ror */
-                LOG_DIS("l.ror r%d, r%d, r%d\n", rd, ra, rb);
-                tcg_gen_rotr_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);
-                break;
-
-            default:
-                gen_illegal_exception(dc);
-                break;
-            }
-            break;
-
-        default:
-            gen_illegal_exception(dc);
-            break;
-        }
+    case 2:
         break;
 
-    case 0x000c:
-        switch (op1) {
-        case 0x00:
-            switch (op2) {
-            case 0x00:    /* l.exths */
-                LOG_DIS("l.exths r%d, r%d\n", rd, ra);
-                tcg_gen_ext16s_tl(cpu_R[rd], cpu_R[ra]);
-                break;
-            case 0x01:    /* l.extbs */
-                LOG_DIS("l.extbs r%d, r%d\n", rd, ra);
-                tcg_gen_ext8s_tl(cpu_R[rd], cpu_R[ra]);
-                break;
-            case 0x02:    /* l.exthz */
-                LOG_DIS("l.exthz r%d, r%d\n", rd, ra);
-                tcg_gen_ext16u_tl(cpu_R[rd], cpu_R[ra]);
-                break;
-            case 0x03:    /* l.extbz */
-                LOG_DIS("l.extbz r%d, r%d\n", rd, ra);
-                tcg_gen_ext8u_tl(cpu_R[rd], cpu_R[ra]);
-                break;
-
-            default:
-                gen_illegal_exception(dc);
-                break;
-            }
-            break;
-
-        default:
-            gen_illegal_exception(dc);
-            break;
-        }
-        break;
+    case 3:
+        switch (op0) {
+        case 0x6: /* l.mul */
+            LOG_DIS("l.mul r%d, r%d, r%d\n", rd, ra, rb);
+            gen_mul(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]);
+            return;
 
-    case 0x000d:
-        switch (op1) {
-        case 0x00:
-            switch (op2) {
-            case 0x00:    /* l.extws */
-                LOG_DIS("l.extws r%d, r%d\n", rd, ra);
-                tcg_gen_ext32s_tl(cpu_R[rd], cpu_R[ra]);
-                break;
-            case 0x01:    /* l.extwz */
-                LOG_DIS("l.extwz r%d, r%d\n", rd, ra);
-                tcg_gen_ext32u_tl(cpu_R[rd], cpu_R[ra]);
-                break;
+        case 0x9: /* l.div */
+            LOG_DIS("l.div r%d, r%d, r%d\n", rd, ra, rb);
+            gen_div(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]);
+            return;
 
-            default:
-                gen_illegal_exception(dc);
-                break;
-            }
-            break;
+        case 0xa: /* l.divu */
+            LOG_DIS("l.divu r%d, r%d, r%d\n", rd, ra, rb);
+            gen_divu(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]);
+            return;
 
-        default:
-            gen_illegal_exception(dc);
-            break;
+        case 0xb: /* l.mulu */
+            LOG_DIS("l.mulu r%d, r%d, r%d\n", rd, ra, rb);
+            gen_mulu(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]);
+            return;
         }
         break;
-
-    default:
-        gen_illegal_exception(dc);
-        break;
     }
+    gen_illegal_exception(dc);
 }
 
 static void dec_misc(DisasContext *dc, uint32_t insn)
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Qemu-devel] [PATCH 11/22] target/openrisc: Keep SR_F in a separate variable
  2017-02-09  4:51 [Qemu-devel] [PATCH 00/22] target/openrisc updates Richard Henderson
                   ` (8 preceding siblings ...)
  2017-02-09  4:51 ` [Qemu-devel] [PATCH 10/22] target/openrisc: Invert the decoding in dec_calc Richard Henderson
@ 2017-02-09  4:51 ` Richard Henderson
  2017-02-09  4:51 ` [Qemu-devel] [PATCH 12/22] target/openrisc: Keep SR_CY and SR_OV in a separate variables Richard Henderson
                   ` (11 subsequent siblings)
  21 siblings, 0 replies; 30+ messages in thread
From: Richard Henderson @ 2017-02-09  4:51 UTC (permalink / raw)
  To: qemu-devel; +Cc: shorne

This avoids having to keep merging and extracting the flag from SR.

Reviewed-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 target/openrisc/cpu.h              |  15 +++++-
 target/openrisc/gdbstub.c          |   4 +-
 target/openrisc/interrupt.c        |   2 +-
 target/openrisc/interrupt_helper.c |   2 +-
 target/openrisc/machine.c          |  38 +++++++++++++-
 target/openrisc/sys_helper.c       |   5 +-
 target/openrisc/translate.c        | 104 ++++++++++++++-----------------------
 7 files changed, 96 insertions(+), 74 deletions(-)

diff --git a/target/openrisc/cpu.h b/target/openrisc/cpu.h
index ef90e49..9e349f9 100644
--- a/target/openrisc/cpu.h
+++ b/target/openrisc/cpu.h
@@ -286,7 +286,8 @@ typedef struct CPUOpenRISCState {
     target_ulong epcr;        /* Exception PC register */
     target_ulong eear;        /* Exception EA register */
 
-    uint32_t sr;              /* Supervisor register */
+    target_ulong sr_f;        /* the SR_F bit, values 0, 1.  */
+    uint32_t sr;              /* Supervisor register, without SR_F */
     uint32_t vr;              /* Version register */
     uint32_t upr;             /* Unit presence register */
     uint32_t cpucfgr;         /* CPU configure register */
@@ -301,7 +302,6 @@ typedef struct CPUOpenRISCState {
 
     uint32_t flags;           /* cpu_flags, we only use it for exception
                                  in solt so far.  */
-    uint32_t btaken;          /* the SR_F bit */
 
     /* Fields up to this point are cleared by a CPU reset */
     struct {} end_reset_fields;
@@ -412,6 +412,17 @@ static inline int cpu_mmu_index(CPUOpenRISCState *env, bool ifetch)
     return (env->sr & SR_SM) == 0 ? MMU_USER_IDX : MMU_SUPERVISOR_IDX;
 }
 
+static inline uint32_t cpu_get_sr(CPUOpenRISCState *env)
+{
+    return env->sr + env->sr_f * SR_F;
+}
+
+static inline void cpu_set_sr(CPUOpenRISCState *env, uint32_t val)
+{
+    env->sr_f = (val & SR_F) != 0;
+    env->sr = (val & ~SR_F) | SR_FO;
+}
+
 #define CPU_INTERRUPT_TIMER   CPU_INTERRUPT_TGT_INT_0
 
 #endif /* OPENRISC_CPU_H */
diff --git a/target/openrisc/gdbstub.c b/target/openrisc/gdbstub.c
index cb16e76..31ea013 100644
--- a/target/openrisc/gdbstub.c
+++ b/target/openrisc/gdbstub.c
@@ -38,7 +38,7 @@ int openrisc_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n)
             return gdb_get_reg32(mem_buf, env->npc);
 
         case 34:    /* SR */
-            return gdb_get_reg32(mem_buf, env->sr);
+            return gdb_get_reg32(mem_buf, cpu_get_sr(env));
 
         default:
             break;
@@ -73,7 +73,7 @@ int openrisc_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
             break;
 
         case 34: /* SR */
-            env->sr = tmp;
+            cpu_set_sr(env, tmp);
             break;
 
         default:
diff --git a/target/openrisc/interrupt.c b/target/openrisc/interrupt.c
index a981638..042506f 100644
--- a/target/openrisc/interrupt.c
+++ b/target/openrisc/interrupt.c
@@ -54,7 +54,7 @@ void openrisc_cpu_do_interrupt(CPUState *cs)
        we need flush TLB when we enter&exit EXCP.  */
     tlb_flush(cs);
 
-    env->esr = env->sr;
+    env->esr = cpu_get_sr(env);
     env->sr &= ~SR_DME;
     env->sr &= ~SR_IME;
     env->sr |= SR_SM;
diff --git a/target/openrisc/interrupt_helper.c b/target/openrisc/interrupt_helper.c
index a6d4df3..c7fa97a 100644
--- a/target/openrisc/interrupt_helper.c
+++ b/target/openrisc/interrupt_helper.c
@@ -33,7 +33,7 @@ void HELPER(rfe)(CPUOpenRISCState *env)
 #endif
     cpu->env.pc = cpu->env.epcr;
     cpu->env.npc = cpu->env.epcr;
-    cpu->env.sr = cpu->env.esr;
+    cpu_set_sr(&cpu->env, cpu->env.esr);
     cpu->env.lock_addr = -1;
 
 #ifndef CONFIG_USER_ONLY
diff --git a/target/openrisc/machine.c b/target/openrisc/machine.c
index d0b47ef..b723138 100644
--- a/target/openrisc/machine.c
+++ b/target/openrisc/machine.c
@@ -24,6 +24,27 @@
 #include "hw/boards.h"
 #include "migration/cpu.h"
 
+static int get_sr(QEMUFile *f, void *opaque, size_t size, VMStateField *field)
+{
+    CPUOpenRISCState *env = opaque;
+    cpu_set_sr(env, qemu_get_be32(f));
+    return 0;
+}
+
+static int put_sr(QEMUFile *f, void *opaque, size_t size,
+                  VMStateField *field, QJSON *vmdesc)
+{
+    CPUOpenRISCState *env = opaque;
+    qemu_put_be32(f, cpu_get_sr(env));
+    return 0;
+}
+
+static const VMStateInfo vmstate_sr = {
+    .name = "sr",
+    .get = get_sr,
+    .put = put_sr,
+};
+
 static const VMStateDescription vmstate_env = {
     .name = "env",
     .version_id = 2,
@@ -38,7 +59,22 @@ static const VMStateDescription vmstate_env = {
         VMSTATE_UINTTL(lock_value, CPUOpenRISCState),
         VMSTATE_UINTTL(epcr, CPUOpenRISCState),
         VMSTATE_UINTTL(eear, CPUOpenRISCState),
-        VMSTATE_UINT32(sr, CPUOpenRISCState),
+
+        /* Save the architecture value of the SR, not the internally
+           expanded version.  Since this architecture value does not
+           exist in memory to be stored, this requires a but of hoop
+           jumping.  We want OFFSET=0 so that we effectively pass ENV
+           to the helper functions, and we need to fill in the name by
+           hand since there's no field of that name.  */
+        {
+            .name = "sr",
+            .version_id = 0,
+            .size = sizeof(uint32_t),
+            .info = &vmstate_sr,
+            .flags = VMS_SINGLE,
+            .offset = 0
+        },
+
         VMSTATE_UINT32(vr, CPUOpenRISCState),
         VMSTATE_UINT32(upr, CPUOpenRISCState),
         VMSTATE_UINT32(cpucfgr, CPUOpenRISCState),
diff --git a/target/openrisc/sys_helper.c b/target/openrisc/sys_helper.c
index daea902..4a59728 100644
--- a/target/openrisc/sys_helper.c
+++ b/target/openrisc/sys_helper.c
@@ -49,8 +49,7 @@ void HELPER(mtspr)(CPUOpenRISCState *env,
             (rb & (SR_IME | SR_DME | SR_SM))) {
             tlb_flush(cs);
         }
-        env->sr = rb;
-        env->sr |= SR_FO;      /* FO is const equal to 1 */
+        cpu_set_sr(env, rb);
         if (env->sr & SR_DME) {
             env->tlb->cpu_openrisc_map_address_data =
                 &cpu_openrisc_get_phys_data;
@@ -200,7 +199,7 @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env,
         return env->npc;
 
     case TO_SPR(0, 17): /* SR */
-        return env->sr;
+        return cpu_get_sr(env);
 
     case TO_SPR(0, 18): /* PPC */
         return env->ppc;
diff --git a/target/openrisc/translate.c b/target/openrisc/translate.c
index 1f3f22c..405a1a0 100644
--- a/target/openrisc/translate.c
+++ b/target/openrisc/translate.c
@@ -54,7 +54,7 @@ static TCGv cpu_pc;
 static TCGv jmp_pc;            /* l.jr/l.jalr temp pc */
 static TCGv cpu_npc;
 static TCGv cpu_ppc;
-static TCGv_i32 env_btaken;    /* bf/bnf , F flag taken */
+static TCGv cpu_sr_f;           /* bf/bnf, F flag taken */
 static TCGv cpu_lock_addr;
 static TCGv cpu_lock_value;
 static TCGv_i32 fpcsr;
@@ -88,9 +88,8 @@ void openrisc_translate_init(void)
                                  offsetof(CPUOpenRISCState, ppc), "ppc");
     jmp_pc = tcg_global_mem_new(cpu_env,
                                 offsetof(CPUOpenRISCState, jmp_pc), "jmp_pc");
-    env_btaken = tcg_global_mem_new_i32(cpu_env,
-                                        offsetof(CPUOpenRISCState, btaken),
-                                        "btaken");
+    cpu_sr_f = tcg_global_mem_new(cpu_env,
+                                  offsetof(CPUOpenRISCState, sr_f), "sr_f");
     cpu_lock_addr = tcg_global_mem_new(cpu_env,
                                        offsetof(CPUOpenRISCState, lock_addr),
                                        "lock_addr");
@@ -119,16 +118,6 @@ void openrisc_translate_init(void)
     }
 }
 
-/* Writeback SR_F translation space to execution space.  */
-static inline void wb_SR_F(void)
-{
-    TCGLabel *label = gen_new_label();
-    tcg_gen_andi_tl(cpu_sr, cpu_sr, ~SR_F);
-    tcg_gen_brcondi_tl(TCG_COND_EQ, env_btaken, 0, label);
-    tcg_gen_ori_tl(cpu_sr, cpu_sr, SR_F);
-    gen_set_label(label);
-}
-
 static inline void gen_sync_flags(DisasContext *dc)
 {
     /* Sync the tb dependent flag between translate and runtime.  */
@@ -220,14 +209,11 @@ static void gen_jump(DisasContext *dc, int32_t n26, uint32_t reg, uint32_t op0)
     case 0x04:     /* l.bf  */
         {
             TCGLabel *lab = gen_new_label();
-            TCGv sr_f = tcg_temp_new();
             tcg_gen_movi_tl(jmp_pc, dc->pc+8);
-            tcg_gen_andi_tl(sr_f, cpu_sr, SR_F);
-            tcg_gen_brcondi_i32(op0 == 0x03 ? TCG_COND_EQ : TCG_COND_NE,
-                                sr_f, SR_F, lab);
+            tcg_gen_brcondi_tl(op0 == 0x03 ? TCG_COND_NE : TCG_COND_EQ,
+                               cpu_sr_f, 0, lab);
             tcg_gen_movi_tl(jmp_pc, tmp_pc);
             gen_set_label(lab);
-            tcg_temp_free(sr_f);
         }
         break;
     case 0x11:     /* l.jr */
@@ -441,17 +427,16 @@ static void gen_swa(DisasContext *dc, TCGv rb, TCGv ra, int32_t ofs)
     val = tcg_temp_new();
     tcg_gen_atomic_cmpxchg_tl(val, cpu_lock_addr, cpu_lock_value,
                               rb, dc->mem_idx, MO_TEUL);
-    tcg_gen_setcond_tl(TCG_COND_EQ, env_btaken, val, cpu_lock_value);
+    tcg_gen_setcond_tl(TCG_COND_EQ, cpu_sr_f, val, cpu_lock_value);
     tcg_temp_free(val);
 
     tcg_gen_br(lab_done);
 
     gen_set_label(lab_fail);
-    tcg_gen_movi_tl(env_btaken, 0);
+    tcg_gen_movi_tl(cpu_sr_f, 0);
 
     gen_set_label(lab_done);
     tcg_gen_movi_tl(cpu_lock_addr, -1);
-    wb_SR_F();
 }
 
 static void dec_calc(DisasContext *dc, uint32_t insn)
@@ -558,14 +543,11 @@ static void dec_calc(DisasContext *dc, uint32_t insn)
             {
                 TCGLabel *lab = gen_new_label();
                 TCGv res = tcg_temp_local_new();
-                TCGv sr_f = tcg_temp_new();
-                tcg_gen_andi_tl(sr_f, cpu_sr, SR_F);
                 tcg_gen_mov_tl(res, cpu_R[rb]);
-                tcg_gen_brcondi_tl(TCG_COND_NE, sr_f, SR_F, lab);
+                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_sr_f, 0, lab);
                 tcg_gen_mov_tl(res, cpu_R[ra]);
                 gen_set_label(lab);
                 tcg_gen_mov_tl(cpu_R[rd], res);
-                tcg_temp_free(sr_f);
                 tcg_temp_free(res);
             }
             return;
@@ -1046,7 +1028,6 @@ static void dec_comp(DisasContext *dc, uint32_t insn)
     ra = extract32(insn, 16, 5);
     rb = extract32(insn, 11, 5);
 
-    tcg_gen_movi_i32(env_btaken, 0x0);
     /* unsigned integers  */
     tcg_gen_ext32u_tl(cpu_R[ra], cpu_R[ra]);
     tcg_gen_ext32u_tl(cpu_R[rb], cpu_R[rb]);
@@ -1054,59 +1035,58 @@ static void dec_comp(DisasContext *dc, uint32_t insn)
     switch (op0) {
     case 0x0:    /* l.sfeq */
         LOG_DIS("l.sfeq  r%d, r%d\n", ra, rb);
-        tcg_gen_setcond_tl(TCG_COND_EQ, env_btaken, cpu_R[ra], cpu_R[rb]);
+        tcg_gen_setcond_tl(TCG_COND_EQ, cpu_sr_f, cpu_R[ra], cpu_R[rb]);
         break;
 
     case 0x1:    /* l.sfne */
         LOG_DIS("l.sfne  r%d, r%d\n", ra, rb);
-        tcg_gen_setcond_tl(TCG_COND_NE, env_btaken, cpu_R[ra], cpu_R[rb]);
+        tcg_gen_setcond_tl(TCG_COND_NE, cpu_sr_f, cpu_R[ra], cpu_R[rb]);
         break;
 
     case 0x2:    /* l.sfgtu */
         LOG_DIS("l.sfgtu  r%d, r%d\n", ra, rb);
-        tcg_gen_setcond_tl(TCG_COND_GTU, env_btaken, cpu_R[ra], cpu_R[rb]);
+        tcg_gen_setcond_tl(TCG_COND_GTU, cpu_sr_f, cpu_R[ra], cpu_R[rb]);
         break;
 
     case 0x3:    /* l.sfgeu */
         LOG_DIS("l.sfgeu  r%d, r%d\n", ra, rb);
-        tcg_gen_setcond_tl(TCG_COND_GEU, env_btaken, cpu_R[ra], cpu_R[rb]);
+        tcg_gen_setcond_tl(TCG_COND_GEU, cpu_sr_f, cpu_R[ra], cpu_R[rb]);
         break;
 
     case 0x4:    /* l.sfltu */
         LOG_DIS("l.sfltu  r%d, r%d\n", ra, rb);
-        tcg_gen_setcond_tl(TCG_COND_LTU, env_btaken, cpu_R[ra], cpu_R[rb]);
+        tcg_gen_setcond_tl(TCG_COND_LTU, cpu_sr_f, cpu_R[ra], cpu_R[rb]);
         break;
 
     case 0x5:    /* l.sfleu */
         LOG_DIS("l.sfleu  r%d, r%d\n", ra, rb);
-        tcg_gen_setcond_tl(TCG_COND_LEU, env_btaken, cpu_R[ra], cpu_R[rb]);
+        tcg_gen_setcond_tl(TCG_COND_LEU, cpu_sr_f, cpu_R[ra], cpu_R[rb]);
         break;
 
     case 0xa:    /* l.sfgts */
         LOG_DIS("l.sfgts  r%d, r%d\n", ra, rb);
-        tcg_gen_setcond_tl(TCG_COND_GT, env_btaken, cpu_R[ra], cpu_R[rb]);
+        tcg_gen_setcond_tl(TCG_COND_GT, cpu_sr_f, cpu_R[ra], cpu_R[rb]);
         break;
 
     case 0xb:    /* l.sfges */
         LOG_DIS("l.sfges  r%d, r%d\n", ra, rb);
-        tcg_gen_setcond_tl(TCG_COND_GE, env_btaken, cpu_R[ra], cpu_R[rb]);
+        tcg_gen_setcond_tl(TCG_COND_GE, cpu_sr_f, cpu_R[ra], cpu_R[rb]);
         break;
 
     case 0xc:    /* l.sflts */
         LOG_DIS("l.sflts  r%d, r%d\n", ra, rb);
-        tcg_gen_setcond_tl(TCG_COND_LT, env_btaken, cpu_R[ra], cpu_R[rb]);
+        tcg_gen_setcond_tl(TCG_COND_LT, cpu_sr_f, cpu_R[ra], cpu_R[rb]);
         break;
 
     case 0xd:    /* l.sfles */
         LOG_DIS("l.sfles  r%d, r%d\n", ra, rb);
-        tcg_gen_setcond_tl(TCG_COND_LE, env_btaken, cpu_R[ra], cpu_R[rb]);
+        tcg_gen_setcond_tl(TCG_COND_LE, cpu_sr_f, cpu_R[ra], cpu_R[rb]);
         break;
 
     default:
         gen_illegal_exception(dc);
         break;
     }
-    wb_SR_F();
 }
 
 static void dec_compi(DisasContext *dc, uint32_t insn)
@@ -1118,64 +1098,61 @@ static void dec_compi(DisasContext *dc, uint32_t insn)
     ra = extract32(insn, 16, 5);
     I16 = sextract32(insn, 0, 16);
 
-    tcg_gen_movi_i32(env_btaken, 0x0);
-
     switch (op0) {
     case 0x0:    /* l.sfeqi */
         LOG_DIS("l.sfeqi  r%d, %d\n", ra, I16);
-        tcg_gen_setcondi_tl(TCG_COND_EQ, env_btaken, cpu_R[ra], I16);
+        tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_sr_f, cpu_R[ra], I16);
         break;
 
     case 0x1:    /* l.sfnei */
         LOG_DIS("l.sfnei  r%d, %d\n", ra, I16);
-        tcg_gen_setcondi_tl(TCG_COND_NE, env_btaken, cpu_R[ra], I16);
+        tcg_gen_setcondi_tl(TCG_COND_NE, cpu_sr_f, cpu_R[ra], I16);
         break;
 
     case 0x2:    /* l.sfgtui */
         LOG_DIS("l.sfgtui  r%d, %d\n", ra, I16);
-        tcg_gen_setcondi_tl(TCG_COND_GTU, env_btaken, cpu_R[ra], I16);
+        tcg_gen_setcondi_tl(TCG_COND_GTU, cpu_sr_f, cpu_R[ra], I16);
         break;
 
     case 0x3:    /* l.sfgeui */
         LOG_DIS("l.sfgeui  r%d, %d\n", ra, I16);
-        tcg_gen_setcondi_tl(TCG_COND_GEU, env_btaken, cpu_R[ra], I16);
+        tcg_gen_setcondi_tl(TCG_COND_GEU, cpu_sr_f, cpu_R[ra], I16);
         break;
 
     case 0x4:    /* l.sfltui */
         LOG_DIS("l.sfltui  r%d, %d\n", ra, I16);
-        tcg_gen_setcondi_tl(TCG_COND_LTU, env_btaken, cpu_R[ra], I16);
+        tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_sr_f, cpu_R[ra], I16);
         break;
 
     case 0x5:    /* l.sfleui */
         LOG_DIS("l.sfleui  r%d, %d\n", ra, I16);
-        tcg_gen_setcondi_tl(TCG_COND_LEU, env_btaken, cpu_R[ra], I16);
+        tcg_gen_setcondi_tl(TCG_COND_LEU, cpu_sr_f, cpu_R[ra], I16);
         break;
 
     case 0xa:    /* l.sfgtsi */
         LOG_DIS("l.sfgtsi  r%d, %d\n", ra, I16);
-        tcg_gen_setcondi_tl(TCG_COND_GT, env_btaken, cpu_R[ra], I16);
+        tcg_gen_setcondi_tl(TCG_COND_GT, cpu_sr_f, cpu_R[ra], I16);
         break;
 
     case 0xb:    /* l.sfgesi */
         LOG_DIS("l.sfgesi  r%d, %d\n", ra, I16);
-        tcg_gen_setcondi_tl(TCG_COND_GE, env_btaken, cpu_R[ra], I16);
+        tcg_gen_setcondi_tl(TCG_COND_GE, cpu_sr_f, cpu_R[ra], I16);
         break;
 
     case 0xc:    /* l.sfltsi */
         LOG_DIS("l.sfltsi  r%d, %d\n", ra, I16);
-        tcg_gen_setcondi_tl(TCG_COND_LT, env_btaken, cpu_R[ra], I16);
+        tcg_gen_setcondi_tl(TCG_COND_LT, cpu_sr_f, cpu_R[ra], I16);
         break;
 
     case 0xd:    /* l.sflesi */
         LOG_DIS("l.sflesi  r%d, %d\n", ra, I16);
-        tcg_gen_setcondi_tl(TCG_COND_LE, env_btaken, cpu_R[ra], I16);
+        tcg_gen_setcondi_tl(TCG_COND_LE, cpu_sr_f, cpu_R[ra], I16);
         break;
 
     default:
         gen_illegal_exception(dc);
         break;
     }
-    wb_SR_F();
 }
 
 static void dec_sys(DisasContext *dc, uint32_t insn)
@@ -1308,32 +1285,32 @@ static void dec_float(DisasContext *dc, uint32_t insn)
 
     case 0x08:    /* lf.sfeq.s */
         LOG_DIS("lf.sfeq.s r%d, r%d\n", ra, rb);
-        gen_helper_float_eq_s(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]);
+        gen_helper_float_eq_s(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
         break;
 
     case 0x09:    /* lf.sfne.s */
         LOG_DIS("lf.sfne.s r%d, r%d\n", ra, rb);
-        gen_helper_float_ne_s(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]);
+        gen_helper_float_ne_s(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
         break;
 
     case 0x0a:    /* lf.sfgt.s */
         LOG_DIS("lf.sfgt.s r%d, r%d\n", ra, rb);
-        gen_helper_float_gt_s(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]);
+        gen_helper_float_gt_s(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
         break;
 
     case 0x0b:    /* lf.sfge.s */
         LOG_DIS("lf.sfge.s r%d, r%d\n", ra, rb);
-        gen_helper_float_ge_s(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]);
+        gen_helper_float_ge_s(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
         break;
 
     case 0x0c:    /* lf.sflt.s */
         LOG_DIS("lf.sflt.s r%d, r%d\n", ra, rb);
-        gen_helper_float_lt_s(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]);
+        gen_helper_float_lt_s(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
         break;
 
     case 0x0d:    /* lf.sfle.s */
         LOG_DIS("lf.sfle.s r%d, r%d\n", ra, rb);
-        gen_helper_float_le_s(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]);
+        gen_helper_float_le_s(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
         break;
 
 /* not used yet, open it when we need or64.  */
@@ -1394,37 +1371,37 @@ static void dec_float(DisasContext *dc, uint32_t insn)
     case 0x18:     lf.sfeq.d
         LOG_DIS("lf.sfeq.d r%d, r%d\n", ra, rb);
         check_of64s(dc);
-        gen_helper_float_eq_d(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]);
+        gen_helper_float_eq_d(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
         break;
 
     case 0x1a:     lf.sfgt.d
         LOG_DIS("lf.sfgt.d r%d, r%d\n", ra, rb);
         check_of64s(dc);
-        gen_helper_float_gt_d(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]);
+        gen_helper_float_gt_d(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
         break;
 
     case 0x1b:     lf.sfge.d
         LOG_DIS("lf.sfge.d r%d, r%d\n", ra, rb);
         check_of64s(dc);
-        gen_helper_float_ge_d(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]);
+        gen_helper_float_ge_d(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
         break;
 
     case 0x19:     lf.sfne.d
         LOG_DIS("lf.sfne.d r%d, r%d\n", ra, rb);
         check_of64s(dc);
-        gen_helper_float_ne_d(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]);
+        gen_helper_float_ne_d(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
         break;
 
     case 0x1c:     lf.sflt.d
         LOG_DIS("lf.sflt.d r%d, r%d\n", ra, rb);
         check_of64s(dc);
-        gen_helper_float_lt_d(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]);
+        gen_helper_float_lt_d(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
         break;
 
     case 0x1d:     lf.sfle.d
         LOG_DIS("lf.sfle.d r%d, r%d\n", ra, rb);
         check_of64s(dc);
-        gen_helper_float_le_d(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]);
+        gen_helper_float_le_d(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
         break;
 #endif*/
 
@@ -1432,7 +1409,6 @@ static void dec_float(DisasContext *dc, uint32_t insn)
         gen_illegal_exception(dc);
         break;
     }
-    wb_SR_F();
 }
 
 static void disas_openrisc_insn(DisasContext *dc, OpenRISCCPU *cpu)
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Qemu-devel] [PATCH 12/22] target/openrisc: Keep SR_CY and SR_OV in a separate variables
  2017-02-09  4:51 [Qemu-devel] [PATCH 00/22] target/openrisc updates Richard Henderson
                   ` (9 preceding siblings ...)
  2017-02-09  4:51 ` [Qemu-devel] [PATCH 11/22] target/openrisc: Keep SR_F in a separate variable Richard Henderson
@ 2017-02-09  4:51 ` Richard Henderson
  2017-02-09  4:51 ` [Qemu-devel] [PATCH 13/22] target/openrisc: Use movcond where appropriate Richard Henderson
                   ` (10 subsequent siblings)
  21 siblings, 0 replies; 30+ messages in thread
From: Richard Henderson @ 2017-02-09  4:51 UTC (permalink / raw)
  To: qemu-devel; +Cc: shorne

This significantly streamlines carry and overflow production.

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 target/openrisc/cpu.h              |  13 +++-
 target/openrisc/exception_helper.c |  31 ++++++++--
 target/openrisc/helper.h           |   4 +-
 target/openrisc/translate.c        | 119 +++++++++++++------------------------
 4 files changed, 78 insertions(+), 89 deletions(-)

diff --git a/target/openrisc/cpu.h b/target/openrisc/cpu.h
index 9e349f9..82b87b3 100644
--- a/target/openrisc/cpu.h
+++ b/target/openrisc/cpu.h
@@ -287,7 +287,9 @@ typedef struct CPUOpenRISCState {
     target_ulong eear;        /* Exception EA register */
 
     target_ulong sr_f;        /* the SR_F bit, values 0, 1.  */
-    uint32_t sr;              /* Supervisor register, without SR_F */
+    target_ulong sr_cy;       /* the SR_CY bit, values 0, 1.  */
+    target_long  sr_ov;       /* the SR_OV bit (in the sign bit only) */
+    uint32_t sr;              /* Supervisor register, without SR_{F,CY,OV} */
     uint32_t vr;              /* Version register */
     uint32_t upr;             /* Unit presence register */
     uint32_t cpucfgr;         /* CPU configure register */
@@ -414,13 +416,18 @@ static inline int cpu_mmu_index(CPUOpenRISCState *env, bool ifetch)
 
 static inline uint32_t cpu_get_sr(CPUOpenRISCState *env)
 {
-    return env->sr + env->sr_f * SR_F;
+    return (env->sr
+            + env->sr_f * SR_F
+            + env->sr_cy * SR_CY
+            + (env->sr_ov < 0) * SR_OV);
 }
 
 static inline void cpu_set_sr(CPUOpenRISCState *env, uint32_t val)
 {
     env->sr_f = (val & SR_F) != 0;
-    env->sr = (val & ~SR_F) | SR_FO;
+    env->sr_cy = (val & SR_CY) != 0;
+    env->sr_ov = (val & SR_OV ? -1 : 0);
+    env->sr = (val & ~(SR_F | SR_CY | SR_OV)) | SR_FO;
 }
 
 #define CPU_INTERRUPT_TIMER   CPU_INTERRUPT_TGT_INT_0
diff --git a/target/openrisc/exception_helper.c b/target/openrisc/exception_helper.c
index 5147da6..1536053 100644
--- a/target/openrisc/exception_helper.c
+++ b/target/openrisc/exception_helper.c
@@ -30,13 +30,32 @@ void HELPER(exception)(CPUOpenRISCState *env, uint32_t excp)
     raise_exception(cpu, excp);
 }
 
-void HELPER(ove)(CPUOpenRISCState *env, target_ulong test)
+static void QEMU_NORETURN do_range(CPUOpenRISCState *env, uintptr_t pc)
 {
-    if (unlikely(test)) {
-        OpenRISCCPU *cpu = openrisc_env_get_cpu(env);
-        CPUState *cs = CPU(cpu);
+    OpenRISCCPU *cpu = openrisc_env_get_cpu(env);
+    CPUState *cs = CPU(cpu);
+
+    cs->exception_index = EXCP_RANGE;
+    cpu_loop_exit_restore(cs, pc);
+}
+
+void HELPER(ove_cy)(CPUOpenRISCState *env)
+{
+    if (env->sr_cy) {
+        do_range(env, GETPC());
+    }
+}
+
+void HELPER(ove_ov)(CPUOpenRISCState *env)
+{
+    if (env->sr_ov < 0) {
+        do_range(env, GETPC());
+    }
+}
 
-        cs->exception_index = EXCP_RANGE;
-        cpu_loop_exit_restore(cs, GETPC());
+void HELPER(ove_cyov)(CPUOpenRISCState *env)
+{
+    if (env->sr_cy || env->sr_ov < 0) {
+        do_range(env, GETPC());
     }
 }
diff --git a/target/openrisc/helper.h b/target/openrisc/helper.h
index c2c8098..f4d97a2 100644
--- a/target/openrisc/helper.h
+++ b/target/openrisc/helper.h
@@ -19,7 +19,9 @@
 
 /* exception */
 DEF_HELPER_FLAGS_2(exception, 0, void, env, i32)
-DEF_HELPER_FLAGS_2(ove, TCG_CALL_NO_WG, void, env, tl)
+DEF_HELPER_FLAGS_1(ove_cy, TCG_CALL_NO_WG, void, env)
+DEF_HELPER_FLAGS_1(ove_ov, TCG_CALL_NO_WG, void, env)
+DEF_HELPER_FLAGS_1(ove_cyov, TCG_CALL_NO_WG, void, env)
 
 /* float */
 DEF_HELPER_FLAGS_2(itofd, 0, i64, env, i64)
diff --git a/target/openrisc/translate.c b/target/openrisc/translate.c
index 405a1a0..6c745d3 100644
--- a/target/openrisc/translate.c
+++ b/target/openrisc/translate.c
@@ -55,6 +55,8 @@ static TCGv jmp_pc;            /* l.jr/l.jalr temp pc */
 static TCGv cpu_npc;
 static TCGv cpu_ppc;
 static TCGv cpu_sr_f;           /* bf/bnf, F flag taken */
+static TCGv cpu_sr_cy;          /* carry (unsigned overflow) */
+static TCGv cpu_sr_ov;          /* signed overflow */
 static TCGv cpu_lock_addr;
 static TCGv cpu_lock_value;
 static TCGv_i32 fpcsr;
@@ -90,6 +92,10 @@ void openrisc_translate_init(void)
                                 offsetof(CPUOpenRISCState, jmp_pc), "jmp_pc");
     cpu_sr_f = tcg_global_mem_new(cpu_env,
                                   offsetof(CPUOpenRISCState, sr_f), "sr_f");
+    cpu_sr_cy = tcg_global_mem_new(cpu_env,
+                                   offsetof(CPUOpenRISCState, sr_cy), "sr_cy");
+    cpu_sr_ov = tcg_global_mem_new(cpu_env,
+                                   offsetof(CPUOpenRISCState, sr_ov), "sr_ov");
     cpu_lock_addr = tcg_global_mem_new(cpu_env,
                                        offsetof(CPUOpenRISCState, lock_addr),
                                        "lock_addr");
@@ -233,27 +239,24 @@ static void gen_jump(DisasContext *dc, int32_t n26, uint32_t reg, uint32_t op0)
     gen_sync_flags(dc);
 }
 
-static void gen_ove_cy(DisasContext *dc, TCGv cy)
+static void gen_ove_cy(DisasContext *dc)
 {
     if (dc->tb_flags & SR_OVE) {
-        gen_helper_ove(cpu_env, cy);
+        gen_helper_ove_cy(cpu_env);
     }
 }
 
-static void gen_ove_ov(DisasContext *dc, TCGv ov)
+static void gen_ove_ov(DisasContext *dc)
 {
     if (dc->tb_flags & SR_OVE) {
-        gen_helper_ove(cpu_env, ov);
+        gen_helper_ove_ov(cpu_env);
     }
 }
 
-static void gen_ove_cyov(DisasContext *dc, TCGv cy, TCGv ov)
+static void gen_ove_cyov(DisasContext *dc)
 {
     if (dc->tb_flags & SR_OVE) {
-        TCGv t0 = tcg_temp_new();
-        tcg_gen_or_tl(t0, cy, ov);
-        gen_helper_ove(cpu_env, t0);
-        tcg_temp_free(t0);
+        gen_helper_ove_cyov(cpu_env);
     }
 }
 
@@ -261,143 +264,101 @@ static void gen_add(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb)
 {
     TCGv t0 = tcg_const_tl(0);
     TCGv res = tcg_temp_new();
-    TCGv sr_cy = tcg_temp_new();
-    TCGv sr_ov = tcg_temp_new();
 
-    tcg_gen_add2_tl(res, sr_cy, srca, t0, srcb, t0);
-    tcg_gen_xor_tl(sr_ov, srca, srcb);
+    tcg_gen_add2_tl(res, cpu_sr_cy, srca, t0, srcb, t0);
+    tcg_gen_xor_tl(cpu_sr_ov, srca, srcb);
     tcg_gen_xor_tl(t0, res, srcb);
-    tcg_gen_andc_tl(sr_ov, t0, sr_ov);
+    tcg_gen_andc_tl(cpu_sr_ov, t0, cpu_sr_ov);
     tcg_temp_free(t0);
 
     tcg_gen_mov_tl(dest, res);
     tcg_temp_free(res);
 
-    tcg_gen_shri_tl(sr_ov, sr_ov, TARGET_LONG_BITS - 1);
-    tcg_gen_deposit_tl(cpu_sr, cpu_sr, sr_cy, ctz32(SR_CY), 1);
-    tcg_gen_deposit_tl(cpu_sr, cpu_sr, sr_ov, ctz32(SR_OV), 1);
-
-    gen_ove_cyov(dc, sr_ov, sr_cy);
-    tcg_temp_free(sr_ov);
-    tcg_temp_free(sr_cy);
+    gen_ove_cyov(dc);
 }
 
 static void gen_addc(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb)
 {
     TCGv t0 = tcg_const_tl(0);
     TCGv res = tcg_temp_new();
-    TCGv sr_cy = tcg_temp_new();
-    TCGv sr_ov = tcg_temp_new();
-
-    tcg_gen_shri_tl(sr_cy, cpu_sr, ctz32(SR_CY));
-    tcg_gen_andi_tl(sr_cy, sr_cy, 1);
 
-    tcg_gen_add2_tl(res, sr_cy, srca, t0, sr_cy, t0);
-    tcg_gen_add2_tl(res, sr_cy, res, sr_cy, srcb, t0);
-    tcg_gen_xor_tl(sr_ov, srca, srcb);
+    tcg_gen_add2_tl(res, cpu_sr_cy, srca, t0, cpu_sr_cy, t0);
+    tcg_gen_add2_tl(res, cpu_sr_cy, res, cpu_sr_cy, srcb, t0);
+    tcg_gen_xor_tl(cpu_sr_ov, srca, srcb);
     tcg_gen_xor_tl(t0, res, srcb);
-    tcg_gen_andc_tl(sr_ov, t0, sr_ov);
+    tcg_gen_andc_tl(cpu_sr_ov, t0, cpu_sr_ov);
     tcg_temp_free(t0);
 
     tcg_gen_mov_tl(dest, res);
     tcg_temp_free(res);
 
-    tcg_gen_shri_tl(sr_ov, sr_ov, TARGET_LONG_BITS - 1);
-    tcg_gen_deposit_tl(cpu_sr, cpu_sr, sr_cy, ctz32(SR_CY), 1);
-    tcg_gen_deposit_tl(cpu_sr, cpu_sr, sr_ov, ctz32(SR_OV), 1);
-
-    gen_ove_cyov(dc, sr_ov, sr_cy);
-    tcg_temp_free(sr_ov);
-    tcg_temp_free(sr_cy);
+    gen_ove_cyov(dc);
 }
 
 static void gen_sub(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb)
 {
     TCGv res = tcg_temp_new();
-    TCGv sr_cy = tcg_temp_new();
-    TCGv sr_ov = tcg_temp_new();
 
     tcg_gen_sub_tl(res, srca, srcb);
-    tcg_gen_xor_tl(sr_cy, srca, srcb);
-    tcg_gen_xor_tl(sr_ov, res, srcb);
-    tcg_gen_and_tl(sr_ov, sr_ov, sr_cy);
-    tcg_gen_setcond_tl(TCG_COND_LTU, sr_cy, srca, srcb);
+    tcg_gen_xor_tl(cpu_sr_cy, srca, srcb);
+    tcg_gen_xor_tl(cpu_sr_ov, res, srcb);
+    tcg_gen_and_tl(cpu_sr_ov, cpu_sr_ov, cpu_sr_cy);
+    tcg_gen_setcond_tl(TCG_COND_LTU, cpu_sr_cy, srca, srcb);
 
     tcg_gen_mov_tl(dest, res);
     tcg_temp_free(res);
 
-    tcg_gen_shri_tl(sr_ov, sr_ov, TARGET_LONG_BITS - 1);
-    tcg_gen_deposit_tl(cpu_sr, cpu_sr, sr_cy, ctz32(SR_CY), 1);
-    tcg_gen_deposit_tl(cpu_sr, cpu_sr, sr_ov, ctz32(SR_OV), 1);
-
-    gen_ove_cyov(dc, sr_ov, sr_cy);
-    tcg_temp_free(sr_ov);
-    tcg_temp_free(sr_cy);
+    gen_ove_cyov(dc);
 }
 
 static void gen_mul(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb)
 {
-    TCGv sr_ov = tcg_temp_new();
     TCGv t0 = tcg_temp_new();
 
-    tcg_gen_muls2_tl(dest, sr_ov, srca, srcb);
+    tcg_gen_muls2_tl(dest, cpu_sr_ov, srca, srcb);
     tcg_gen_sari_tl(t0, dest, TARGET_LONG_BITS - 1);
-    tcg_gen_setcond_tl(TCG_COND_NE, sr_ov, sr_ov, t0);
+    tcg_gen_setcond_tl(TCG_COND_NE, cpu_sr_ov, cpu_sr_ov, t0);
     tcg_temp_free(t0);
 
-    tcg_gen_deposit_tl(cpu_sr, cpu_sr, sr_ov, ctz32(SR_OV), 1);
-
-    gen_ove_ov(dc, sr_ov);
-    tcg_temp_free(sr_ov);
+    tcg_gen_neg_tl(cpu_sr_ov, cpu_sr_ov);
+    gen_ove_ov(dc);
 }
 
 static void gen_mulu(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb)
 {
-    TCGv sr_cy = tcg_temp_new();
-
-    tcg_gen_muls2_tl(dest, sr_cy, srca, srcb);
-    tcg_gen_setcondi_tl(TCG_COND_NE, sr_cy, sr_cy, 0);
-
-    tcg_gen_deposit_tl(cpu_sr, cpu_sr, sr_cy, ctz32(SR_CY), 1);
+    tcg_gen_muls2_tl(dest, cpu_sr_cy, srca, srcb);
+    tcg_gen_setcondi_tl(TCG_COND_NE, cpu_sr_cy, cpu_sr_cy, 0);
 
-    gen_ove_cy(dc, sr_cy);
-    tcg_temp_free(sr_cy);
+    gen_ove_cy(dc);
 }
 
 static void gen_div(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb)
 {
-    TCGv sr_ov = tcg_temp_new();
     TCGv t0 = tcg_temp_new();
 
-    tcg_gen_setcondi_tl(TCG_COND_EQ, sr_ov, srcb, 0);
+    tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_sr_ov, srcb, 0);
     /* The result of divide-by-zero is undefined.
        Supress the host-side exception by dividing by 1.  */
-    tcg_gen_or_tl(t0, srcb, sr_ov);
+    tcg_gen_or_tl(t0, srcb, cpu_sr_ov);
     tcg_gen_div_tl(dest, srca, t0);
     tcg_temp_free(t0);
 
-    tcg_gen_deposit_tl(cpu_sr, cpu_sr, sr_ov, ctz32(SR_OV), 1);
-
-    gen_ove_ov(dc, sr_ov);
-    tcg_temp_free(sr_ov);
+    tcg_gen_neg_tl(cpu_sr_ov, cpu_sr_ov);
+    gen_ove_ov(dc);
 }
 
 static void gen_divu(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb)
 {
-    TCGv sr_cy = tcg_temp_new();
     TCGv t0 = tcg_temp_new();
 
-    tcg_gen_setcondi_tl(TCG_COND_EQ, sr_cy, srcb, 0);
+    tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_sr_cy, srcb, 0);
     /* The result of divide-by-zero is undefined.
        Supress the host-side exception by dividing by 1.  */
-    tcg_gen_or_tl(t0, srcb, sr_cy);
+    tcg_gen_or_tl(t0, srcb, cpu_sr_cy);
     tcg_gen_divu_tl(dest, srca, t0);
     tcg_temp_free(t0);
 
-    tcg_gen_deposit_tl(cpu_sr, cpu_sr, sr_cy, ctz32(SR_CY), 1);
-
-    gen_ove_cy(dc, sr_cy);
-    tcg_temp_free(sr_cy);
+    gen_ove_cy(dc);
 }
 
 static void gen_lwa(DisasContext *dc, TCGv rd, TCGv ra, int32_t ofs)
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Qemu-devel] [PATCH 13/22] target/openrisc: Use movcond where appropriate
  2017-02-09  4:51 [Qemu-devel] [PATCH 00/22] target/openrisc updates Richard Henderson
                   ` (10 preceding siblings ...)
  2017-02-09  4:51 ` [Qemu-devel] [PATCH 12/22] target/openrisc: Keep SR_CY and SR_OV in a separate variables Richard Henderson
@ 2017-02-09  4:51 ` Richard Henderson
  2017-02-09  4:51 ` [Qemu-devel] [PATCH 14/22] target/openrisc: Set flags on helpers Richard Henderson
                   ` (9 subsequent siblings)
  21 siblings, 0 replies; 30+ messages in thread
From: Richard Henderson @ 2017-02-09  4:51 UTC (permalink / raw)
  To: qemu-devel; +Cc: shorne

Reviewed-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 target/openrisc/translate.c | 28 ++++++++++++++--------------
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/target/openrisc/translate.c b/target/openrisc/translate.c
index 6c745d3..f91ab6a 100644
--- a/target/openrisc/translate.c
+++ b/target/openrisc/translate.c
@@ -214,12 +214,16 @@ static void gen_jump(DisasContext *dc, int32_t n26, uint32_t reg, uint32_t op0)
     case 0x03:     /* l.bnf */
     case 0x04:     /* l.bf  */
         {
-            TCGLabel *lab = gen_new_label();
-            tcg_gen_movi_tl(jmp_pc, dc->pc+8);
-            tcg_gen_brcondi_tl(op0 == 0x03 ? TCG_COND_NE : TCG_COND_EQ,
-                               cpu_sr_f, 0, lab);
-            tcg_gen_movi_tl(jmp_pc, tmp_pc);
-            gen_set_label(lab);
+            TCGv t_next = tcg_const_tl(dc->pc + 8);
+            TCGv t_true = tcg_const_tl(tmp_pc);
+            TCGv t_zero = tcg_const_tl(0);
+
+            tcg_gen_movcond_tl(op0 == 0x03 ? TCG_COND_EQ : TCG_COND_NE,
+                               jmp_pc, cpu_sr_f, t_zero, t_true, t_next);
+
+            tcg_temp_free(t_next);
+            tcg_temp_free(t_true);
+            tcg_temp_free(t_zero);
         }
         break;
     case 0x11:     /* l.jr */
@@ -502,14 +506,10 @@ static void dec_calc(DisasContext *dc, uint32_t insn)
         case 0xe: /* l.cmov */
             LOG_DIS("l.cmov r%d, r%d, r%d\n", rd, ra, rb);
             {
-                TCGLabel *lab = gen_new_label();
-                TCGv res = tcg_temp_local_new();
-                tcg_gen_mov_tl(res, cpu_R[rb]);
-                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_sr_f, 0, lab);
-                tcg_gen_mov_tl(res, cpu_R[ra]);
-                gen_set_label(lab);
-                tcg_gen_mov_tl(cpu_R[rd], res);
-                tcg_temp_free(res);
+                TCGv zero = tcg_const_tl(0);
+                tcg_gen_movcond_tl(TCG_COND_NE, cpu_R[rd], cpu_sr_f, zero,
+                                   cpu_R[ra], cpu_R[rb]);
+                tcg_temp_free(zero);
             }
             return;
 
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Qemu-devel] [PATCH 14/22] target/openrisc: Set flags on helpers
  2017-02-09  4:51 [Qemu-devel] [PATCH 00/22] target/openrisc updates Richard Henderson
                   ` (11 preceding siblings ...)
  2017-02-09  4:51 ` [Qemu-devel] [PATCH 13/22] target/openrisc: Use movcond where appropriate Richard Henderson
@ 2017-02-09  4:51 ` Richard Henderson
  2017-02-09  5:16   ` Philippe Mathieu-Daudé
  2017-02-09  4:51 ` [Qemu-devel] [PATCH 15/22] target/openrisc: Enable trap, csync, msync, psync for user mode Richard Henderson
                   ` (8 subsequent siblings)
  21 siblings, 1 reply; 30+ messages in thread
From: Richard Henderson @ 2017-02-09  4:51 UTC (permalink / raw)
  To: qemu-devel; +Cc: shorne

Reviewed-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 target/openrisc/helper.h | 24 ++++++++++++------------
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/target/openrisc/helper.h b/target/openrisc/helper.h
index f4d97a2..78a123d 100644
--- a/target/openrisc/helper.h
+++ b/target/openrisc/helper.h
@@ -18,26 +18,26 @@
  */
 
 /* exception */
-DEF_HELPER_FLAGS_2(exception, 0, void, env, i32)
+DEF_HELPER_FLAGS_2(exception, TCG_CALL_NO_WG, void, env, i32)
 DEF_HELPER_FLAGS_1(ove_cy, TCG_CALL_NO_WG, void, env)
 DEF_HELPER_FLAGS_1(ove_ov, TCG_CALL_NO_WG, void, env)
 DEF_HELPER_FLAGS_1(ove_cyov, TCG_CALL_NO_WG, void, env)
 
 /* float */
-DEF_HELPER_FLAGS_2(itofd, 0, i64, env, i64)
-DEF_HELPER_FLAGS_2(itofs, 0, i32, env, i32)
-DEF_HELPER_FLAGS_2(ftoid, 0, i64, env, i64)
-DEF_HELPER_FLAGS_2(ftois, 0, i32, env, i32)
+DEF_HELPER_FLAGS_2(itofd, TCG_CALL_NO_WG, i64, env, i64)
+DEF_HELPER_FLAGS_2(itofs, TCG_CALL_NO_WG, i32, env, i32)
+DEF_HELPER_FLAGS_2(ftoid, TCG_CALL_NO_WG, i64, env, i64)
+DEF_HELPER_FLAGS_2(ftois, TCG_CALL_NO_WG, i32, env, i32)
 
 #define FOP_MADD(op)                                             \
-DEF_HELPER_FLAGS_3(float_ ## op ## _s, 0, i32, env, i32, i32)    \
-DEF_HELPER_FLAGS_3(float_ ## op ## _d, 0, i64, env, i64, i64)
+DEF_HELPER_FLAGS_3(float_ ## op ## _s, TCG_CALL_NO_WG, i32, env, i32, i32) \
+DEF_HELPER_FLAGS_3(float_ ## op ## _d, TCG_CALL_NO_WG, i64, env, i64, i64)
 FOP_MADD(muladd)
 #undef FOP_MADD
 
 #define FOP_CALC(op)                                            \
-DEF_HELPER_FLAGS_3(float_ ## op ## _s, 0, i32, env, i32, i32)    \
-DEF_HELPER_FLAGS_3(float_ ## op ## _d, 0, i64, env, i64, i64)
+DEF_HELPER_FLAGS_3(float_ ## op ## _s, TCG_CALL_NO_WG, i32, env, i32, i32) \
+DEF_HELPER_FLAGS_3(float_ ## op ## _d, TCG_CALL_NO_WG, i64, env, i64, i64)
 FOP_CALC(add)
 FOP_CALC(sub)
 FOP_CALC(mul)
@@ -46,8 +46,8 @@ FOP_CALC(rem)
 #undef FOP_CALC
 
 #define FOP_CMP(op)                                              \
-DEF_HELPER_FLAGS_3(float_ ## op ## _s, 0, i32, env, i32, i32)    \
-DEF_HELPER_FLAGS_3(float_ ## op ## _d, 0, i64, env, i64, i64)
+DEF_HELPER_FLAGS_3(float_ ## op ## _s, TCG_CALL_NO_WG, i32, env, i32, i32) \
+DEF_HELPER_FLAGS_3(float_ ## op ## _d, TCG_CALL_NO_WG, i64, env, i64, i64)
 FOP_CMP(eq)
 FOP_CMP(lt)
 FOP_CMP(le)
@@ -61,4 +61,4 @@ DEF_HELPER_FLAGS_1(rfe, 0, void, env)
 
 /* sys */
 DEF_HELPER_FLAGS_4(mtspr, 0, void, env, tl, tl, tl)
-DEF_HELPER_FLAGS_4(mfspr, 0, tl, env, tl, tl, tl)
+DEF_HELPER_FLAGS_4(mfspr, TCG_CALL_NO_WG, tl, env, tl, tl, tl)
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Qemu-devel] [PATCH 15/22] target/openrisc: Enable trap, csync, msync, psync for user mode
  2017-02-09  4:51 [Qemu-devel] [PATCH 00/22] target/openrisc updates Richard Henderson
                   ` (12 preceding siblings ...)
  2017-02-09  4:51 ` [Qemu-devel] [PATCH 14/22] target/openrisc: Set flags on helpers Richard Henderson
@ 2017-02-09  4:51 ` Richard Henderson
  2017-02-09  5:24   ` Philippe Mathieu-Daudé
  2017-02-09  4:51 ` [Qemu-devel] [PATCH 16/22] target/openrisc: Implement msync Richard Henderson
                   ` (7 subsequent siblings)
  21 siblings, 1 reply; 30+ messages in thread
From: Richard Henderson @ 2017-02-09  4:51 UTC (permalink / raw)
  To: qemu-devel; +Cc: shorne

Not documented as disabled for user mode.

Reviewed-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 target/openrisc/translate.c | 32 --------------------------------
 1 file changed, 32 deletions(-)

diff --git a/target/openrisc/translate.c b/target/openrisc/translate.c
index f91ab6a..6c8f05c 100644
--- a/target/openrisc/translate.c
+++ b/target/openrisc/translate.c
@@ -1134,52 +1134,20 @@ static void dec_sys(DisasContext *dc, uint32_t insn)
 
     case 0x100:    /* l.trap */
         LOG_DIS("l.trap %d\n", K16);
-#if defined(CONFIG_USER_ONLY)
-        return;
-#else
-        if (dc->mem_idx == MMU_USER_IDX) {
-            gen_illegal_exception(dc);
-            return;
-        }
         tcg_gen_movi_tl(cpu_pc, dc->pc);
         gen_exception(dc, EXCP_TRAP);
-#endif
         break;
 
     case 0x300:    /* l.csync */
         LOG_DIS("l.csync\n");
-#if defined(CONFIG_USER_ONLY)
-        return;
-#else
-        if (dc->mem_idx == MMU_USER_IDX) {
-            gen_illegal_exception(dc);
-            return;
-        }
-#endif
         break;
 
     case 0x200:    /* l.msync */
         LOG_DIS("l.msync\n");
-#if defined(CONFIG_USER_ONLY)
-        return;
-#else
-        if (dc->mem_idx == MMU_USER_IDX) {
-            gen_illegal_exception(dc);
-            return;
-        }
-#endif
         break;
 
     case 0x270:    /* l.psync */
         LOG_DIS("l.psync\n");
-#if defined(CONFIG_USER_ONLY)
-        return;
-#else
-        if (dc->mem_idx == MMU_USER_IDX) {
-            gen_illegal_exception(dc);
-            return;
-        }
-#endif
         break;
 
     default:
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Qemu-devel] [PATCH 16/22] target/openrisc: Implement msync
  2017-02-09  4:51 [Qemu-devel] [PATCH 00/22] target/openrisc updates Richard Henderson
                   ` (13 preceding siblings ...)
  2017-02-09  4:51 ` [Qemu-devel] [PATCH 15/22] target/openrisc: Enable trap, csync, msync, psync for user mode Richard Henderson
@ 2017-02-09  4:51 ` Richard Henderson
  2017-02-09  4:51 ` [Qemu-devel] [PATCH 17/22] target/openrisc: Represent MACHI:MACLO as a single unit Richard Henderson
                   ` (6 subsequent siblings)
  21 siblings, 0 replies; 30+ messages in thread
From: Richard Henderson @ 2017-02-09  4:51 UTC (permalink / raw)
  To: qemu-devel; +Cc: shorne

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 target/openrisc/translate.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/target/openrisc/translate.c b/target/openrisc/translate.c
index 6c8f05c..dd4ba8c 100644
--- a/target/openrisc/translate.c
+++ b/target/openrisc/translate.c
@@ -1144,6 +1144,7 @@ static void dec_sys(DisasContext *dc, uint32_t insn)
 
     case 0x200:    /* l.msync */
         LOG_DIS("l.msync\n");
+        tcg_gen_mb(TCG_MO_ALL);
         break;
 
     case 0x270:    /* l.psync */
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Qemu-devel] [PATCH 17/22] target/openrisc: Represent MACHI:MACLO as a single unit
  2017-02-09  4:51 [Qemu-devel] [PATCH 00/22] target/openrisc updates Richard Henderson
                   ` (14 preceding siblings ...)
  2017-02-09  4:51 ` [Qemu-devel] [PATCH 16/22] target/openrisc: Implement msync Richard Henderson
@ 2017-02-09  4:51 ` Richard Henderson
  2017-02-09  4:51 ` [Qemu-devel] [PATCH 18/22] target/openrisc: Implement muld, muldu, macu, msbu Richard Henderson
                   ` (5 subsequent siblings)
  21 siblings, 0 replies; 30+ messages in thread
From: Richard Henderson @ 2017-02-09  4:51 UTC (permalink / raw)
  To: qemu-devel; +Cc: shorne

Significantly simplifies the implementation of the use of MAC.

Reviewed-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 target/openrisc/cpu.h        |   3 +-
 target/openrisc/machine.c    |   5 +-
 target/openrisc/sys_helper.c |  13 +++++
 target/openrisc/translate.c  | 120 +++++++++++++++++++++++--------------------
 4 files changed, 80 insertions(+), 61 deletions(-)

diff --git a/target/openrisc/cpu.h b/target/openrisc/cpu.h
index 82b87b3..1ee1210 100644
--- a/target/openrisc/cpu.h
+++ b/target/openrisc/cpu.h
@@ -277,8 +277,7 @@ typedef struct CPUOpenRISCState {
     target_ulong ppc;         /* Prev PC */
     target_ulong jmp_pc;      /* Jump PC */
 
-    target_ulong machi;       /* Multiply register MACHI */
-    target_ulong maclo;       /* Multiply register MACLO */
+    uint64_t mac;             /* Multiply registers MACHI:MACLO */
 
     target_ulong fpmaddhi;    /* Multiply and add float register FPMADDHI */
     target_ulong fpmaddlo;    /* Multiply and add float register FPMADDLO */
diff --git a/target/openrisc/machine.c b/target/openrisc/machine.c
index b723138..4100957 100644
--- a/target/openrisc/machine.c
+++ b/target/openrisc/machine.c
@@ -47,8 +47,8 @@ static const VMStateInfo vmstate_sr = {
 
 static const VMStateDescription vmstate_env = {
     .name = "env",
-    .version_id = 2,
-    .minimum_version_id = 2,
+    .version_id = 3,
+    .minimum_version_id = 3,
     .fields = (VMStateField[]) {
         VMSTATE_UINTTL_ARRAY(gpr, CPUOpenRISCState, 32),
         VMSTATE_UINTTL(pc, CPUOpenRISCState),
@@ -82,6 +82,7 @@ static const VMStateDescription vmstate_env = {
         VMSTATE_UINT32(immucfgr, CPUOpenRISCState),
         VMSTATE_UINT32(esr, CPUOpenRISCState),
         VMSTATE_UINT32(fpcsr, CPUOpenRISCState),
+        VMSTATE_UINT64(mac, CPUOpenRISCState),
         VMSTATE_END_OF_LIST()
     }
 };
diff --git a/target/openrisc/sys_helper.c b/target/openrisc/sys_helper.c
index 4a59728..9841a5b 100644
--- a/target/openrisc/sys_helper.c
+++ b/target/openrisc/sys_helper.c
@@ -120,6 +120,12 @@ void HELPER(mtspr)(CPUOpenRISCState *env,
     case TO_SPR(2, 1280) ... TO_SPR(2, 1407): /* ITLBW3MR 0-127 */
     case TO_SPR(2, 1408) ... TO_SPR(2, 1535): /* ITLBW3TR 0-127 */
         break;
+    case TO_SPR(5, 1):  /* MACLO */
+        env->mac = deposit64(env->mac, 0, 32, rb);
+        break;
+    case TO_SPR(5, 2):  /* MACHI */
+        env->mac = deposit64(env->mac, 32, 32, rb);
+        break;
     case TO_SPR(9, 0):  /* PICMR */
         env->picmr |= rb;
         break;
@@ -245,6 +251,13 @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env,
     case TO_SPR(2, 1408) ... TO_SPR(2, 1535): /* ITLBW3TR 0-127 */
         break;
 
+    case TO_SPR(5, 1):  /* MACLO */
+        return (uint32_t)env->mac;
+        break;
+    case TO_SPR(5, 2):  /* MACHI */
+        return env->mac >> 32;
+        break;
+
     case TO_SPR(9, 0):  /* PICMR */
         return env->picmr;
 
diff --git a/target/openrisc/translate.c b/target/openrisc/translate.c
index dd4ba8c..82b8bec 100644
--- a/target/openrisc/translate.c
+++ b/target/openrisc/translate.c
@@ -60,7 +60,7 @@ static TCGv cpu_sr_ov;          /* signed overflow */
 static TCGv cpu_lock_addr;
 static TCGv cpu_lock_value;
 static TCGv_i32 fpcsr;
-static TCGv machi, maclo;
+static TCGv_i64 cpu_mac;        /* MACHI:MACLO */
 static TCGv fpmaddhi, fpmaddlo;
 static TCGv_i32 env_flags;
 #include "exec/gen-icount.h"
@@ -105,12 +105,9 @@ void openrisc_translate_init(void)
     fpcsr = tcg_global_mem_new_i32(cpu_env,
                                    offsetof(CPUOpenRISCState, fpcsr),
                                    "fpcsr");
-    machi = tcg_global_mem_new(cpu_env,
-                               offsetof(CPUOpenRISCState, machi),
-                               "machi");
-    maclo = tcg_global_mem_new(cpu_env,
-                               offsetof(CPUOpenRISCState, maclo),
-                               "maclo");
+    cpu_mac = tcg_global_mem_new_i64(cpu_env,
+                                     offsetof(CPUOpenRISCState, mac),
+                                     "mac");
     fpmaddhi = tcg_global_mem_new(cpu_env,
                                   offsetof(CPUOpenRISCState, fpmaddhi),
                                   "fpmaddhi");
@@ -365,6 +362,58 @@ static void gen_divu(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb)
     gen_ove_cy(dc);
 }
 
+static void gen_mac(DisasContext *dc, TCGv srca, TCGv srcb)
+{
+    TCGv_i64 t1 = tcg_temp_new_i64();
+    TCGv_i64 t2 = tcg_temp_new_i64();
+
+    tcg_gen_ext_tl_i64(t1, srca);
+    tcg_gen_ext_tl_i64(t2, srcb);
+    tcg_gen_mul_i64(t1, t1, t2);
+
+    /* Note that overflow is only computed during addition stage.  */
+    tcg_gen_xor_i64(t2, cpu_mac, t1);
+    tcg_gen_add_i64(cpu_mac, cpu_mac, t1);
+    tcg_gen_xor_i64(t1, t1, cpu_mac);
+    tcg_gen_andc_i64(t1, t1, t2);
+    tcg_temp_free_i64(t2);
+
+#if TARGET_LONG_BITS == 32
+    tcg_gen_extrh_i64_i32(cpu_sr_ov, t1);
+#else
+    tcg_gen_mov_i64(cpu_sr_ov, t1);
+#endif
+    tcg_temp_free_i64(t1);
+
+    gen_ove_ov(dc);
+}
+
+static void gen_msb(DisasContext *dc, TCGv srca, TCGv srcb)
+{
+    TCGv_i64 t1 = tcg_temp_new_i64();
+    TCGv_i64 t2 = tcg_temp_new_i64();
+
+    tcg_gen_ext_tl_i64(t1, srca);
+    tcg_gen_ext_tl_i64(t2, srcb);
+    tcg_gen_mul_i64(t1, t1, t2);
+
+    /* Note that overflow is only computed during subtraction stage.  */
+    tcg_gen_xor_i64(t2, cpu_mac, t1);
+    tcg_gen_sub_i64(cpu_mac, cpu_mac, t1);
+    tcg_gen_xor_i64(t1, t1, cpu_mac);
+    tcg_gen_and_i64(t1, t1, t2);
+    tcg_temp_free_i64(t2);
+
+#if TARGET_LONG_BITS == 32
+    tcg_gen_extrh_i64_i32(cpu_sr_ov, t1);
+#else
+    tcg_gen_mov_i64(cpu_sr_ov, t1);
+#endif
+    tcg_temp_free_i64(t1);
+
+    gen_ove_ov(dc);
+}
+
 static void gen_lwa(DisasContext *dc, TCGv rd, TCGv ra, int32_t ofs)
 {
     TCGv ea = tcg_temp_new();
@@ -628,23 +677,9 @@ static void dec_misc(DisasContext *dc, uint32_t insn)
 
     case 0x13:    /* l.maci */
         LOG_DIS("l.maci r%d, %d\n", ra, I16);
-        {
-            TCGv_i64 t1 = tcg_temp_new_i64();
-            TCGv_i64 t2 = tcg_temp_new_i64();
-            TCGv_i32 dst = tcg_temp_new_i32();
-            TCGv ttmp = tcg_const_tl(I16);
-            tcg_gen_mul_tl(dst, cpu_R[ra], ttmp);
-            tcg_gen_ext_i32_i64(t1, dst);
-            tcg_gen_concat_i32_i64(t2, maclo, machi);
-            tcg_gen_add_i64(t2, t2, t1);
-            tcg_gen_extrl_i64_i32(maclo, t2);
-            tcg_gen_shri_i64(t2, t2, 32);
-            tcg_gen_extrl_i64_i32(machi, t2);
-            tcg_temp_free_i32(dst);
-            tcg_temp_free(ttmp);
-            tcg_temp_free_i64(t1);
-            tcg_temp_free_i64(t2);
-        }
+        t0 = tcg_const_tl(I16);
+        gen_mac(dc, cpu_R[ra], t0);
+        tcg_temp_free(t0);
         break;
 
     case 0x09:    /* l.rfe */
@@ -873,40 +908,12 @@ static void dec_mac(DisasContext *dc, uint32_t insn)
     switch (op0) {
     case 0x0001:    /* l.mac */
         LOG_DIS("l.mac r%d, r%d\n", ra, rb);
-        {
-            TCGv_i32 t0 = tcg_temp_new_i32();
-            TCGv_i64 t1 = tcg_temp_new_i64();
-            TCGv_i64 t2 = tcg_temp_new_i64();
-            tcg_gen_mul_tl(t0, cpu_R[ra], cpu_R[rb]);
-            tcg_gen_ext_i32_i64(t1, t0);
-            tcg_gen_concat_i32_i64(t2, maclo, machi);
-            tcg_gen_add_i64(t2, t2, t1);
-            tcg_gen_extrl_i64_i32(maclo, t2);
-            tcg_gen_shri_i64(t2, t2, 32);
-            tcg_gen_extrl_i64_i32(machi, t2);
-            tcg_temp_free_i32(t0);
-            tcg_temp_free_i64(t1);
-            tcg_temp_free_i64(t2);
-        }
+        gen_mac(dc, cpu_R[ra], cpu_R[rb]);
         break;
 
     case 0x0002:    /* l.msb */
         LOG_DIS("l.msb r%d, r%d\n", ra, rb);
-        {
-            TCGv_i32 t0 = tcg_temp_new_i32();
-            TCGv_i64 t1 = tcg_temp_new_i64();
-            TCGv_i64 t2 = tcg_temp_new_i64();
-            tcg_gen_mul_tl(t0, cpu_R[ra], cpu_R[rb]);
-            tcg_gen_ext_i32_i64(t1, t0);
-            tcg_gen_concat_i32_i64(t2, maclo, machi);
-            tcg_gen_sub_i64(t2, t2, t1);
-            tcg_gen_extrl_i64_i32(maclo, t2);
-            tcg_gen_shri_i64(t2, t2, 32);
-            tcg_gen_extrl_i64_i32(machi, t2);
-            tcg_temp_free_i32(t0);
-            tcg_temp_free_i64(t1);
-            tcg_temp_free_i64(t2);
-        }
+        gen_msb(dc, cpu_R[ra], cpu_R[rb]);
         break;
 
     default:
@@ -969,9 +976,8 @@ static void dec_M(DisasContext *dc, uint32_t insn)
 
     case 0x1:    /* l.macrc */
         LOG_DIS("l.macrc  r%d\n", rd);
-        tcg_gen_mov_tl(cpu_R[rd], maclo);
-        tcg_gen_movi_tl(maclo, 0x0);
-        tcg_gen_movi_tl(machi, 0x0);
+        tcg_gen_trunc_i64_tl(cpu_R[rd], cpu_mac);
+        tcg_gen_movi_i64(cpu_mac, 0);
         break;
 
     default:
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Qemu-devel] [PATCH 18/22] target/openrisc: Implement muld, muldu, macu, msbu
  2017-02-09  4:51 [Qemu-devel] [PATCH 00/22] target/openrisc updates Richard Henderson
                   ` (15 preceding siblings ...)
  2017-02-09  4:51 ` [Qemu-devel] [PATCH 17/22] target/openrisc: Represent MACHI:MACLO as a single unit Richard Henderson
@ 2017-02-09  4:51 ` Richard Henderson
  2017-02-09  4:51 ` [Qemu-devel] [PATCH 19/22] target/openrisc: Fix madd Richard Henderson
                   ` (4 subsequent siblings)
  21 siblings, 0 replies; 30+ messages in thread
From: Richard Henderson @ 2017-02-09  4:51 UTC (permalink / raw)
  To: qemu-devel; +Cc: shorne

Reviewed-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 target/openrisc/translate.c | 108 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 108 insertions(+)

diff --git a/target/openrisc/translate.c b/target/openrisc/translate.c
index 82b8bec..ce9672e 100644
--- a/target/openrisc/translate.c
+++ b/target/openrisc/translate.c
@@ -362,6 +362,56 @@ static void gen_divu(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb)
     gen_ove_cy(dc);
 }
 
+static void gen_muld(DisasContext *dc, TCGv srca, TCGv srcb)
+{
+    TCGv_i64 t1 = tcg_temp_new_i64();
+    TCGv_i64 t2 = tcg_temp_new_i64();
+
+    tcg_gen_ext_tl_i64(t1, srca);
+    tcg_gen_ext_tl_i64(t2, srcb);
+    if (TARGET_LONG_BITS == 32) {
+        tcg_gen_mul_i64(cpu_mac, t1, t2);
+        tcg_gen_movi_tl(cpu_sr_ov, 0);
+    } else {
+        TCGv_i64 high = tcg_temp_new_i64();
+
+        tcg_gen_muls2_i64(cpu_mac, high, t1, t2);
+        tcg_gen_sari_i64(t1, cpu_mac, 63);
+        tcg_gen_setcond_i64(TCG_COND_NE, t1, t1, high);
+        tcg_temp_free_i64(high);
+        tcg_gen_trunc_i64_tl(cpu_sr_ov, t1);
+        tcg_gen_neg_tl(cpu_sr_ov, cpu_sr_ov);
+
+        gen_ove_ov(dc);
+    }
+    tcg_temp_free_i64(t1);
+    tcg_temp_free_i64(t2);
+}
+
+static void gen_muldu(DisasContext *dc, TCGv srca, TCGv srcb)
+{
+    TCGv_i64 t1 = tcg_temp_new_i64();
+    TCGv_i64 t2 = tcg_temp_new_i64();
+
+    tcg_gen_extu_tl_i64(t1, srca);
+    tcg_gen_extu_tl_i64(t2, srcb);
+    if (TARGET_LONG_BITS == 32) {
+        tcg_gen_mul_i64(cpu_mac, t1, t2);
+        tcg_gen_movi_tl(cpu_sr_cy, 0);
+    } else {
+        TCGv_i64 high = tcg_temp_new_i64();
+
+        tcg_gen_mulu2_i64(cpu_mac, high, t1, t2);
+        tcg_gen_setcondi_i64(TCG_COND_NE, high, high, 0);
+        tcg_gen_trunc_i64_tl(cpu_sr_cy, high);
+        tcg_temp_free_i64(high);
+
+        gen_ove_cy(dc);
+    }
+    tcg_temp_free_i64(t1);
+    tcg_temp_free_i64(t2);
+}
+
 static void gen_mac(DisasContext *dc, TCGv srca, TCGv srcb)
 {
     TCGv_i64 t1 = tcg_temp_new_i64();
@@ -388,6 +438,25 @@ static void gen_mac(DisasContext *dc, TCGv srca, TCGv srcb)
     gen_ove_ov(dc);
 }
 
+static void gen_macu(DisasContext *dc, TCGv srca, TCGv srcb)
+{
+    TCGv_i64 t1 = tcg_temp_new_i64();
+    TCGv_i64 t2 = tcg_temp_new_i64();
+
+    tcg_gen_extu_tl_i64(t1, srca);
+    tcg_gen_extu_tl_i64(t2, srcb);
+    tcg_gen_mul_i64(t1, t1, t2);
+    tcg_temp_free_i64(t2);
+
+    /* Note that overflow is only computed during addition stage.  */
+    tcg_gen_add_i64(cpu_mac, cpu_mac, t1);
+    tcg_gen_setcond_i64(TCG_COND_LTU, t1, cpu_mac, t1);
+    tcg_gen_trunc_i64_tl(cpu_sr_cy, t1);
+    tcg_temp_free_i64(t1);
+
+    gen_ove_cy(dc);
+}
+
 static void gen_msb(DisasContext *dc, TCGv srca, TCGv srcb)
 {
     TCGv_i64 t1 = tcg_temp_new_i64();
@@ -414,6 +483,25 @@ static void gen_msb(DisasContext *dc, TCGv srca, TCGv srcb)
     gen_ove_ov(dc);
 }
 
+static void gen_msbu(DisasContext *dc, TCGv srca, TCGv srcb)
+{
+    TCGv_i64 t1 = tcg_temp_new_i64();
+    TCGv_i64 t2 = tcg_temp_new_i64();
+
+    tcg_gen_extu_tl_i64(t1, srca);
+    tcg_gen_extu_tl_i64(t2, srcb);
+    tcg_gen_mul_i64(t1, t1, t2);
+
+    /* Note that overflow is only computed during subtraction stage.  */
+    tcg_gen_setcond_i64(TCG_COND_LTU, t2, cpu_mac, t1);
+    tcg_gen_sub_i64(cpu_mac, cpu_mac, t1);
+    tcg_gen_trunc_i64_tl(cpu_sr_cy, t2);
+    tcg_temp_free_i64(t2);
+    tcg_temp_free_i64(t1);
+
+    gen_ove_cy(dc);
+}
+
 static void gen_lwa(DisasContext *dc, TCGv rd, TCGv ra, int32_t ofs)
 {
     TCGv ea = tcg_temp_new();
@@ -590,6 +678,11 @@ static void dec_calc(DisasContext *dc, uint32_t insn)
             gen_mul(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]);
             return;
 
+        case 0x7: /* l.muld */
+            LOG_DIS("l.muld r%d, r%d\n", ra, rb);
+            gen_muld(dc, cpu_R[ra], cpu_R[rb]);
+            break;
+
         case 0x9: /* l.div */
             LOG_DIS("l.div r%d, r%d, r%d\n", rd, ra, rb);
             gen_div(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]);
@@ -604,6 +697,11 @@ static void dec_calc(DisasContext *dc, uint32_t insn)
             LOG_DIS("l.mulu r%d, r%d, r%d\n", rd, ra, rb);
             gen_mulu(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]);
             return;
+
+        case 0xc: /* l.muldu */
+            LOG_DIS("l.muldu r%d, r%d\n", ra, rb);
+            gen_muldu(dc, cpu_R[ra], cpu_R[rb]);
+            return;
         }
         break;
     }
@@ -916,6 +1014,16 @@ static void dec_mac(DisasContext *dc, uint32_t insn)
         gen_msb(dc, cpu_R[ra], cpu_R[rb]);
         break;
 
+    case 0x0003:    /* l.macu */
+        LOG_DIS("l.macu r%d, r%d\n", ra, rb);
+        gen_macu(dc, cpu_R[ra], cpu_R[rb]);
+        break;
+
+    case 0x0004:    /* l.msbu */
+        LOG_DIS("l.msbu r%d, r%d\n", ra, rb);
+        gen_msbu(dc, cpu_R[ra], cpu_R[rb]);
+        break;
+
     default:
         gen_illegal_exception(dc);
         break;
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Qemu-devel] [PATCH 19/22] target/openrisc: Fix madd
  2017-02-09  4:51 [Qemu-devel] [PATCH 00/22] target/openrisc updates Richard Henderson
                   ` (16 preceding siblings ...)
  2017-02-09  4:51 ` [Qemu-devel] [PATCH 18/22] target/openrisc: Implement muld, muldu, macu, msbu Richard Henderson
@ 2017-02-09  4:51 ` Richard Henderson
  2017-02-09  4:51 ` [Qemu-devel] [PATCH 20/22] target/openrisc: Optimize l.jal to next Richard Henderson
                   ` (3 subsequent siblings)
  21 siblings, 0 replies; 30+ messages in thread
From: Richard Henderson @ 2017-02-09  4:51 UTC (permalink / raw)
  To: qemu-devel; +Cc: shorne

Note that the specification for lf.madd.s is confused.  It's
the only mention of supposed FPMADDHI/FPMADDLO special registers.
On the other hand, or1ksim implements a somewhat normal non-fused
multiply and add.  Mirror that.

Reviewed-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 target/openrisc/cpu.h        |  3 --
 target/openrisc/fpu_helper.c | 68 ++++++++++++++++----------------------------
 target/openrisc/helper.h     |  7 ++---
 target/openrisc/translate.c  | 13 +++------
 4 files changed, 30 insertions(+), 61 deletions(-)

diff --git a/target/openrisc/cpu.h b/target/openrisc/cpu.h
index 1ee1210..6426e32 100644
--- a/target/openrisc/cpu.h
+++ b/target/openrisc/cpu.h
@@ -279,9 +279,6 @@ typedef struct CPUOpenRISCState {
 
     uint64_t mac;             /* Multiply registers MACHI:MACLO */
 
-    target_ulong fpmaddhi;    /* Multiply and add float register FPMADDHI */
-    target_ulong fpmaddlo;    /* Multiply and add float register FPMADDLO */
-
     target_ulong epcr;        /* Exception PC register */
     target_ulong eear;        /* Exception EA register */
 
diff --git a/target/openrisc/fpu_helper.c b/target/openrisc/fpu_helper.c
index c54404b..1375cea 100644
--- a/target/openrisc/fpu_helper.c
+++ b/target/openrisc/fpu_helper.c
@@ -146,52 +146,32 @@ FLOAT_CALC(div)
 FLOAT_CALC(rem)
 #undef FLOAT_CALC
 
-#define FLOAT_TERNOP(name1, name2)                                        \
-uint64_t helper_float_ ## name1 ## name2 ## _d(CPUOpenRISCState *env,     \
-                                               uint64_t fdt0,             \
-                                               uint64_t fdt1)             \
-{                                                                         \
-    uint64_t result, temp, hi, lo;                                        \
-    uint32_t val1, val2;                                                  \
-    OpenRISCCPU *cpu = openrisc_env_get_cpu(env);                         \
-    hi = env->fpmaddhi;                                                   \
-    lo = env->fpmaddlo;                                                   \
-    set_float_exception_flags(0, &cpu->env.fp_status);                    \
-    result = float64_ ## name1(fdt0, fdt1, &cpu->env.fp_status);          \
-    lo &= 0xffffffff;                                                     \
-    hi &= 0xffffffff;                                                     \
-    temp = (hi << 32) | lo;                                               \
-    result = float64_ ## name2(result, temp, &cpu->env.fp_status);        \
-    val1 = result >> 32;                                                  \
-    val2 = (uint32_t) (result & 0xffffffff);                              \
-    update_fpcsr(cpu);                                                    \
-    cpu->env.fpmaddlo = val2;                                             \
-    cpu->env.fpmaddhi = val1;                                             \
-    return 0;                                                             \
-}                                                                         \
-                                                                          \
-uint32_t helper_float_ ## name1 ## name2 ## _s(CPUOpenRISCState *env,     \
-                                            uint32_t fdt0, uint32_t fdt1) \
-{                                                                         \
-    uint64_t result, temp, hi, lo;                                        \
-    uint32_t val1, val2;                                                  \
-    OpenRISCCPU *cpu = openrisc_env_get_cpu(env);                         \
-    hi = cpu->env.fpmaddhi;                                               \
-    lo = cpu->env.fpmaddlo;                                               \
-    set_float_exception_flags(0, &cpu->env.fp_status);                    \
-    result = float64_ ## name1(fdt0, fdt1, &cpu->env.fp_status);          \
-    temp = (hi << 32) | lo;                                               \
-    result = float64_ ## name2(result, temp, &cpu->env.fp_status);        \
-    val1 = result >> 32;                                                  \
-    val2 = (uint32_t) (result & 0xffffffff);                              \
-    update_fpcsr(cpu);                                                    \
-    cpu->env.fpmaddlo = val2;                                             \
-    cpu->env.fpmaddhi = val1;                                             \
-    return 0;                                                             \
+
+uint64_t helper_float_madd_d(CPUOpenRISCState *env, uint64_t a,
+                             uint64_t b, uint64_t c)
+{
+    OpenRISCCPU *cpu = openrisc_env_get_cpu(env);
+    uint64_t result;
+    set_float_exception_flags(0, &cpu->env.fp_status);
+    /* Note that or1ksim doesn't use merged operation.  */
+    result = float64_mul(b, c, &cpu->env.fp_status);
+    result = float64_add(result, a, &cpu->env.fp_status);
+    update_fpcsr(cpu);
+    return result;
 }
 
-FLOAT_TERNOP(mul, add)
-#undef FLOAT_TERNOP
+uint32_t helper_float_madd_s(CPUOpenRISCState *env, uint32_t a,
+                             uint32_t b, uint32_t c)
+{
+    OpenRISCCPU *cpu = openrisc_env_get_cpu(env);
+    uint32_t result;
+    set_float_exception_flags(0, &cpu->env.fp_status);
+    /* Note that or1ksim doesn't use merged operation.  */
+    result = float32_mul(b, c, &cpu->env.fp_status);
+    result = float32_add(result, a, &cpu->env.fp_status);
+    update_fpcsr(cpu);
+    return result;
+}
 
 
 #define FLOAT_CMP(name)                                                   \
diff --git a/target/openrisc/helper.h b/target/openrisc/helper.h
index 78a123d..4fd1a6b 100644
--- a/target/openrisc/helper.h
+++ b/target/openrisc/helper.h
@@ -29,11 +29,8 @@ DEF_HELPER_FLAGS_2(itofs, TCG_CALL_NO_WG, i32, env, i32)
 DEF_HELPER_FLAGS_2(ftoid, TCG_CALL_NO_WG, i64, env, i64)
 DEF_HELPER_FLAGS_2(ftois, TCG_CALL_NO_WG, i32, env, i32)
 
-#define FOP_MADD(op)                                             \
-DEF_HELPER_FLAGS_3(float_ ## op ## _s, TCG_CALL_NO_WG, i32, env, i32, i32) \
-DEF_HELPER_FLAGS_3(float_ ## op ## _d, TCG_CALL_NO_WG, i64, env, i64, i64)
-FOP_MADD(muladd)
-#undef FOP_MADD
+DEF_HELPER_FLAGS_4(float_madd_s, TCG_CALL_NO_WG, i32, env, i32, i32, i32)
+DEF_HELPER_FLAGS_4(float_madd_d, TCG_CALL_NO_WG, i64, env, i64, i64, i64)
 
 #define FOP_CALC(op)                                            \
 DEF_HELPER_FLAGS_3(float_ ## op ## _s, TCG_CALL_NO_WG, i32, env, i32, i32) \
diff --git a/target/openrisc/translate.c b/target/openrisc/translate.c
index ce9672e..66064e1 100644
--- a/target/openrisc/translate.c
+++ b/target/openrisc/translate.c
@@ -61,7 +61,6 @@ static TCGv cpu_lock_addr;
 static TCGv cpu_lock_value;
 static TCGv_i32 fpcsr;
 static TCGv_i64 cpu_mac;        /* MACHI:MACLO */
-static TCGv fpmaddhi, fpmaddlo;
 static TCGv_i32 env_flags;
 #include "exec/gen-icount.h"
 
@@ -108,12 +107,6 @@ void openrisc_translate_init(void)
     cpu_mac = tcg_global_mem_new_i64(cpu_env,
                                      offsetof(CPUOpenRISCState, mac),
                                      "mac");
-    fpmaddhi = tcg_global_mem_new(cpu_env,
-                                  offsetof(CPUOpenRISCState, fpmaddhi),
-                                  "fpmaddhi");
-    fpmaddlo = tcg_global_mem_new(cpu_env,
-                                  offsetof(CPUOpenRISCState, fpmaddlo),
-                                  "fpmaddlo");
     for (i = 0; i < 32; i++) {
         cpu_R[i] = tcg_global_mem_new(cpu_env,
                                       offsetof(CPUOpenRISCState, gpr[i]),
@@ -1324,7 +1317,8 @@ static void dec_float(DisasContext *dc, uint32_t insn)
 
     case 0x07:    /* lf.madd.s */
         LOG_DIS("lf.madd.s r%d, r%d, r%d\n", rd, ra, rb);
-        gen_helper_float_muladd_s(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
+        gen_helper_float_madd_s(cpu_R[rd], cpu_env, cpu_R[rd],
+                                cpu_R[ra], cpu_R[rb]);
         break;
 
     case 0x08:    /* lf.sfeq.s */
@@ -1409,7 +1403,8 @@ static void dec_float(DisasContext *dc, uint32_t insn)
     case 0x17:     lf.madd.d
         LOG_DIS("lf.madd.d r%d, r%d, r%d\n", rd, ra, rb);
         check_of64s(dc);
-        gen_helper_float_muladd_d(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
+        gen_helper_float_madd_d(cpu_R[rd], cpu_env, cpu_R[rd],
+                                cpu_R[ra], cpu_R[rb]);
         break;
 
     case 0x18:     lf.sfeq.d
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Qemu-devel] [PATCH 20/22] target/openrisc: Optimize l.jal to next
  2017-02-09  4:51 [Qemu-devel] [PATCH 00/22] target/openrisc updates Richard Henderson
                   ` (17 preceding siblings ...)
  2017-02-09  4:51 ` [Qemu-devel] [PATCH 19/22] target/openrisc: Fix madd Richard Henderson
@ 2017-02-09  4:51 ` Richard Henderson
  2017-02-09  5:20   ` Philippe Mathieu-Daudé
  2017-02-09  4:51 ` [Qemu-devel] [PATCH 21/22] target/openrisc: Tidy ppc/npc implementation Richard Henderson
                   ` (2 subsequent siblings)
  21 siblings, 1 reply; 30+ messages in thread
From: Richard Henderson @ 2017-02-09  4:51 UTC (permalink / raw)
  To: qemu-devel; +Cc: shorne

This allows the tcg optimizer to see, and fold, all of the
constants involved in a GOT base register load sequence.

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 target/openrisc/translate.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/target/openrisc/translate.c b/target/openrisc/translate.c
index 66064e1..cda84b6 100644
--- a/target/openrisc/translate.c
+++ b/target/openrisc/translate.c
@@ -198,7 +198,11 @@ static void gen_jump(DisasContext *dc, int32_t n26, uint32_t reg, uint32_t op0)
         tcg_gen_movi_tl(jmp_pc, tmp_pc);
         break;
     case 0x01:     /* l.jal */
-        tcg_gen_movi_tl(cpu_R[9], (dc->pc + 8));
+        tcg_gen_movi_tl(cpu_R[9], dc->pc + 8);
+        /* Optimize jal being used to load the PC for PIC.  */
+        if (tmp_pc == dc->pc + 8) {
+            return;
+        }
         tcg_gen_movi_tl(jmp_pc, tmp_pc);
         break;
     case 0x03:     /* l.bnf */
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Qemu-devel] [PATCH 21/22] target/openrisc: Tidy ppc/npc implementation
  2017-02-09  4:51 [Qemu-devel] [PATCH 00/22] target/openrisc updates Richard Henderson
                   ` (18 preceding siblings ...)
  2017-02-09  4:51 ` [Qemu-devel] [PATCH 20/22] target/openrisc: Optimize l.jal to next Richard Henderson
@ 2017-02-09  4:51 ` Richard Henderson
  2017-02-09  4:51 ` [Qemu-devel] [PATCH 22/22] target/openrisc: Tidy handling of delayed branches Richard Henderson
  2017-02-10  0:01 ` [Qemu-devel] [PATCH 23/22] linux-user: Honor CLONE_SETTLS for openrisc Richard Henderson
  21 siblings, 0 replies; 30+ messages in thread
From: Richard Henderson @ 2017-02-09  4:51 UTC (permalink / raw)
  To: qemu-devel; +Cc: shorne

The NPC SPR is really only supposed to be used for FPGA debugging.
It contains the same contents as PC, unless one plays games.  Follow
the or1ksim implementation in flushing delayed branch state when it
is changed.

The PPC SPR need not be updated every instruction, merely when we
exit the TB or attempt to read its contents.

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 target/openrisc/cpu.h              |  2 +-
 target/openrisc/gdbstub.c          | 13 +++++++----
 target/openrisc/interrupt_helper.c |  1 -
 target/openrisc/machine.c          |  5 ++---
 target/openrisc/sys_helper.c       | 44 ++++++++++++++------------------------
 target/openrisc/translate.c        | 29 ++++++++++---------------
 6 files changed, 39 insertions(+), 55 deletions(-)

diff --git a/target/openrisc/cpu.h b/target/openrisc/cpu.h
index 6426e32..b3d43e1 100644
--- a/target/openrisc/cpu.h
+++ b/target/openrisc/cpu.h
@@ -58,6 +58,7 @@ typedef struct OpenRISCCPUClass {
 } OpenRISCCPUClass;
 
 #define NB_MMU_MODES    3
+#define TARGET_INSN_START_EXTRA_WORDS 1
 
 enum {
     MMU_NOMMU_IDX = 0,
@@ -273,7 +274,6 @@ typedef struct CPUOpenRISCTLBContext {
 typedef struct CPUOpenRISCState {
     target_ulong gpr[32];     /* General registers */
     target_ulong pc;          /* Program counter */
-    target_ulong npc;         /* Next PC */
     target_ulong ppc;         /* Prev PC */
     target_ulong jmp_pc;      /* Jump PC */
 
diff --git a/target/openrisc/gdbstub.c b/target/openrisc/gdbstub.c
index 31ea013..2a4821f 100644
--- a/target/openrisc/gdbstub.c
+++ b/target/openrisc/gdbstub.c
@@ -34,8 +34,8 @@ int openrisc_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n)
         case 32:    /* PPC */
             return gdb_get_reg32(mem_buf, env->ppc);
 
-        case 33:    /* NPC */
-            return gdb_get_reg32(mem_buf, env->npc);
+        case 33:    /* NPC (equals PC) */
+            return gdb_get_reg32(mem_buf, env->pc);
 
         case 34:    /* SR */
             return gdb_get_reg32(mem_buf, cpu_get_sr(env));
@@ -68,8 +68,13 @@ int openrisc_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
             env->ppc = tmp;
             break;
 
-        case 33: /* NPC */
-            env->npc = tmp;
+        case 33: /* NPC (equals PC) */
+            /* If setting PC to something different,
+               also clear delayed branch status.  */
+            if (env->pc != tmp) {
+                env->pc = tmp;
+                env->flags = 0;
+            }
             break;
 
         case 34: /* SR */
diff --git a/target/openrisc/interrupt_helper.c b/target/openrisc/interrupt_helper.c
index c7fa97a..56620e0 100644
--- a/target/openrisc/interrupt_helper.c
+++ b/target/openrisc/interrupt_helper.c
@@ -32,7 +32,6 @@ void HELPER(rfe)(CPUOpenRISCState *env)
                          (cpu->env.esr & (SR_SM | SR_IME | SR_DME));
 #endif
     cpu->env.pc = cpu->env.epcr;
-    cpu->env.npc = cpu->env.epcr;
     cpu_set_sr(&cpu->env, cpu->env.esr);
     cpu->env.lock_addr = -1;
 
diff --git a/target/openrisc/machine.c b/target/openrisc/machine.c
index 4100957..686eaa3 100644
--- a/target/openrisc/machine.c
+++ b/target/openrisc/machine.c
@@ -47,12 +47,11 @@ static const VMStateInfo vmstate_sr = {
 
 static const VMStateDescription vmstate_env = {
     .name = "env",
-    .version_id = 3,
-    .minimum_version_id = 3,
+    .version_id = 4,
+    .minimum_version_id = 4,
     .fields = (VMStateField[]) {
         VMSTATE_UINTTL_ARRAY(gpr, CPUOpenRISCState, 32),
         VMSTATE_UINTTL(pc, CPUOpenRISCState),
-        VMSTATE_UINTTL(npc, CPUOpenRISCState),
         VMSTATE_UINTTL(ppc, CPUOpenRISCState),
         VMSTATE_UINTTL(jmp_pc, CPUOpenRISCState),
         VMSTATE_UINTTL(lock_addr, CPUOpenRISCState),
diff --git a/target/openrisc/sys_helper.c b/target/openrisc/sys_helper.c
index 9841a5b..0968901 100644
--- a/target/openrisc/sys_helper.c
+++ b/target/openrisc/sys_helper.c
@@ -29,11 +29,10 @@ void HELPER(mtspr)(CPUOpenRISCState *env,
                    target_ulong ra, target_ulong rb, target_ulong offset)
 {
 #ifndef CONFIG_USER_ONLY
-    int spr = (ra | offset);
-    int idx;
-
     OpenRISCCPU *cpu = openrisc_env_get_cpu(env);
     CPUState *cs = CPU(cpu);
+    int spr = (ra | offset);
+    int idx;
 
     switch (spr) {
     case TO_SPR(0, 0): /* VR */
@@ -41,7 +40,14 @@ void HELPER(mtspr)(CPUOpenRISCState *env,
         break;
 
     case TO_SPR(0, 16): /* NPC */
-        env->npc = rb;
+        cpu_restore_state(cs, GETPC());
+        /* ??? Mirror or1ksim in not trashing delayed branch state
+           when "jumping" to the current instruction.  */
+        if (env->pc != rb) {
+            env->pc = rb;
+            env->flags = 0;
+            cpu_loop_exit(cs);
+        }
         break;
 
     case TO_SPR(0, 17): /* SR */
@@ -170,7 +176,6 @@ void HELPER(mtspr)(CPUOpenRISCState *env,
         cpu_openrisc_timer_update(cpu);
         break;
     default:
-
         break;
     }
 #endif
@@ -180,11 +185,11 @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env,
                            target_ulong rd, target_ulong ra, uint32_t offset)
 {
 #ifndef CONFIG_USER_ONLY
+    OpenRISCCPU *cpu = openrisc_env_get_cpu(env);
+    CPUState *cs = CPU(cpu);
     int spr = (ra | offset);
     int idx;
 
-    OpenRISCCPU *cpu = openrisc_env_get_cpu(env);
-
     switch (spr) {
     case TO_SPR(0, 0): /* VR */
         return env->vr & SPR_VR;
@@ -201,13 +206,15 @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env,
     case TO_SPR(0, 4): /* IMMUCFGR */
         return env->immucfgr;
 
-    case TO_SPR(0, 16): /* NPC */
-        return env->npc;
+    case TO_SPR(0, 16): /* NPC (equals PC) */
+        cpu_restore_state(cs, GETPC());
+        return env->pc;
 
     case TO_SPR(0, 17): /* SR */
         return cpu_get_sr(env);
 
     case TO_SPR(0, 18): /* PPC */
+        cpu_restore_state(cs, GETPC());
         return env->ppc;
 
     case TO_SPR(0, 32): /* EPCR */
@@ -276,25 +283,6 @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env,
     }
 #endif
 
-/*If we later need to add tracepoints (or debug printfs) for the return
-value, it may be useful to structure the code like this:
-
-target_ulong ret = 0;
-
-switch() {
-case x:
- ret = y;
- break;
-case z:
- ret = 42;
- break;
-...
-}
-
-later something like trace_spr_read(ret);
-
-return ret;*/
-
     /* for rd is passed in, if rd unchanged, just keep it back.  */
     return rd;
 }
diff --git a/target/openrisc/translate.c b/target/openrisc/translate.c
index cda84b6..10f0633 100644
--- a/target/openrisc/translate.c
+++ b/target/openrisc/translate.c
@@ -39,7 +39,7 @@
 
 typedef struct DisasContext {
     TranslationBlock *tb;
-    target_ulong pc, ppc, npc;
+    target_ulong pc;
     uint32_t tb_flags, synced_flags, flags;
     uint32_t is_jmp;
     uint32_t mem_idx;
@@ -52,7 +52,6 @@ static TCGv cpu_sr;
 static TCGv cpu_R[32];
 static TCGv cpu_pc;
 static TCGv jmp_pc;            /* l.jr/l.jalr temp pc */
-static TCGv cpu_npc;
 static TCGv cpu_ppc;
 static TCGv cpu_sr_f;           /* bf/bnf, F flag taken */
 static TCGv cpu_sr_cy;          /* carry (unsigned overflow) */
@@ -83,8 +82,6 @@ void openrisc_translate_init(void)
                                        "flags");
     cpu_pc = tcg_global_mem_new(cpu_env,
                                 offsetof(CPUOpenRISCState, pc), "pc");
-    cpu_npc = tcg_global_mem_new(cpu_env,
-                                 offsetof(CPUOpenRISCState, npc), "npc");
     cpu_ppc = tcg_global_mem_new(cpu_env,
                                  offsetof(CPUOpenRISCState, ppc), "ppc");
     jmp_pc = tcg_global_mem_new(cpu_env,
@@ -1514,7 +1511,6 @@ void gen_intermediate_code(CPUOpenRISCState *env, struct TranslationBlock *tb)
     dc->tb = tb;
 
     dc->is_jmp = DISAS_NEXT;
-    dc->ppc = pc_start;
     dc->pc = pc_start;
     dc->flags = cpu->env.cpucfgr;
     dc->mem_idx = cpu_mmu_index(&cpu->env, false);
@@ -1543,7 +1539,7 @@ void gen_intermediate_code(CPUOpenRISCState *env, struct TranslationBlock *tb)
     gen_tb_start(tb);
 
     do {
-        tcg_gen_insn_start(dc->pc);
+        tcg_gen_insn_start(dc->pc, num_insns != 0);
         num_insns++;
 
         if (unlikely(cpu_breakpoint_test(cs, dc->pc, BP_ANY))) {
@@ -1561,12 +1557,9 @@ void gen_intermediate_code(CPUOpenRISCState *env, struct TranslationBlock *tb)
         if (num_insns == max_insns && (tb->cflags & CF_LAST_IO)) {
             gen_io_start();
         }
-        dc->ppc = dc->pc - 4;
-        dc->npc = dc->pc + 4;
-        tcg_gen_movi_tl(cpu_ppc, dc->ppc);
-        tcg_gen_movi_tl(cpu_npc, dc->npc);
         disas_openrisc_insn(dc, cpu);
-        dc->pc = dc->npc;
+        dc->pc = dc->pc + 4;
+
         /* delay slot */
         if (dc->delayed_branch) {
             dc->delayed_branch--;
@@ -1574,10 +1567,8 @@ void gen_intermediate_code(CPUOpenRISCState *env, struct TranslationBlock *tb)
                 dc->tb_flags &= ~D_FLAG;
                 gen_sync_flags(dc);
                 tcg_gen_mov_tl(cpu_pc, jmp_pc);
-                tcg_gen_mov_tl(cpu_npc, jmp_pc);
-                tcg_gen_movi_tl(jmp_pc, 0);
-                tcg_gen_exit_tb(0);
-                dc->is_jmp = DISAS_JUMP;
+                tcg_gen_discard_tl(jmp_pc);
+                dc->is_jmp = DISAS_UPDATE;
                 break;
             }
         }
@@ -1591,14 +1582,13 @@ void gen_intermediate_code(CPUOpenRISCState *env, struct TranslationBlock *tb)
     if (tb->cflags & CF_LAST_IO) {
         gen_io_end();
     }
+
+    tcg_gen_movi_tl(cpu_ppc, dc->pc - 4);
     if (dc->is_jmp == DISAS_NEXT) {
         dc->is_jmp = DISAS_UPDATE;
         tcg_gen_movi_tl(cpu_pc, dc->pc);
     }
     if (unlikely(cs->singlestep_enabled)) {
-        if (dc->is_jmp == DISAS_NEXT) {
-            tcg_gen_movi_tl(cpu_pc, dc->pc);
-        }
         gen_exception(dc, EXCP_DEBUG);
     } else {
         switch (dc->is_jmp) {
@@ -1651,4 +1641,7 @@ void restore_state_to_opc(CPUOpenRISCState *env, TranslationBlock *tb,
                           target_ulong *data)
 {
     env->pc = data[0];
+    if (data[1]) {
+        env->ppc = env->pc - 4;
+    }
 }
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Qemu-devel] [PATCH 22/22] target/openrisc: Tidy handling of delayed branches
  2017-02-09  4:51 [Qemu-devel] [PATCH 00/22] target/openrisc updates Richard Henderson
                   ` (19 preceding siblings ...)
  2017-02-09  4:51 ` [Qemu-devel] [PATCH 21/22] target/openrisc: Tidy ppc/npc implementation Richard Henderson
@ 2017-02-09  4:51 ` Richard Henderson
  2017-02-10  0:01 ` [Qemu-devel] [PATCH 23/22] linux-user: Honor CLONE_SETTLS for openrisc Richard Henderson
  21 siblings, 0 replies; 30+ messages in thread
From: Richard Henderson @ 2017-02-09  4:51 UTC (permalink / raw)
  To: qemu-devel; +Cc: shorne

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 target/openrisc/cpu.h        | 12 +++++-------
 target/openrisc/gdbstub.c    |  2 +-
 target/openrisc/interrupt.c  |  4 ++--
 target/openrisc/sys_helper.c |  2 +-
 target/openrisc/translate.c  | 40 ++++++++++++++++------------------------
 5 files changed, 25 insertions(+), 35 deletions(-)

diff --git a/target/openrisc/cpu.h b/target/openrisc/cpu.h
index b3d43e1..e3a7782 100644
--- a/target/openrisc/cpu.h
+++ b/target/openrisc/cpu.h
@@ -83,9 +83,6 @@ enum {
 /* Version Register */
 #define SPR_VR 0xFFFF003F
 
-/* Internal flags, delay slot flag */
-#define D_FLAG    1
-
 /* Interrupt */
 #define NR_IRQS  32
 
@@ -298,8 +295,7 @@ typedef struct CPUOpenRISCState {
     target_ulong lock_addr;
     target_ulong lock_value;
 
-    uint32_t flags;           /* cpu_flags, we only use it for exception
-                                 in solt so far.  */
+    uint32_t dflag;           /* In delay slot (boolean) */
 
     /* Fields up to this point are cleared by a CPU reset */
     struct {} end_reset_fields;
@@ -392,14 +388,16 @@ int cpu_openrisc_get_phys_data(OpenRISCCPU *cpu,
 
 #include "exec/cpu-all.h"
 
+#define TB_FLAGS_DFLAG 1
+#define TB_FLAGS_OVE   SR_OVE
+
 static inline void cpu_get_tb_cpu_state(CPUOpenRISCState *env,
                                         target_ulong *pc,
                                         target_ulong *cs_base, uint32_t *flags)
 {
     *pc = env->pc;
     *cs_base = 0;
-    /* D_FLAG -- branch instruction exception, OVE overflow trap enable.  */
-    *flags = (env->flags & D_FLAG) | (env->sr & SR_OVE);
+    *flags = env->dflag | (env->sr & SR_OVE);
 }
 
 static inline int cpu_mmu_index(CPUOpenRISCState *env, bool ifetch)
diff --git a/target/openrisc/gdbstub.c b/target/openrisc/gdbstub.c
index 2a4821f..b18c7e9 100644
--- a/target/openrisc/gdbstub.c
+++ b/target/openrisc/gdbstub.c
@@ -73,7 +73,7 @@ int openrisc_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
                also clear delayed branch status.  */
             if (env->pc != tmp) {
                 env->pc = tmp;
-                env->flags = 0;
+                env->dflag = 0;
             }
             break;
 
diff --git a/target/openrisc/interrupt.c b/target/openrisc/interrupt.c
index 042506f..a2eec6f 100644
--- a/target/openrisc/interrupt.c
+++ b/target/openrisc/interrupt.c
@@ -34,8 +34,8 @@ void openrisc_cpu_do_interrupt(CPUState *cs)
     CPUOpenRISCState *env = &cpu->env;
 
     env->epcr = env->pc;
-    if (env->flags & D_FLAG) {
-        env->flags &= ~D_FLAG;
+    if (env->dflag) {
+        env->dflag = 0;
         env->sr |= SR_DSX;
         env->epcr -= 4;
     } else {
diff --git a/target/openrisc/sys_helper.c b/target/openrisc/sys_helper.c
index 0968901..60c3193 100644
--- a/target/openrisc/sys_helper.c
+++ b/target/openrisc/sys_helper.c
@@ -45,7 +45,7 @@ void HELPER(mtspr)(CPUOpenRISCState *env,
            when "jumping" to the current instruction.  */
         if (env->pc != rb) {
             env->pc = rb;
-            env->flags = 0;
+            env->dflag = 0;
             cpu_loop_exit(cs);
         }
         break;
diff --git a/target/openrisc/translate.c b/target/openrisc/translate.c
index 10f0633..313dae2 100644
--- a/target/openrisc/translate.c
+++ b/target/openrisc/translate.c
@@ -40,11 +40,11 @@
 typedef struct DisasContext {
     TranslationBlock *tb;
     target_ulong pc;
-    uint32_t tb_flags, synced_flags, flags;
     uint32_t is_jmp;
     uint32_t mem_idx;
-    int singlestep_enabled;
+    uint32_t tb_flags;
     uint32_t delayed_branch;
+    bool singlestep_enabled;
 } DisasContext;
 
 static TCGv_env cpu_env;
@@ -60,7 +60,7 @@ static TCGv cpu_lock_addr;
 static TCGv cpu_lock_value;
 static TCGv_i32 fpcsr;
 static TCGv_i64 cpu_mac;        /* MACHI:MACLO */
-static TCGv_i32 env_flags;
+static TCGv_i32 cpu_dflag;
 #include "exec/gen-icount.h"
 
 void openrisc_translate_init(void)
@@ -77,9 +77,9 @@ void openrisc_translate_init(void)
     tcg_ctx.tcg_env = cpu_env;
     cpu_sr = tcg_global_mem_new(cpu_env,
                                 offsetof(CPUOpenRISCState, sr), "sr");
-    env_flags = tcg_global_mem_new_i32(cpu_env,
-                                       offsetof(CPUOpenRISCState, flags),
-                                       "flags");
+    cpu_dflag = tcg_global_mem_new_i32(cpu_env,
+                                       offsetof(CPUOpenRISCState, dflag),
+                                       "dflag");
     cpu_pc = tcg_global_mem_new(cpu_env,
                                 offsetof(CPUOpenRISCState, pc), "pc");
     cpu_ppc = tcg_global_mem_new(cpu_env,
@@ -111,15 +111,6 @@ void openrisc_translate_init(void)
     }
 }
 
-static inline void gen_sync_flags(DisasContext *dc)
-{
-    /* Sync the tb dependent flag between translate and runtime.  */
-    if ((dc->tb_flags ^ dc->synced_flags) & D_FLAG) {
-        tcg_gen_movi_tl(env_flags, dc->tb_flags & D_FLAG);
-        dc->synced_flags = dc->tb_flags;
-    }
-}
-
 static void gen_exception(DisasContext *dc, unsigned int excp)
 {
     TCGv_i32 tmp = tcg_const_i32(excp);
@@ -230,8 +221,6 @@ static void gen_jump(DisasContext *dc, int32_t n26, uint32_t reg, uint32_t op0)
     }
 
     dc->delayed_branch = 2;
-    dc->tb_flags |= D_FLAG;
-    gen_sync_flags(dc);
 }
 
 static void gen_ove_cy(DisasContext *dc)
@@ -1512,10 +1501,9 @@ void gen_intermediate_code(CPUOpenRISCState *env, struct TranslationBlock *tb)
 
     dc->is_jmp = DISAS_NEXT;
     dc->pc = pc_start;
-    dc->flags = cpu->env.cpucfgr;
     dc->mem_idx = cpu_mmu_index(&cpu->env, false);
-    dc->synced_flags = dc->tb_flags = tb->flags;
-    dc->delayed_branch = (dc->tb_flags & D_FLAG) != 0;
+    dc->tb_flags = tb->flags;
+    dc->delayed_branch = (dc->tb_flags & TB_FLAGS_DFLAG) != 0;
     dc->singlestep_enabled = cs->singlestep_enabled;
 
     next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
@@ -1539,7 +1527,8 @@ void gen_intermediate_code(CPUOpenRISCState *env, struct TranslationBlock *tb)
     gen_tb_start(tb);
 
     do {
-        tcg_gen_insn_start(dc->pc, num_insns != 0);
+        tcg_gen_insn_start(dc->pc, (dc->delayed_branch ? 1 : 0)
+			   | (num_insns ? 2 : 0));
         num_insns++;
 
         if (unlikely(cpu_breakpoint_test(cs, dc->pc, BP_ANY))) {
@@ -1564,8 +1553,6 @@ void gen_intermediate_code(CPUOpenRISCState *env, struct TranslationBlock *tb)
         if (dc->delayed_branch) {
             dc->delayed_branch--;
             if (!dc->delayed_branch) {
-                dc->tb_flags &= ~D_FLAG;
-                gen_sync_flags(dc);
                 tcg_gen_mov_tl(cpu_pc, jmp_pc);
                 tcg_gen_discard_tl(jmp_pc);
                 dc->is_jmp = DISAS_UPDATE;
@@ -1583,6 +1570,10 @@ void gen_intermediate_code(CPUOpenRISCState *env, struct TranslationBlock *tb)
         gen_io_end();
     }
 
+    if ((dc->tb_flags & TB_FLAGS_DFLAG ? 1 : 0) != (dc->delayed_branch != 0)) {
+        tcg_gen_movi_i32(cpu_dflag, dc->delayed_branch != 0);
+    }
+
     tcg_gen_movi_tl(cpu_ppc, dc->pc - 4);
     if (dc->is_jmp == DISAS_NEXT) {
         dc->is_jmp = DISAS_UPDATE;
@@ -1641,7 +1632,8 @@ void restore_state_to_opc(CPUOpenRISCState *env, TranslationBlock *tb,
                           target_ulong *data)
 {
     env->pc = data[0];
-    if (data[1]) {
+    env->dflag = data[1] & 1;
+    if (data[1] & 2) {
         env->ppc = env->pc - 4;
     }
 }
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* Re: [Qemu-devel] [PATCH 06/22] target/openrisc: Tidy insn dumping
  2017-02-09  4:51 ` [Qemu-devel] [PATCH 06/22] target/openrisc: Tidy insn dumping Richard Henderson
@ 2017-02-09  5:14   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 30+ messages in thread
From: Philippe Mathieu-Daudé @ 2017-02-09  5:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: Richard Henderson, shorne



On 02/09/2017 01:51 AM, Richard Henderson wrote:
> Avoids warnings from unused variables etc.
>
> Reviewed-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
> Signed-off-by: Richard Henderson <rth@twiddle.net>

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>

> ---
>  target/openrisc/translate.c | 36 ++++++++++++------------------------
>  1 file changed, 12 insertions(+), 24 deletions(-)
>
> diff --git a/target/openrisc/translate.c b/target/openrisc/translate.c
> index c207875..ac0c409 100644
> --- a/target/openrisc/translate.c
> +++ b/target/openrisc/translate.c
> @@ -34,14 +34,8 @@
>  #include "trace-tcg.h"
>  #include "exec/log.h"
>
> -
> -#define OPENRISC_DISAS
> -
> -#ifdef OPENRISC_DISAS
> -#  define LOG_DIS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__)
> -#else
> -#  define LOG_DIS(...) do { } while (0)
> -#endif
> +#define LOG_DIS(str, ...) \
> +    qemu_log_mask(CPU_LOG_TB_IN_ASM, "%08x: " str, dc->pc, ## __VA_ARGS__)
>
>  typedef struct DisasContext {
>      TranslationBlock *tb;
> @@ -766,9 +760,7 @@ static void dec_misc(DisasContext *dc, uint32_t insn)
>  {
>      uint32_t op0, op1;
>      uint32_t ra, rb, rd;
> -#ifdef OPENRISC_DISAS
>      uint32_t L6, K5;
> -#endif
>      uint32_t I16, I5, I11, N26, tmp;
>      TCGMemOp mop;
>
> @@ -777,10 +769,8 @@ static void dec_misc(DisasContext *dc, uint32_t insn)
>      ra = extract32(insn, 16, 5);
>      rb = extract32(insn, 11, 5);
>      rd = extract32(insn, 21, 5);
> -#ifdef OPENRISC_DISAS
>      L6 = extract32(insn, 5, 6);
>      K5 = extract32(insn, 0, 5);
> -#endif
>      I16 = extract32(insn, 0, 16);
>      I5 = extract32(insn, 21, 5);
>      I11 = extract32(insn, 0, 11);
> @@ -1387,13 +1377,10 @@ static void dec_compi(DisasContext *dc, uint32_t insn)
>  static void dec_sys(DisasContext *dc, uint32_t insn)
>  {
>      uint32_t op0;
> -#ifdef OPENRISC_DISAS
>      uint32_t K16;
> -#endif
> +
>      op0 = extract32(insn, 16, 10);
> -#ifdef OPENRISC_DISAS
>      K16 = extract32(insn, 0, 16);
> -#endif
>
>      switch (op0) {
>      case 0x000:    /* l.sys */
> @@ -1723,6 +1710,13 @@ void gen_intermediate_code(CPUOpenRISCState *env, struct TranslationBlock *tb)
>          max_insns = TCG_MAX_INSNS;
>      }
>
> +    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
> +        && qemu_log_in_addr_range(pc_start)) {
> +        qemu_log_lock();
> +        qemu_log("----------------\n");
> +        qemu_log("IN: %s\n", lookup_symbol(pc_start));
> +    }
> +
>      gen_tb_start(tb);
>
>      do {
> @@ -1807,18 +1801,12 @@ void gen_intermediate_code(CPUOpenRISCState *env, struct TranslationBlock *tb)
>      tb->size = dc->pc - pc_start;
>      tb->icount = num_insns;
>
> -#ifdef DEBUG_DISAS
>      if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
>          && qemu_log_in_addr_range(pc_start)) {
> -        qemu_log_lock();
> -        qemu_log("----------------\n");
> -        qemu_log("IN: %s\n", lookup_symbol(pc_start));
> -        log_target_disas(cs, pc_start, dc->pc - pc_start, 0);
> -        qemu_log("\nisize=%d osize=%d\n",
> -                 dc->pc - pc_start, tcg_op_buf_count());
> +        log_target_disas(cs, pc_start, tb->size, 0);
> +        qemu_log("\n");
>          qemu_log_unlock();
>      }
> -#endif
>  }
>
>  void openrisc_cpu_dump_state(CPUState *cs, FILE *f,
>

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [Qemu-devel] [PATCH 14/22] target/openrisc: Set flags on helpers
  2017-02-09  4:51 ` [Qemu-devel] [PATCH 14/22] target/openrisc: Set flags on helpers Richard Henderson
@ 2017-02-09  5:16   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 30+ messages in thread
From: Philippe Mathieu-Daudé @ 2017-02-09  5:16 UTC (permalink / raw)
  To: qemu-devel; +Cc: Richard Henderson, shorne



On 02/09/2017 01:51 AM, Richard Henderson wrote:
> Reviewed-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
> Signed-off-by: Richard Henderson <rth@twiddle.net>

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>

> ---
>  target/openrisc/helper.h | 24 ++++++++++++------------
>  1 file changed, 12 insertions(+), 12 deletions(-)
>
> diff --git a/target/openrisc/helper.h b/target/openrisc/helper.h
> index f4d97a2..78a123d 100644
> --- a/target/openrisc/helper.h
> +++ b/target/openrisc/helper.h
> @@ -18,26 +18,26 @@
>   */
>
>  /* exception */
> -DEF_HELPER_FLAGS_2(exception, 0, void, env, i32)
> +DEF_HELPER_FLAGS_2(exception, TCG_CALL_NO_WG, void, env, i32)
>  DEF_HELPER_FLAGS_1(ove_cy, TCG_CALL_NO_WG, void, env)
>  DEF_HELPER_FLAGS_1(ove_ov, TCG_CALL_NO_WG, void, env)
>  DEF_HELPER_FLAGS_1(ove_cyov, TCG_CALL_NO_WG, void, env)
>
>  /* float */
> -DEF_HELPER_FLAGS_2(itofd, 0, i64, env, i64)
> -DEF_HELPER_FLAGS_2(itofs, 0, i32, env, i32)
> -DEF_HELPER_FLAGS_2(ftoid, 0, i64, env, i64)
> -DEF_HELPER_FLAGS_2(ftois, 0, i32, env, i32)
> +DEF_HELPER_FLAGS_2(itofd, TCG_CALL_NO_WG, i64, env, i64)
> +DEF_HELPER_FLAGS_2(itofs, TCG_CALL_NO_WG, i32, env, i32)
> +DEF_HELPER_FLAGS_2(ftoid, TCG_CALL_NO_WG, i64, env, i64)
> +DEF_HELPER_FLAGS_2(ftois, TCG_CALL_NO_WG, i32, env, i32)
>
>  #define FOP_MADD(op)                                             \
> -DEF_HELPER_FLAGS_3(float_ ## op ## _s, 0, i32, env, i32, i32)    \
> -DEF_HELPER_FLAGS_3(float_ ## op ## _d, 0, i64, env, i64, i64)
> +DEF_HELPER_FLAGS_3(float_ ## op ## _s, TCG_CALL_NO_WG, i32, env, i32, i32) \
> +DEF_HELPER_FLAGS_3(float_ ## op ## _d, TCG_CALL_NO_WG, i64, env, i64, i64)
>  FOP_MADD(muladd)
>  #undef FOP_MADD
>
>  #define FOP_CALC(op)                                            \
> -DEF_HELPER_FLAGS_3(float_ ## op ## _s, 0, i32, env, i32, i32)    \
> -DEF_HELPER_FLAGS_3(float_ ## op ## _d, 0, i64, env, i64, i64)
> +DEF_HELPER_FLAGS_3(float_ ## op ## _s, TCG_CALL_NO_WG, i32, env, i32, i32) \
> +DEF_HELPER_FLAGS_3(float_ ## op ## _d, TCG_CALL_NO_WG, i64, env, i64, i64)
>  FOP_CALC(add)
>  FOP_CALC(sub)
>  FOP_CALC(mul)
> @@ -46,8 +46,8 @@ FOP_CALC(rem)
>  #undef FOP_CALC
>
>  #define FOP_CMP(op)                                              \
> -DEF_HELPER_FLAGS_3(float_ ## op ## _s, 0, i32, env, i32, i32)    \
> -DEF_HELPER_FLAGS_3(float_ ## op ## _d, 0, i64, env, i64, i64)
> +DEF_HELPER_FLAGS_3(float_ ## op ## _s, TCG_CALL_NO_WG, i32, env, i32, i32) \
> +DEF_HELPER_FLAGS_3(float_ ## op ## _d, TCG_CALL_NO_WG, i64, env, i64, i64)
>  FOP_CMP(eq)
>  FOP_CMP(lt)
>  FOP_CMP(le)
> @@ -61,4 +61,4 @@ DEF_HELPER_FLAGS_1(rfe, 0, void, env)
>
>  /* sys */
>  DEF_HELPER_FLAGS_4(mtspr, 0, void, env, tl, tl, tl)
> -DEF_HELPER_FLAGS_4(mfspr, 0, tl, env, tl, tl, tl)
> +DEF_HELPER_FLAGS_4(mfspr, TCG_CALL_NO_WG, tl, env, tl, tl, tl)
>

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [Qemu-devel] [PATCH 20/22] target/openrisc: Optimize l.jal to next
  2017-02-09  4:51 ` [Qemu-devel] [PATCH 20/22] target/openrisc: Optimize l.jal to next Richard Henderson
@ 2017-02-09  5:20   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 30+ messages in thread
From: Philippe Mathieu-Daudé @ 2017-02-09  5:20 UTC (permalink / raw)
  To: qemu-devel; +Cc: Richard Henderson, shorne



On 02/09/2017 01:51 AM, Richard Henderson wrote:
> This allows the tcg optimizer to see, and fold, all of the
> constants involved in a GOT base register load sequence.
>
> Signed-off-by: Richard Henderson <rth@twiddle.net>

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>

> ---
>  target/openrisc/translate.c | 6 +++++-
>  1 file changed, 5 insertions(+), 1 deletion(-)
>
> diff --git a/target/openrisc/translate.c b/target/openrisc/translate.c
> index 66064e1..cda84b6 100644
> --- a/target/openrisc/translate.c
> +++ b/target/openrisc/translate.c
> @@ -198,7 +198,11 @@ static void gen_jump(DisasContext *dc, int32_t n26, uint32_t reg, uint32_t op0)
>          tcg_gen_movi_tl(jmp_pc, tmp_pc);
>          break;
>      case 0x01:     /* l.jal */
> -        tcg_gen_movi_tl(cpu_R[9], (dc->pc + 8));
> +        tcg_gen_movi_tl(cpu_R[9], dc->pc + 8);
> +        /* Optimize jal being used to load the PC for PIC.  */
> +        if (tmp_pc == dc->pc + 8) {
> +            return;
> +        }
>          tcg_gen_movi_tl(jmp_pc, tmp_pc);
>          break;
>      case 0x03:     /* l.bnf */
>

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [Qemu-devel] [PATCH 15/22] target/openrisc: Enable trap, csync, msync, psync for user mode
  2017-02-09  4:51 ` [Qemu-devel] [PATCH 15/22] target/openrisc: Enable trap, csync, msync, psync for user mode Richard Henderson
@ 2017-02-09  5:24   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 30+ messages in thread
From: Philippe Mathieu-Daudé @ 2017-02-09  5:24 UTC (permalink / raw)
  To: qemu-devel; +Cc: Richard Henderson, shorne

On 02/09/2017 01:51 AM, Richard Henderson wrote:
> Not documented as disabled for user mode.
>
> Reviewed-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
> Signed-off-by: Richard Henderson <rth@twiddle.net>

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>

> ---
>  target/openrisc/translate.c | 32 --------------------------------
>  1 file changed, 32 deletions(-)
>
> diff --git a/target/openrisc/translate.c b/target/openrisc/translate.c
> index f91ab6a..6c8f05c 100644
> --- a/target/openrisc/translate.c
> +++ b/target/openrisc/translate.c
> @@ -1134,52 +1134,20 @@ static void dec_sys(DisasContext *dc, uint32_t insn)
>
>      case 0x100:    /* l.trap */
>          LOG_DIS("l.trap %d\n", K16);
> -#if defined(CONFIG_USER_ONLY)
> -        return;
> -#else
> -        if (dc->mem_idx == MMU_USER_IDX) {
> -            gen_illegal_exception(dc);
> -            return;
> -        }
>          tcg_gen_movi_tl(cpu_pc, dc->pc);
>          gen_exception(dc, EXCP_TRAP);
> -#endif
>          break;
>
>      case 0x300:    /* l.csync */
>          LOG_DIS("l.csync\n");
> -#if defined(CONFIG_USER_ONLY)
> -        return;
> -#else
> -        if (dc->mem_idx == MMU_USER_IDX) {
> -            gen_illegal_exception(dc);
> -            return;
> -        }
> -#endif
>          break;
>
>      case 0x200:    /* l.msync */
>          LOG_DIS("l.msync\n");
> -#if defined(CONFIG_USER_ONLY)
> -        return;
> -#else
> -        if (dc->mem_idx == MMU_USER_IDX) {
> -            gen_illegal_exception(dc);
> -            return;
> -        }
> -#endif
>          break;
>
>      case 0x270:    /* l.psync */
>          LOG_DIS("l.psync\n");
> -#if defined(CONFIG_USER_ONLY)
> -        return;
> -#else
> -        if (dc->mem_idx == MMU_USER_IDX) {
> -            gen_illegal_exception(dc);
> -            return;
> -        }
> -#endif
>          break;
>
>      default:
>

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [Qemu-devel] [PATCH 23/22] linux-user: Honor CLONE_SETTLS for openrisc
  2017-02-09  4:51 [Qemu-devel] [PATCH 00/22] target/openrisc updates Richard Henderson
                   ` (20 preceding siblings ...)
  2017-02-09  4:51 ` [Qemu-devel] [PATCH 22/22] target/openrisc: Tidy handling of delayed branches Richard Henderson
@ 2017-02-10  0:01 ` Richard Henderson
  2017-02-10  0:44     ` [OpenRISC] " Stafford Horne
  21 siblings, 1 reply; 30+ messages in thread
From: Richard Henderson @ 2017-02-10  0:01 UTC (permalink / raw)
  To: qemu-devel; +Cc: shorne

Threads work much better when you set the TLS register.
This was fixed in the upstream kernel for Linux 4.9.

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 linux-user/openrisc/target_cpu.h | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/linux-user/openrisc/target_cpu.h b/linux-user/openrisc/target_cpu.h
index a21ed1a..f283d96 100644
--- a/linux-user/openrisc/target_cpu.h
+++ b/linux-user/openrisc/target_cpu.h
@@ -30,9 +30,7 @@ static inline void cpu_clone_regs(CPUOpenRISCState *env, target_ulong newsp)
 
 static inline void cpu_set_tls(CPUOpenRISCState *env, target_ulong newtls)
 {
-    /* Linux kernel 3.10 does not pay any attention to CLONE_SETTLS
-     * in copy_thread(), so QEMU need not do so either.
-     */
+    env->gpr[10] = newtls;
 }
 
 #endif
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* Re: [Qemu-devel] [PATCH 23/22] linux-user: Honor CLONE_SETTLS for openrisc
  2017-02-10  0:01 ` [Qemu-devel] [PATCH 23/22] linux-user: Honor CLONE_SETTLS for openrisc Richard Henderson
@ 2017-02-10  0:44     ` Stafford Horne
  0 siblings, 0 replies; 30+ messages in thread
From: Stafford Horne @ 2017-02-10  0:44 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-devel, Openrisc

23/22 ?

:)

On Fri, Feb 10, 2017 at 10:01:22AM +1000, Richard Henderson wrote:
> Threads work much better when you set the TLS register.
> This was fixed in the upstream kernel for Linux 4.9.
> 
> Signed-off-by: Richard Henderson <rth@twiddle.net>
> ---
>  linux-user/openrisc/target_cpu.h | 4 +---
>  1 file changed, 1 insertion(+), 3 deletions(-)
> 
> diff --git a/linux-user/openrisc/target_cpu.h b/linux-user/openrisc/target_cpu.h
> index a21ed1a..f283d96 100644
> --- a/linux-user/openrisc/target_cpu.h
> +++ b/linux-user/openrisc/target_cpu.h
> @@ -30,9 +30,7 @@ static inline void cpu_clone_regs(CPUOpenRISCState *env, target_ulong newsp)
>  
>  static inline void cpu_set_tls(CPUOpenRISCState *env, target_ulong newtls)
>  {
> -    /* Linux kernel 3.10 does not pay any attention to CLONE_SETTLS
> -     * in copy_thread(), so QEMU need not do so either.
> -     */
> +    env->gpr[10] = newtls;
>  }
>  
>  #endif
> -- 
> 2.9.3
> 

Reviewed-by: Stafford Horne <shorne@gmail.com>

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [OpenRISC] [PATCH 23/22] linux-user: Honor CLONE_SETTLS for openrisc
@ 2017-02-10  0:44     ` Stafford Horne
  0 siblings, 0 replies; 30+ messages in thread
From: Stafford Horne @ 2017-02-10  0:44 UTC (permalink / raw)
  To: openrisc

23/22 ?

:)

On Fri, Feb 10, 2017 at 10:01:22AM +1000, Richard Henderson wrote:
> Threads work much better when you set the TLS register.
> This was fixed in the upstream kernel for Linux 4.9.
> 
> Signed-off-by: Richard Henderson <rth@twiddle.net>
> ---
>  linux-user/openrisc/target_cpu.h | 4 +---
>  1 file changed, 1 insertion(+), 3 deletions(-)
> 
> diff --git a/linux-user/openrisc/target_cpu.h b/linux-user/openrisc/target_cpu.h
> index a21ed1a..f283d96 100644
> --- a/linux-user/openrisc/target_cpu.h
> +++ b/linux-user/openrisc/target_cpu.h
> @@ -30,9 +30,7 @@ static inline void cpu_clone_regs(CPUOpenRISCState *env, target_ulong newsp)
>  
>  static inline void cpu_set_tls(CPUOpenRISCState *env, target_ulong newtls)
>  {
> -    /* Linux kernel 3.10 does not pay any attention to CLONE_SETTLS
> -     * in copy_thread(), so QEMU need not do so either.
> -     */
> +    env->gpr[10] = newtls;
>  }
>  
>  #endif
> -- 
> 2.9.3
> 

Reviewed-by: Stafford Horne <shorne@gmail.com>

^ permalink raw reply	[flat|nested] 30+ messages in thread

end of thread, other threads:[~2017-02-10  0:44 UTC | newest]

Thread overview: 30+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-02-09  4:51 [Qemu-devel] [PATCH 00/22] target/openrisc updates Richard Henderson
2017-02-09  4:51 ` [Qemu-devel] [PATCH 01/22] target/openrisc: Rename the cpu from or32 to or1k Richard Henderson
2017-02-09  4:51 ` [Qemu-devel] [PATCH 03/22] linux-user: Fix openrisc cpu_loop Richard Henderson
2017-02-09  4:51 ` [Qemu-devel] [PATCH 04/22] target/openrisc: Fix exception handling status registers Richard Henderson
2017-02-09  4:51   ` [OpenRISC] " Richard Henderson
2017-02-09  4:51 ` [Qemu-devel] [PATCH 05/22] target/openrisc: Implement lwa, swa Richard Henderson
2017-02-09  4:51 ` [Qemu-devel] [PATCH 06/22] target/openrisc: Tidy insn dumping Richard Henderson
2017-02-09  5:14   ` Philippe Mathieu-Daudé
2017-02-09  4:51 ` [Qemu-devel] [PATCH 07/22] target/openrisc: Rationalize immediate extraction Richard Henderson
2017-02-09  4:51 ` [Qemu-devel] [PATCH 08/22] target/openrisc: Streamline arithmetic and OVE Richard Henderson
2017-02-09  4:51 ` [Qemu-devel] [PATCH 09/22] target/openrisc: Put SR[OVE] in TB flags Richard Henderson
2017-02-09  4:51 ` [Qemu-devel] [PATCH 10/22] target/openrisc: Invert the decoding in dec_calc Richard Henderson
2017-02-09  4:51 ` [Qemu-devel] [PATCH 11/22] target/openrisc: Keep SR_F in a separate variable Richard Henderson
2017-02-09  4:51 ` [Qemu-devel] [PATCH 12/22] target/openrisc: Keep SR_CY and SR_OV in a separate variables Richard Henderson
2017-02-09  4:51 ` [Qemu-devel] [PATCH 13/22] target/openrisc: Use movcond where appropriate Richard Henderson
2017-02-09  4:51 ` [Qemu-devel] [PATCH 14/22] target/openrisc: Set flags on helpers Richard Henderson
2017-02-09  5:16   ` Philippe Mathieu-Daudé
2017-02-09  4:51 ` [Qemu-devel] [PATCH 15/22] target/openrisc: Enable trap, csync, msync, psync for user mode Richard Henderson
2017-02-09  5:24   ` Philippe Mathieu-Daudé
2017-02-09  4:51 ` [Qemu-devel] [PATCH 16/22] target/openrisc: Implement msync Richard Henderson
2017-02-09  4:51 ` [Qemu-devel] [PATCH 17/22] target/openrisc: Represent MACHI:MACLO as a single unit Richard Henderson
2017-02-09  4:51 ` [Qemu-devel] [PATCH 18/22] target/openrisc: Implement muld, muldu, macu, msbu Richard Henderson
2017-02-09  4:51 ` [Qemu-devel] [PATCH 19/22] target/openrisc: Fix madd Richard Henderson
2017-02-09  4:51 ` [Qemu-devel] [PATCH 20/22] target/openrisc: Optimize l.jal to next Richard Henderson
2017-02-09  5:20   ` Philippe Mathieu-Daudé
2017-02-09  4:51 ` [Qemu-devel] [PATCH 21/22] target/openrisc: Tidy ppc/npc implementation Richard Henderson
2017-02-09  4:51 ` [Qemu-devel] [PATCH 22/22] target/openrisc: Tidy handling of delayed branches Richard Henderson
2017-02-10  0:01 ` [Qemu-devel] [PATCH 23/22] linux-user: Honor CLONE_SETTLS for openrisc Richard Henderson
2017-02-10  0:44   ` Stafford Horne
2017-02-10  0:44     ` [OpenRISC] " Stafford Horne

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.