Re: Call for GSoC/Outreachy internship project ideas

2024-01-30 Thread Palmer Dabbelt

On Mon, 15 Jan 2024 08:32:59 PST (-0800), stefa...@gmail.com wrote:

Dear QEMU and KVM communities,
QEMU will apply for the Google Summer of Code and Outreachy internship
programs again this year. Regular contributors can submit project
ideas that they'd like to mentor by replying to this email before
January 30th.


It's the 30th, sorry if this is late but I just saw it today.  +Alistair 
and Daniel, as I didn't sync up with anyone about this so not sure if 
someone else is looking already (we're not internally).



Internship programs
---
GSoC (https://summerofcode.withgoogle.com/) and Outreachy
(https://www.outreachy.org/) offer paid open source remote work
internships to eligible people wishing to participate in open source
development. QEMU has been part of these internship programs for many
years. Our mentors have enjoyed helping talented interns make their
first open source contributions and some former interns continue to
participate today.

Who can mentor
--
Regular contributors to QEMU and KVM can participate as mentors.
Mentorship involves about 5 hours of time commitment per week to
communicate with the intern, review their patches, etc. Time is also
required during the intern selection phase to communicate with
applicants. Being a mentor is an opportunity to help someone get
started in open source development, will give you experience with
managing a project in a low-stakes environment, and a chance to
explore interesting technical ideas that you may not have time to
develop yourself.

How to propose your idea
--
Reply to this email with the following project idea template filled in:

=== TITLE ===

'''Summary:''' Short description of the project

Detailed description of the project that explains the general idea,
including a list of high-level tasks that will be completed by the
project, and provides enough background for someone unfamiliar with
the codebase to do research. Typically 2 or 3 paragraphs.

'''Links:'''
* Wiki links to relevant material
* External links to mailing lists or web sites

'''Details:'''
* Skill level: beginner or intermediate or advanced
* Language: C/Python/Rust/etc


I'm not 100% sure this is a sane GSoC idea, as it's a bit open ended and 
might have some tricky parts.  That said it's tripping some people up 
and as far as I know nobody's started looking at it, so I figrued I'd 
write something up.


I can try and dig up some more links if folks thing it's interesting, 
IIRC there's been a handful of bug reports related to very small loops 
that run ~10x slower when vectorized.  Large benchmarks like SPEC have 
also shown slowdowns.


---

=== RISC-V Vector TCG Frontend Optimization ===

'''Summary:''' The RISC-V vector extension has been implemented in QEMU, 
but we have some performance pathologies mapping it to existing TCG 
backends.  This project would aim to improve the performance of the 
RISC-V vector ISA's mappings to TCG.


The RISC-V TCG frontend (ie, decoding RISC-V instructions 
and emitting TCG calls to emulate them) has some inefficient mappings to 
TCG, which results in binaries that have vector instructions frequently 
performing worse than those without, sometimes even up to 10x slower.  
This causes various headaches for users, including running toolchain 
regressions and doing distro work.  This project's aim would be to bring 
the performance of vectorized RISC-V code to a similar level as the 
corresponding scalar code.


This will definitely require changing the RISC-V TCG frontend.  It's 
likely there is some remaining optimization work that can be done 
without adding TCG primitives, but it may be necessary to do some core 
TCG work in order to improve performance sufficiently.


'''Links:'''
* https://lists.gnu.org/archive/html/qemu-devel/2023-07/msg04495.html

'''Details'''
* Skill level: intermediate
* Language: C, RISC-V assembly



More information
--
You can find out about the process we follow here:
Video: https://www.youtube.com/watch?v=xNVCX7YMUL8
Slides (PDF): https://vmsplice.net/~stefan/stefanha-kvm-forum-2016.pdf

The QEMU wiki page for GSoC 2024 is now available:
https://wiki.qemu.org/Google_Summer_of_Code_2024

Thanks,
Stefan




Re: Call for GSoC/Outreachy internship project ideas

2024-01-30 Thread Palmer Dabbelt

On Tue, 30 Jan 2024 12:28:27 PST (-0800), stefa...@gmail.com wrote:

On Tue, 30 Jan 2024 at 14:40, Palmer Dabbelt  wrote:


On Mon, 15 Jan 2024 08:32:59 PST (-0800), stefa...@gmail.com wrote:
> Dear QEMU and KVM communities,
> QEMU will apply for the Google Summer of Code and Outreachy internship
> programs again this year. Regular contributors can submit project
> ideas that they'd like to mentor by replying to this email before
> January 30th.

It's the 30th, sorry if this is late but I just saw it today.  +Alistair
and Daniel, as I didn't sync up with anyone about this so not sure if
someone else is looking already (we're not internally).

> Internship programs
> ---
> GSoC (https://summerofcode.withgoogle.com/) and Outreachy
> (https://www.outreachy.org/) offer paid open source remote work
> internships to eligible people wishing to participate in open source
> development. QEMU has been part of these internship programs for many
> years. Our mentors have enjoyed helping talented interns make their
> first open source contributions and some former interns continue to
> participate today.
>
> Who can mentor
> --
> Regular contributors to QEMU and KVM can participate as mentors.
> Mentorship involves about 5 hours of time commitment per week to
> communicate with the intern, review their patches, etc. Time is also
> required during the intern selection phase to communicate with
> applicants. Being a mentor is an opportunity to help someone get
> started in open source development, will give you experience with
> managing a project in a low-stakes environment, and a chance to
> explore interesting technical ideas that you may not have time to
> develop yourself.
>
> How to propose your idea
> --
> Reply to this email with the following project idea template filled in:
>
> === TITLE ===
>
> '''Summary:''' Short description of the project
>
> Detailed description of the project that explains the general idea,
> including a list of high-level tasks that will be completed by the
> project, and provides enough background for someone unfamiliar with
> the codebase to do research. Typically 2 or 3 paragraphs.
>
> '''Links:'''
> * Wiki links to relevant material
> * External links to mailing lists or web sites
>
> '''Details:'''
> * Skill level: beginner or intermediate or advanced
> * Language: C/Python/Rust/etc

I'm not 100% sure this is a sane GSoC idea, as it's a bit open ended and
might have some tricky parts.  That said it's tripping some people up
and as far as I know nobody's started looking at it, so I figrued I'd
write something up.

I can try and dig up some more links if folks thing it's interesting,
IIRC there's been a handful of bug reports related to very small loops
that run ~10x slower when vectorized.  Large benchmarks like SPEC have
also shown slowdowns.


Hi Palmer,
Performance optimization can be challenging for newcomers. I wouldn't
recommend it for a GSoC project unless you have time to seed the
project idea with specific optimizations to implement based on your
experience and profiling. That way the intern has a solid starting
point where they can have a few successes before venturing out to do
their own performance analysis.


Ya, I agree.  That's part of the reason why I wasn't sure if it's a 
good idea.  At least for this one I think there should be some easy to 
understand performance issue, as the loops that go very slowly consist 
of a small number of instructions and go a lot slower.


I'm actually more worried about this running into a rabbit hole of 
adding new TCG operations or even just having no well defined mappings 
between RVV and AVX, those might make the project really hard.



Do you have the time to profile and add specifics to the project idea
by Feb 21st? If that sounds good to you, I'll add it to the project
ideas list and you can add more detailed tasks in the coming weeks.


I can at least dig up some of the examples I ran into, there's been a 
handful filtering in over the last year or so.


This one 
<https://gist.github.com/compnerd/daa7e68f7b4910cb6b27f856e6c2beba> 
still has a much more than 10x slowdown (73ms -> 13s) with 
vectorization, for example.



Thanks,
Stefan




Re: Call for GSoC/Outreachy internship project ideas

2024-01-30 Thread Palmer Dabbelt

On Tue, 30 Jan 2024 17:26:11 PST (-0800), alistai...@gmail.com wrote:

On Wed, Jan 31, 2024 at 10:30 AM Palmer Dabbelt  wrote:


On Tue, 30 Jan 2024 12:28:27 PST (-0800), stefa...@gmail.com wrote:
> On Tue, 30 Jan 2024 at 14:40, Palmer Dabbelt  wrote:
>>
>> On Mon, 15 Jan 2024 08:32:59 PST (-0800), stefa...@gmail.com wrote:
>> > Dear QEMU and KVM communities,
>> > QEMU will apply for the Google Summer of Code and Outreachy internship
>> > programs again this year. Regular contributors can submit project
>> > ideas that they'd like to mentor by replying to this email before
>> > January 30th.
>>
>> It's the 30th, sorry if this is late but I just saw it today.  +Alistair
>> and Daniel, as I didn't sync up with anyone about this so not sure if
>> someone else is looking already (we're not internally).
>>
>> > Internship programs
>> > ---
>> > GSoC (https://summerofcode.withgoogle.com/) and Outreachy
>> > (https://www.outreachy.org/) offer paid open source remote work
>> > internships to eligible people wishing to participate in open source
>> > development. QEMU has been part of these internship programs for many
>> > years. Our mentors have enjoyed helping talented interns make their
>> > first open source contributions and some former interns continue to
>> > participate today.
>> >
>> > Who can mentor
>> > --
>> > Regular contributors to QEMU and KVM can participate as mentors.
>> > Mentorship involves about 5 hours of time commitment per week to
>> > communicate with the intern, review their patches, etc. Time is also
>> > required during the intern selection phase to communicate with
>> > applicants. Being a mentor is an opportunity to help someone get
>> > started in open source development, will give you experience with
>> > managing a project in a low-stakes environment, and a chance to
>> > explore interesting technical ideas that you may not have time to
>> > develop yourself.
>> >
>> > How to propose your idea
>> > --
>> > Reply to this email with the following project idea template filled in:
>> >
>> > === TITLE ===
>> >
>> > '''Summary:''' Short description of the project
>> >
>> > Detailed description of the project that explains the general idea,
>> > including a list of high-level tasks that will be completed by the
>> > project, and provides enough background for someone unfamiliar with
>> > the codebase to do research. Typically 2 or 3 paragraphs.
>> >
>> > '''Links:'''
>> > * Wiki links to relevant material
>> > * External links to mailing lists or web sites
>> >
>> > '''Details:'''
>> > * Skill level: beginner or intermediate or advanced
>> > * Language: C/Python/Rust/etc
>>
>> I'm not 100% sure this is a sane GSoC idea, as it's a bit open ended and
>> might have some tricky parts.  That said it's tripping some people up
>> and as far as I know nobody's started looking at it, so I figrued I'd
>> write something up.
>>
>> I can try and dig up some more links if folks thing it's interesting,
>> IIRC there's been a handful of bug reports related to very small loops
>> that run ~10x slower when vectorized.  Large benchmarks like SPEC have
>> also shown slowdowns.
>
> Hi Palmer,
> Performance optimization can be challenging for newcomers. I wouldn't
> recommend it for a GSoC project unless you have time to seed the
> project idea with specific optimizations to implement based on your
> experience and profiling. That way the intern has a solid starting
> point where they can have a few successes before venturing out to do
> their own performance analysis.

Ya, I agree.  That's part of the reason why I wasn't sure if it's a
good idea.  At least for this one I think there should be some easy to
understand performance issue, as the loops that go very slowly consist
of a small number of instructions and go a lot slower.

I'm actually more worried about this running into a rabbit hole of
adding new TCG operations or even just having no well defined mappings
between RVV and AVX, those might make the project really hard.

> Do you have the time to profile and add specifics to the project idea
> by Feb 21st? If that sounds good to you, I'll add it to the project
> ideas list and you can add more detailed tasks in the coming weeks.

I can at least dig up some of the examples I ran into, there's been a
handful filtering in over the last year or so.

This one
<https://gist.github.com/compnerd/daa7e68f7b4910cb6b27f856e6c2beba>
still has a much more than 10x slowdown (73ms -> 13s) with
vectorization, for example.


It's probably worth creating a Gitlab issue for this and adding all of
the examples there. That way we have a single place to store them all


Makes sense.  I think I'd been telling people to make bug reports for 
them, so there might be some in there already -- I just dug this one out 
of some history.


Here's a start: https://gitlab.com/qemu-project/qemu/-/issues/2137



Alistair



> Thanks,
> Stefan





Re: Call for GSoC/Outreachy internship project ideas

2024-01-31 Thread Palmer Dabbelt

On Wed, 31 Jan 2024 06:39:25 PST (-0800), stefa...@gmail.com wrote:

On Tue, 30 Jan 2024 at 14:40, Palmer Dabbelt  wrote:

On Mon, 15 Jan 2024 08:32:59 PST (-0800), stefa...@gmail.com wrote:
I'm not 100% sure this is a sane GSoC idea, as it's a bit open ended and
might have some tricky parts.  That said it's tripping some people up
and as far as I know nobody's started looking at it, so I figrued I'd
write something up.


Hi Palmer,
Your idea has been added:
https://wiki.qemu.org/Google_Summer_of_Code_2024#RISC-V_Vector_TCG_Frontend_Optimization

I added links to the vector extension specification and the RISC-V TCG
frontend source code.

Please add concrete tasks (e.g. specific optimizations the intern
should implement and benchmark) by Feb 21st. Thank you!


OK.  We've got a few examples starting to filter in, I'll keep updating 
the bug until we get some nice concrete reproducers for slowdows of 
decent vectorized code.  Then I'll take a look and what's inside them, 
with any luck it'll be simple to figure out which vector instructions 
are commonly used and slow -- there's a bunch of stuff in the RVV 
translation that doesn't map cleanly, so I'm guessing it'll be in there.


If that all goes smoothly then I think we should have a reasonably 
actionable intern project, but LMK if you were thinking of something 
else?



Stefan




[PATCH] RISC-V: Report the QEMU vendor/arch IDs on virtual CPUs

2024-01-31 Thread Palmer Dabbelt
Right now we just report 0 for marchid/mvendorid in QEMU.  That's legal,
but it's tricky for users that want to check if they're running on QEMU
to do so.  This sets marchid to 42, which I've proposed as the QEMU
architecture ID (mvendorid remains 0, just explicitly set, as that's how
the ISA handles open source implementations).

Link: https://github.com/riscv/riscv-isa-manual/pull/1213
Signed-off-by: Palmer Dabbelt 
---
 target/riscv/cpu.c  | 16 
 target/riscv/cpu_vendorid.h |  3 +++
 2 files changed, 19 insertions(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 8cbfc7e781..1aef186f87 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -415,6 +415,9 @@ static void riscv_any_cpu_init(Object *obj)
 cpu->cfg.ext_zicsr = true;
 cpu->cfg.mmu = true;
 cpu->cfg.pmp = true;
+
+cpu->cfg.mvendorid = QEMU_MVENDORID;
+cpu->cfg.marchid = QEMU_MARCHID;
 }
 
 static void riscv_max_cpu_init(Object *obj)
@@ -432,6 +435,8 @@ static void riscv_max_cpu_init(Object *obj)
 set_satp_mode_max_supported(RISCV_CPU(obj), mlx == MXL_RV32 ?
 VM_1_10_SV32 : VM_1_10_SV57);
 #endif
+cpu->cfg.mvendorid = QEMU_MVENDORID;
+cpu->cfg.marchid = QEMU_MARCHID;
 }
 
 #if defined(TARGET_RISCV64)
@@ -445,6 +450,8 @@ static void rv64_base_cpu_init(Object *obj)
 #ifndef CONFIG_USER_ONLY
 set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV57);
 #endif
+cpu->cfg.mvendorid = QEMU_MVENDORID;
+cpu->cfg.marchid = QEMU_MARCHID;
 }
 
 static void rv64_sifive_u_cpu_init(Object *obj)
@@ -569,6 +576,8 @@ static void rv128_base_cpu_init(Object *obj)
 #ifndef CONFIG_USER_ONLY
 set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV57);
 #endif
+cpu->cfg.mvendorid = QEMU_MVENDORID;
+cpu->cfg.marchid = QEMU_MARCHID;
 }
 
 static void rv64i_bare_cpu_init(Object *obj)
@@ -591,6 +600,8 @@ static void rv64i_bare_cpu_init(Object *obj)
 #ifndef CONFIG_USER_ONLY
 set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV64);
 #endif
+cpu->cfg.mvendorid = QEMU_MVENDORID;
+cpu->cfg.marchid = QEMU_MARCHID;
 }
 #else
 static void rv32_base_cpu_init(Object *obj)
@@ -603,6 +614,8 @@ static void rv32_base_cpu_init(Object *obj)
 #ifndef CONFIG_USER_ONLY
 set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV32);
 #endif
+cpu->cfg.mvendorid = QEMU_MVENDORID;
+cpu->cfg.marchid = QEMU_MARCHID;
 }
 
 static void rv32_sifive_u_cpu_init(Object *obj)
@@ -672,6 +685,9 @@ static void rv32_imafcu_nommu_cpu_init(Object *obj)
 cpu->cfg.ext_zifencei = true;
 cpu->cfg.ext_zicsr = true;
 cpu->cfg.pmp = true;
+
+cpu->cfg.mvendorid = QEMU_MVENDORID;
+cpu->cfg.marchid = QEMU_MARCHID;
 }
 #endif
 
diff --git a/target/riscv/cpu_vendorid.h b/target/riscv/cpu_vendorid.h
index 96b6b9c2cb..486832cd53 100644
--- a/target/riscv/cpu_vendorid.h
+++ b/target/riscv/cpu_vendorid.h
@@ -7,4 +7,7 @@
 #define VEYRON_V1_MIMPID0x111
 #define VEYRON_V1_MVENDORID 0x61f
 
+#define QEMU_VIRT_MVENDORID 0
+#define QEMU_VIRT_MARCHID   42
+
 #endif /*  TARGET_RISCV_CPU_VENDORID_H */
-- 
2.43.0




Re: Call for GSoC/Outreachy internship project ideas

2024-02-01 Thread Palmer Dabbelt

On Thu, 01 Feb 2024 09:39:22 PST (-0800), alex.ben...@linaro.org wrote:

Palmer Dabbelt  writes:


On Tue, 30 Jan 2024 12:28:27 PST (-0800), stefa...@gmail.com wrote:

On Tue, 30 Jan 2024 at 14:40, Palmer Dabbelt  wrote:


On Mon, 15 Jan 2024 08:32:59 PST (-0800), stefa...@gmail.com wrote:
> Dear QEMU and KVM communities,
> QEMU will apply for the Google Summer of Code and Outreachy internship
> programs again this year. Regular contributors can submit project
> ideas that they'd like to mentor by replying to this email before
> January 30th.

It's the 30th, sorry if this is late but I just saw it today.  +Alistair
and Daniel, as I didn't sync up with anyone about this so not sure if
someone else is looking already (we're not internally).



Hi Palmer,
Performance optimization can be challenging for newcomers. I wouldn't
recommend it for a GSoC project unless you have time to seed the
project idea with specific optimizations to implement based on your
experience and profiling. That way the intern has a solid starting
point where they can have a few successes before venturing out to do
their own performance analysis.


Ya, I agree.  That's part of the reason why I wasn't sure if it's a
good idea.  At least for this one I think there should be some easy to
understand performance issue, as the loops that go very slowly consist
of a small number of instructions and go a lot slower.

I'm actually more worried about this running into a rabbit hole of
adding new TCG operations or even just having no well defined mappings
between RVV and AVX, those might make the project really hard.


You shouldn't have a hard guest-target mapping. But are you already
using the TCGVec types and they are not expanding to AVX when its
available?


Ya, sorry, I guess that was an odd way to describe it.  IIUC we're doing 
sane stuff, it's just that RISC-V has a very different vector masking 
model than other ISAs.  I just said AVX there because I only care about 
the performance on Intel servers, since that's what I run QEMU on.  I'd 
asssume we have similar performance problems on other targets, I just 
haven't looked.


So my worry would be that the RVV things we're doing slowly just don't 
have fast implementations via AVX and thus we run into some intractable 
problems.  That sort of stuff can be really frusturating for an intern, 
as everything's new to them so it can be hard to know when something's 
an optimization dead end.


That said, we're seeing 100x slowdows in microbenchmarks and 10x 
slowdowns in real code, so I think there sholud be some way to do 
better.



Remember for anything float we will end up with softfloat anyway so we
can't use SIMD on the backend.


Yep, but we have a handful of integer slowdowns too so I think there's 
some meat to chew on here.  The softfloat stuff should be equally slow 
for scalar/vector, so we shouldn't be tripping false positives there.



Do you have the time to profile and add specifics to the project idea
by Feb 21st? If that sounds good to you, I'll add it to the project
ideas list and you can add more detailed tasks in the coming weeks.


I can at least dig up some of the examples I ran into, there's been a
handful filtering in over the last year or so.

This one
<https://gist.github.com/compnerd/daa7e68f7b4910cb6b27f856e6c2beba>
still has a much more than 10x slowdown (73ms -> 13s) with
vectorization, for example.


Thanks,
Stefan


--
Alex Bennée
Virtualisation Tech Lead @ Linaro




Re: Call for GSoC/Outreachy internship project ideas

2024-02-01 Thread Palmer Dabbelt

On Thu, 01 Feb 2024 10:57:00 PST (-0800), alex.ben...@linaro.org wrote:

Palmer Dabbelt  writes:


On Thu, 01 Feb 2024 09:39:22 PST (-0800), alex.ben...@linaro.org wrote:

Palmer Dabbelt  writes:


On Tue, 30 Jan 2024 12:28:27 PST (-0800), stefa...@gmail.com wrote:

On Tue, 30 Jan 2024 at 14:40, Palmer Dabbelt  wrote:


On Mon, 15 Jan 2024 08:32:59 PST (-0800), stefa...@gmail.com wrote:
> Dear QEMU and KVM communities,
> QEMU will apply for the Google Summer of Code and Outreachy internship
> programs again this year. Regular contributors can submit project
> ideas that they'd like to mentor by replying to this email before
> January 30th.

It's the 30th, sorry if this is late but I just saw it today.  +Alistair
and Daniel, as I didn't sync up with anyone about this so not sure if
someone else is looking already (we're not internally).



Hi Palmer,
Performance optimization can be challenging for newcomers. I wouldn't
recommend it for a GSoC project unless you have time to seed the
project idea with specific optimizations to implement based on your
experience and profiling. That way the intern has a solid starting
point where they can have a few successes before venturing out to do
their own performance analysis.


Ya, I agree.  That's part of the reason why I wasn't sure if it's a
good idea.  At least for this one I think there should be some easy to
understand performance issue, as the loops that go very slowly consist
of a small number of instructions and go a lot slower.

I'm actually more worried about this running into a rabbit hole of
adding new TCG operations or even just having no well defined mappings
between RVV and AVX, those might make the project really hard.


You shouldn't have a hard guest-target mapping. But are you already
using the TCGVec types and they are not expanding to AVX when its
available?


Ya, sorry, I guess that was an odd way to describe it.  IIUC we're
doing sane stuff, it's just that RISC-V has a very different vector
masking model than other ISAs.  I just said AVX there because I only
care about the performance on Intel servers, since that's what I run
QEMU on.  I'd asssume we have similar performance problems on other
targets, I just haven't looked.

So my worry would be that the RVV things we're doing slowly just don't
have fast implementations via AVX and thus we run into some
intractable problems.  That sort of stuff can be really frusturating
for an intern, as everything's new to them so it can be hard to know
when something's an optimization dead end.

That said, we're seeing 100x slowdows in microbenchmarks and 10x
slowdowns in real code, so I think there sholud be some way to do
better.


It would be nice if you could convert that micro-benchmark to plain C
for a tcg/multiarch test case. It would be a useful tool for testing
changes.


Yep.  I actually gave it a shot before posting the C++ version and it 
seems kind of fragile, just poking it boring looknig ways changes the 
behavior.  Some of that was tied up in me trying to get GCC to generate 
similar code to clang, though, so hopefully that's all manageable.  I 
certainly wouldn't want to throw something that wacky at an intern for 
their first project, though.  So I don't have a good version yet.


I'm also hoping the fuzzer reproduces some nice small examples, but no 
luck yet...







Remember for anything float we will end up with softfloat anyway so we
can't use SIMD on the backend.


Yep, but we have a handful of integer slowdowns too so I think there's
some meat to chew on here.  The softfloat stuff should be equally slow
for scalar/vector, so we shouldn't be tripping false positives there.


Do you have the time to profile and add specifics to the project idea
by Feb 21st? If that sounds good to you, I'll add it to the project
ideas list and you can add more detailed tasks in the coming weeks.


I can at least dig up some of the examples I ran into, there's been a
handful filtering in over the last year or so.

This one
<https://gist.github.com/compnerd/daa7e68f7b4910cb6b27f856e6c2beba>
still has a much more than 10x slowdown (73ms -> 13s) with
vectorization, for example.


Thanks,
Stefan


-- Alex Bennée
Virtualisation Tech Lead @ Linaro


--
Alex Bennée
Virtualisation Tech Lead @ Linaro




Re: [Qemu-devel] [PATCH 2/2] target/riscv: Add checks for several RVC reserved operands

2019-05-01 Thread Palmer Dabbelt

On Thu, 25 Apr 2019 10:32:43 PDT (-0700), richard.hender...@linaro.org wrote:

On 4/25/19 10:26 AM, Richard Henderson wrote:

 {
+  illegal 011 0  -  0 01 # c.addi16sp, RES nzimm=0
   addi011 .  00010  . 01 @c_addi16sp
   lui 011 .  .  . 01 @c_lui
 }


Bah.  I just realized the comment should be more like

  # c.addi16sp and c.lui, RES nzimm=0

Otherwise one is led to believe that rd=2 is missing
from the illegal pattern.


OK, I went ahead and squashed in that fix as well.




Re: [Qemu-devel] [PATCH 1/2] fixup! target/riscv: Name the argument sets for all of insn32 formats

2019-05-01 Thread Palmer Dabbelt

On Thu, 25 Apr 2019 10:26:35 PDT (-0700), richard.hender...@linaro.org wrote:

---
 target/riscv/translate.c | 13 ++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index d1f599a92d..009c146e8f 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -713,12 +713,19 @@ static bool gen_shift(DisasContext *ctx, arg_r *a,
  * initially declared by the 32-bit decoder, which results in duplicate
  * declaration warnings.  Suppress them.
  */
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wredundant-decls"
+#ifdef CONFIG_PRAGMA_DIAGNOSTIC_AVAILABLE
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wredundant-decls"
+# ifdef __clang__
+#  pragma GCC diagnostic ignored "-Wtypedef-redefinition"
+# endif
+#endif

 #include "decode_insn16.inc.c"

-#pragma GCC diagnostic pop
+#ifdef CONFIG_PRAGMA_DIAGNOSTIC_AVAILABLE
+# pragma GCC diagnostic pop
+#endif

 static void decode_opc(DisasContext *ctx)
 {


I've attemeted to fixup the patch on my for-master, let me know if I've screwed
something up!



Re: [Qemu-devel] [PATCH for 4.1] target/riscv: More accurate handling of `sip` CSR

2019-05-07 Thread Palmer Dabbelt

On Mon, 06 May 2019 08:52:43 PDT (-0700), finte...@gmail.com wrote:

According to the spec, "All bits besides SSIP, USIP, and UEIP in the sip
register are read-only." Further, if an interrupt is not delegated to mode
x,
then "the corresponding bits in xip [...] should appear to be hardwired to
zero. This patch implements both of those requirements.

Signed-off-by: Jonathan Behrens 
---
 target/riscv/csr.c | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 1ec1222da1..fff7d834e8 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -246,6 +246,7 @@ static const target_ulong sstatus_v1_9_mask =
SSTATUS_SIE | SSTATUS_SPIE |
 static const target_ulong sstatus_v1_10_mask = SSTATUS_SIE | SSTATUS_SPIE |
 SSTATUS_UIE | SSTATUS_UPIE | SSTATUS_SPP | SSTATUS_FS | SSTATUS_XS |
 SSTATUS_SUM | SSTATUS_MXR | SSTATUS_SD;
+static const target_ulong sip_writable_mask = SIP_SSIP | MIP_USIP |
MIP_UEIP;

 #if defined(TARGET_RISCV32)
 static const char valid_vm_1_09[16] = {
@@ -694,8 +695,10 @@ static int write_sbadaddr(CPURISCVState *env, int
csrno, target_ulong val)
 static int rmw_sip(CPURISCVState *env, int csrno, target_ulong *ret_value,
target_ulong new_value, target_ulong write_mask)
 {
-return rmw_mip(env, CSR_MSTATUS, ret_value, new_value,
-   write_mask & env->mideleg);
+int ret = rmw_mip(env, CSR_MSTATUS, ret_value, new_value,
+  write_mask & env->mideleg & sip_writable_mask);
+*ret_value &= env->mideleg;
+return ret;
 }

 /* Supervisor Protection and Translation */


This patch (and your previous one) don't apply for me.  I don't see the
git-send-email tags in your messages, are you trying to do something like paste
them into gmail?  If so I think they're getting line wrapped.



Re: [Qemu-devel] [PATCH] target/riscv: More accurate handling of `sip` CSR

2019-05-07 Thread Palmer Dabbelt

On Tue, 07 May 2019 15:36:46 PDT (-0700), jonat...@fintelia.io wrote:

According to the spec, "All bits besides SSIP, USIP, and UEIP in the sip
register are read-only." Further, if an interrupt is not delegated to mode x,
then "the corresponding bits in xip [...] should appear to be hardwired to
zero. This patch implements both of those requirements.

Signed-off-by: Jonathan Behrens 
---
 target/riscv/csr.c | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 1ec1222da1..fff7d834e8 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -246,6 +246,7 @@ static const target_ulong sstatus_v1_9_mask = SSTATUS_SIE | 
SSTATUS_SPIE |
 static const target_ulong sstatus_v1_10_mask = SSTATUS_SIE | SSTATUS_SPIE |
 SSTATUS_UIE | SSTATUS_UPIE | SSTATUS_SPP | SSTATUS_FS | SSTATUS_XS |
 SSTATUS_SUM | SSTATUS_MXR | SSTATUS_SD;
+static const target_ulong sip_writable_mask = SIP_SSIP | MIP_USIP | MIP_UEIP;

 #if defined(TARGET_RISCV32)
 static const char valid_vm_1_09[16] = {
@@ -694,8 +695,10 @@ static int write_sbadaddr(CPURISCVState *env, int csrno, 
target_ulong val)
 static int rmw_sip(CPURISCVState *env, int csrno, target_ulong *ret_value,
target_ulong new_value, target_ulong write_mask)
 {
-return rmw_mip(env, CSR_MSTATUS, ret_value, new_value,
-   write_mask & env->mideleg);
+int ret = rmw_mip(env, CSR_MSTATUS, ret_value, new_value,
+  write_mask & env->mideleg & sip_writable_mask);
+*ret_value &= env->mideleg;
+return ret;
 }

 /* Supervisor Protection and Translation */


Reviewed-by: Palmer Dabbelt 

Thanks!



Re: [Qemu-devel] [PATCH] target/riscv: Only flush TLB if SATP.ASID changes

2019-05-08 Thread Palmer Dabbelt

On Wed, 08 May 2019 10:38:35 PDT (-0700), jonat...@fintelia.io wrote:

There is an analogous change for ARM here:
https://patchwork.kernel.org/patch/10649857

Signed-off-by: Jonathan Behrens 
---
 target/riscv/csr.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 6083c782a1..1ec1222da1 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -732,7 +732,9 @@ static int write_satp(CPURISCVState *env, int csrno, 
target_ulong val)
 if (env->priv == PRV_S && get_field(env->mstatus, MSTATUS_TVM)) {
 return -1;
 } else {
-tlb_flush(CPU(riscv_env_get_cpu(env)));
+if((val ^ env->satp) & SATP_ASID) {
+tlb_flush(CPU(riscv_env_get_cpu(env)));
+}
 env->satp = val;
 }
 }


Thanks!  I've taken this into my for-master branch, pending some testing I'll
send it up.



Re: [Qemu-devel] [PULL 4/9] linux-user/nios2 linux-user/riscv: Clean up header guards

2019-05-13 Thread Palmer Dabbelt

On Mon, 13 May 2019 01:18:39 PDT (-0700), arm...@redhat.com wrote:

Reuse of the same guard symbol in multiple headers is okay as long as
they cannot be included together.  scripts/clean-header-guards.pl
can't tell, so it warns.

Since we can avoid guard symbol reuse easily, do so: use guard symbol
${target^^}_${fname^^} for linux-user/$target/$fname, just like we did
in commit a9c94277f0..3500385697.

Signed-off-by: Markus Armbruster 
Message-Id: <20190315145123.28030-4-arm...@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé 
---
 linux-user/nios2/target_cpu.h | 4 ++--
 linux-user/nios2/target_signal.h  | 6 +++---
 linux-user/nios2/target_structs.h | 4 ++--
 linux-user/nios2/target_syscall.h | 6 +++---
 linux-user/riscv/target_cpu.h | 4 ++--
 linux-user/riscv/target_signal.h  | 6 +++---
 linux-user/riscv/target_structs.h | 4 ++--
 7 files changed, 17 insertions(+), 17 deletions(-)

diff --git a/linux-user/nios2/target_cpu.h b/linux-user/nios2/target_cpu.h
index 14f63338fa..5596c05c9c 100644
--- a/linux-user/nios2/target_cpu.h
+++ b/linux-user/nios2/target_cpu.h
@@ -17,8 +17,8 @@
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
 
-#ifndef TARGET_CPU_H

-#define TARGET_CPU_H
+#ifndef NIOS2_TARGET_CPU_H
+#define NIOS2_TARGET_CPU_H
 
 static inline void cpu_clone_regs(CPUNios2State *env, target_ulong newsp)

 {
diff --git a/linux-user/nios2/target_signal.h b/linux-user/nios2/target_signal.h
index 7776bcdbfd..fe48721b3d 100644
--- a/linux-user/nios2/target_signal.h
+++ b/linux-user/nios2/target_signal.h
@@ -1,5 +1,5 @@
-#ifndef TARGET_SIGNAL_H
-#define TARGET_SIGNAL_H
+#ifndef NIOS2_TARGET_SIGNAL_H
+#define NIOS2_TARGET_SIGNAL_H
 
 /* this struct defines a stack used during syscall handling */
 
@@ -18,4 +18,4 @@ typedef struct target_sigaltstack {
 
 #include "../generic/signal.h"
 
-#endif /* TARGET_SIGNAL_H */

+#endif /* NIOS2_TARGET_SIGNAL_H */
diff --git a/linux-user/nios2/target_structs.h 
b/linux-user/nios2/target_structs.h
index 8713772089..7145251706 100644
--- a/linux-user/nios2/target_structs.h
+++ b/linux-user/nios2/target_structs.h
@@ -16,8 +16,8 @@
  * 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/>.
  */
-#ifndef TARGET_STRUCTS_H
-#define TARGET_STRUCTS_H
+#ifndef NIOS2_TARGET_STRUCTS_H
+#define NIOS2_TARGET_STRUCTS_H
 
 struct target_ipc_perm {

 abi_int __key;  /* Key.  */
diff --git a/linux-user/nios2/target_syscall.h 
b/linux-user/nios2/target_syscall.h
index ca6b7e69f6..f3b2a500f4 100644
--- a/linux-user/nios2/target_syscall.h
+++ b/linux-user/nios2/target_syscall.h
@@ -1,5 +1,5 @@
-#ifndef TARGET_SYSCALL_H
-#define TARGET_SYSCALL_H
+#ifndef NIOS2_TARGET_SYSCALL_H
+#define NIOS2_TARGET_SYSCALL_H
 
 #define UNAME_MACHINE "nios2"

 #define UNAME_MINIMUM_RELEASE "3.19.0"
@@ -34,4 +34,4 @@ struct target_pt_regs {
 #define TARGET_MLOCKALL_MCL_CURRENT 1
 #define TARGET_MLOCKALL_MCL_FUTURE  2
 
-#endif  /* TARGET_SYSCALL_H */

+#endif /* NIOS2_TARGET_SYSCALL_H */
diff --git a/linux-user/riscv/target_cpu.h b/linux-user/riscv/target_cpu.h
index 7e090f376a..90f9a4171e 100644
--- a/linux-user/riscv/target_cpu.h
+++ b/linux-user/riscv/target_cpu.h
@@ -1,5 +1,5 @@
-#ifndef TARGET_CPU_H
-#define TARGET_CPU_H
+#ifndef RISCV_TARGET_CPU_H
+#define RISCV_TARGET_CPU_H
 
 static inline void cpu_clone_regs(CPURISCVState *env, target_ulong newsp)

 {
diff --git a/linux-user/riscv/target_signal.h b/linux-user/riscv/target_signal.h
index c8b1455800..f113ba9a55 100644
--- a/linux-user/riscv/target_signal.h
+++ b/linux-user/riscv/target_signal.h
@@ -1,5 +1,5 @@
-#ifndef TARGET_SIGNAL_H
-#define TARGET_SIGNAL_H
+#ifndef RISCV_TARGET_SIGNAL_H
+#define RISCV_TARGET_SIGNAL_H
 
 typedef struct target_sigaltstack {

 abi_ulong ss_sp;
@@ -15,4 +15,4 @@ typedef struct target_sigaltstack {
 
 #include "../generic/signal.h"
 
-#endif /* TARGET_SIGNAL_H */

+#endif /* RISCV_TARGET_SIGNAL_H */
diff --git a/linux-user/riscv/target_structs.h 
b/linux-user/riscv/target_structs.h
index 4f0462c497..ea3e5ed17e 100644
--- a/linux-user/riscv/target_structs.h
+++ b/linux-user/riscv/target_structs.h
@@ -4,8 +4,8 @@
  * This is a copy of ../aarch64/target_structs.h atm.
  *
  */
-#ifndef TARGET_STRUCTS_H
-#define TARGET_STRUCTS_H
+#ifndef RISCV_TARGET_STRUCTS_H
+#define RISCV_TARGET_STRUCTS_H
 
 struct target_ipc_perm {

 abi_int __key;      /* Key.  */
--
2.17.2


Reviewed-by: Palmer Dabbelt 

I'm assuming this is going in through someone else's tree, so I'm not going to
pick it up into mine.



Re: [Qemu-devel] RISC-V: Include ROM in QEMU

2019-06-07 Thread Palmer Dabbelt

On Thu, 06 Jun 2019 16:22:47 PDT (-0700), alistai...@gmail.com wrote:

Hello,

As a test of the waters, how would the QEMU community feel about
including the RISC-V OpenSBI project as a ROM submodule?

The idea would be to have OpenSBI (similar to ATF for ARM and a BIOS
for x86) included by default to simplify the QEMU RISC-V boot process
for users. This would remove the requirement for users/developers to
build a RISC-V firmware. The goal here is to allow people to just
download and run their kernel as easily as they currently do for x86.

We would make sure that it can be disabled! That is users/developers
can use their own (or none) if they want to. The idea here is just to
simplify the boot process, not lock anyone out.


I like it.  My only question is about the mechanics of doing so: are we just
going to assume there's a cross compiler in PATH?  I guess that's less of a
usability headache than needing a complier and a firmware.



Re: [Qemu-devel] Fwd: [j...@sing.id.au: atomic failures on qemu-system-riscv64]

2019-06-07 Thread Palmer Dabbelt

On Thu, 06 Jun 2019 19:50:57 PDT (-0700), richard.hender...@linaro.org wrote:


Also, unless I'm misunderstanding something our implementation of LR/SC is


pretty broken.  We're just using a CAS to check if the value changed, which

suffers from the ABA problem that LR/SC is there to fix in the first
place.  I
might be missing something here, though, as it looks like MIPS is doing
essentially the same thing.



All of our load-lock/store-conditional implementations do the same.

You are correct that we do not implement the exact correct semantics.
Correct semantics, as far as I know, cannot be modeled without emulating
everything in a serial context, including caches.

We therefore make a considered choice to observe that while ll/sc can be
used to do all kinds of wild and woolly things, no one actually does so.
What people actually do is write portable code, using c/c++ atomic
primitives. And that all of these can be done with cmpxchg, because that's
what x86 has.

Using that choice, we can provide multi-threaded smp emulation that,
demonstrably, works.


OK, that makes sense.  I was just worried that we were screwing something up on
our end.



Re: [Qemu-devel] [PATCH v1 2/4] disas/riscv: Disassemble reserved compressed encodings as illegal

2019-06-14 Thread Palmer Dabbelt

On Fri, 17 May 2019 15:11:01 PDT (-0700), Alistair Francis wrote:

From: Michael Clark 

Due to the design of the disassembler, the immediate is not
known during decoding of the opcode; so to handle compressed
encodings with reserved immediate values (non-zero), we need
to add an additional check during decompression to match
reserved encodings with zero immediates and translate them
into the illegal instruction.

The following compressed opcodes have reserved encodings with
zero immediates: c.addi4spn, c.addi, c.lui, c.addi16sp, c.srli,
c.srai, c.andi and c.slli

Signed-off-by: Michael Clark 
Signed-off-by: Alistair Francis 
---
 disas/riscv.c | 51 ++-
 1 file changed, 34 insertions(+), 17 deletions(-)

diff --git a/disas/riscv.c b/disas/riscv.c
index 59a9b0437a..3ab4586f0a 100644
--- a/disas/riscv.c
+++ b/disas/riscv.c
@@ -504,14 +504,19 @@ typedef struct {
 const rvc_constraint *constraints;
 } rv_comp_data;

+enum {
+rvcd_imm_nz = 0x1
+};
+
 typedef struct {
 const char * const name;
 const rv_codec codec;
 const char * const format;
 const rv_comp_data *pseudo;
-const int decomp_rv32;
-const int decomp_rv64;
-const int decomp_rv128;
+const short decomp_rv32;
+const short decomp_rv64;
+const short decomp_rv128;
+const short decomp_data;
 } rv_opcode_data;

 /* register names */
@@ -1011,7 +1016,7 @@ const rv_opcode_data opcode_data[] = {
 { "fcvt.q.lu", rv_codec_r_m, rv_fmt_rm_frd_rs1, NULL, 0, 0, 0 },
 { "fmv.x.q", rv_codec_r, rv_fmt_rd_frs1, NULL, 0, 0, 0 },
 { "fmv.q.x", rv_codec_r, rv_fmt_frd_rs1, NULL, 0, 0, 0 },
-{ "c.addi4spn", rv_codec_ciw_4spn, rv_fmt_rd_rs1_imm, NULL, rv_op_addi, 
rv_op_addi, rv_op_addi },
+{ "c.addi4spn", rv_codec_ciw_4spn, rv_fmt_rd_rs1_imm, NULL, rv_op_addi, 
rv_op_addi, rv_op_addi, rvcd_imm_nz },
 { "c.fld", rv_codec_cl_ld, rv_fmt_frd_offset_rs1, NULL, rv_op_fld, 
rv_op_fld, 0 },
 { "c.lw", rv_codec_cl_lw, rv_fmt_rd_offset_rs1, NULL, rv_op_lw, rv_op_lw, 
rv_op_lw },
 { "c.flw", rv_codec_cl_lw, rv_fmt_frd_offset_rs1, NULL, rv_op_flw, 0, 0 },
@@ -1019,14 +1024,14 @@ const rv_opcode_data opcode_data[] = {
 { "c.sw", rv_codec_cs_sw, rv_fmt_rs2_offset_rs1, NULL, rv_op_sw, rv_op_sw, 
rv_op_sw },
 { "c.fsw", rv_codec_cs_sw, rv_fmt_frs2_offset_rs1, NULL, rv_op_fsw, 0, 0 },
 { "c.nop", rv_codec_ci_none, rv_fmt_none, NULL, rv_op_addi, rv_op_addi, 
rv_op_addi },
-{ "c.addi", rv_codec_ci, rv_fmt_rd_rs1_imm, NULL, rv_op_addi, rv_op_addi, 
rv_op_addi },
+{ "c.addi", rv_codec_ci, rv_fmt_rd_rs1_imm, NULL, rv_op_addi, rv_op_addi, 
rv_op_addi, rvcd_imm_nz },
 { "c.jal", rv_codec_cj_jal, rv_fmt_rd_offset, NULL, rv_op_jal, 0, 0 },
 { "c.li", rv_codec_ci_li, rv_fmt_rd_rs1_imm, NULL, rv_op_addi, rv_op_addi, 
rv_op_addi },
-{ "c.addi16sp", rv_codec_ci_16sp, rv_fmt_rd_rs1_imm, NULL, rv_op_addi, 
rv_op_addi, rv_op_addi },
-{ "c.lui", rv_codec_ci_lui, rv_fmt_rd_imm, NULL, rv_op_lui, rv_op_lui, 
rv_op_lui },
-{ "c.srli", rv_codec_cb_sh6, rv_fmt_rd_rs1_imm, NULL, rv_op_srli, 
rv_op_srli, rv_op_srli },
-{ "c.srai", rv_codec_cb_sh6, rv_fmt_rd_rs1_imm, NULL, rv_op_srai, 
rv_op_srai, rv_op_srai },
-{ "c.andi", rv_codec_cb_imm, rv_fmt_rd_rs1_imm, NULL, rv_op_andi, 
rv_op_andi, rv_op_andi },
+{ "c.addi16sp", rv_codec_ci_16sp, rv_fmt_rd_rs1_imm, NULL, rv_op_addi, 
rv_op_addi, rv_op_addi, rvcd_imm_nz },
+{ "c.lui", rv_codec_ci_lui, rv_fmt_rd_imm, NULL, rv_op_lui, rv_op_lui, 
rv_op_lui, rvcd_imm_nz },
+{ "c.srli", rv_codec_cb_sh6, rv_fmt_rd_rs1_imm, NULL, rv_op_srli, 
rv_op_srli, rv_op_srli, rvcd_imm_nz },
+{ "c.srai", rv_codec_cb_sh6, rv_fmt_rd_rs1_imm, NULL, rv_op_srai, 
rv_op_srai, rv_op_srai, rvcd_imm_nz },
+{ "c.andi", rv_codec_cb_imm, rv_fmt_rd_rs1_imm, NULL, rv_op_andi, 
rv_op_andi, rv_op_andi, rvcd_imm_nz },


Unless I'm missing something, c.andi can have a zero immediate.


 { "c.sub", rv_codec_cs, rv_fmt_rd_rs1_rs2, NULL, rv_op_sub, rv_op_sub, 
rv_op_sub },
 { "c.xor", rv_codec_cs, rv_fmt_rd_rs1_rs2, NULL, rv_op_xor, rv_op_xor, 
rv_op_xor },
 { "c.or", rv_codec_cs, rv_fmt_rd_rs1_rs2, NULL, rv_op_or, rv_op_or, 
rv_op_or },
@@ -1036,7 +1041,7 @@ const rv_opcode_data opcode_data[] = {
 { "c.j", rv_codec_cj, rv_fmt_rd_offset, NULL, rv_op_jal, rv_op_jal, 
rv_op_jal },
 { "c.beqz", rv_codec_cb, rv_fmt_rs1_rs2_offset, NULL, rv_op_beq, 
rv_op_beq, rv_op_beq },
 { "c.bnez", rv_codec_cb, rv_fmt_rs1_rs2_offset, NULL, rv_op_bne, 
rv_op_bne, rv_op_bne },
-{ "c.slli", rv_codec_ci_sh6, rv_fmt_rd_rs1_imm, NULL, rv_op_slli, 
rv_op_slli, rv_op_slli },
+{ "c.slli", rv_codec_ci_sh6, rv_fmt_rd_rs1_imm, NULL, rv_op_slli, 
rv_op_slli, rv_op_slli, rvcd_imm_nz },
 { "c.fldsp", rv_codec_ci_ldsp, rv_fmt_frd_offset_rs1, NULL, rv_op_fld, 
rv_op_fld, rv_op_fld },
 { "c.lwsp", rv_codec_ci_lwsp, rv_fmt_rd_offset_rs1, NULL, rv_op_lw, 
rv_op_lw, rv_op_lw },
 { "c.flwsp", rv_codec_ci_lwsp, rv

Re: [Qemu-devel] [PATCH v1 3/4] disas/riscv: Fix `rdinstreth` constraint

2019-06-14 Thread Palmer Dabbelt

On Fri, 17 May 2019 15:11:04 PDT (-0700), Alistair Francis wrote:

From: Michael Clark 

The constraint for `rdinstreth` was comparing the csr number to 0xc80,
which is `cycleh` instead. Fix this.

Author: Wladimir J. van der Laan 


I'm not sure what this tag is supposed to mean.  If this is the actual author
of the patch, then shouldn't it also have a SOB?


Signed-off-by: Michael Clark 
Signed-off-by: Alistair Francis 
---
 disas/riscv.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/disas/riscv.c b/disas/riscv.c
index 3ab4586f0a..c2578a3c4b 100644
--- a/disas/riscv.c
+++ b/disas/riscv.c
@@ -614,7 +614,7 @@ static const rvc_constraint rvcc_rdtime[] = { 
rvc_rs1_eq_x0, rvc_csr_eq_0xc01, r
 static const rvc_constraint rvcc_rdinstret[] = { rvc_rs1_eq_x0, 
rvc_csr_eq_0xc02, rvc_end };
 static const rvc_constraint rvcc_rdcycleh[] = { rvc_rs1_eq_x0, 
rvc_csr_eq_0xc80, rvc_end };
 static const rvc_constraint rvcc_rdtimeh[] = { rvc_rs1_eq_x0, 
rvc_csr_eq_0xc81, rvc_end };
-static const rvc_constraint rvcc_rdinstreth[] = { rvc_rs1_eq_x0, 
rvc_csr_eq_0xc80, rvc_end };
+static const rvc_constraint rvcc_rdinstreth[] = { rvc_rs1_eq_x0, 
rvc_csr_eq_0xc82, rvc_end };
 static const rvc_constraint rvcc_frcsr[] = { rvc_rs1_eq_x0, rvc_csr_eq_0x003, 
rvc_end };
 static const rvc_constraint rvcc_frrm[] = { rvc_rs1_eq_x0, rvc_csr_eq_0x002, 
rvc_end };
 static const rvc_constraint rvcc_frflags[] = { rvc_rs1_eq_x0, 
rvc_csr_eq_0x001, rvc_end };




Re: [Qemu-devel] [PATCH v1 4/4] target/riscv: Implement riscv_cpu_unassigned_access

2019-06-14 Thread Palmer Dabbelt

On Fri, 17 May 2019 15:11:06 PDT (-0700), Alistair Francis wrote:

From: Michael Clark 

This patch adds support for the riscv_cpu_unassigned_access call
and will raise a load or store access fault.

Signed-off-by: Michael Clark 
[Changes by AF:
 - Squash two patches and rewrite commit message
 - Set baddr to the access address
]
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu.c|  1 +
 target/riscv/cpu.h|  2 ++
 target/riscv/cpu_helper.c | 16 
 3 files changed, 19 insertions(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index b7675707e0..bfe92235d3 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -356,6 +356,7 @@ static void riscv_cpu_class_init(ObjectClass *c, void *data)
 cc->gdb_stop_before_watchpoint = true;
 cc->disas_set_info = riscv_cpu_disas_set_info;
 #ifndef CONFIG_USER_ONLY
+cc->do_unassigned_access = riscv_cpu_unassigned_access;
 cc->do_unaligned_access = riscv_cpu_do_unaligned_access;
 cc->get_phys_page_debug = riscv_cpu_get_phys_page_debug;
 #endif
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index c17184f4e4..8250175811 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -264,6 +264,8 @@ void  riscv_cpu_do_unaligned_access(CPUState *cs, vaddr 
addr,
 bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
 MMUAccessType access_type, int mmu_idx,
 bool probe, uintptr_t retaddr);
+void riscv_cpu_unassigned_access(CPUState *cpu, hwaddr addr, bool is_write,
+ bool is_exec, int unused, unsigned size);
 char *riscv_isa_string(RISCVCPU *cpu);
 void riscv_cpu_list(void);

diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 41d6db41c3..202b6f021d 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -356,6 +356,22 @@ hwaddr riscv_cpu_get_phys_page_debug(CPUState *cs, vaddr 
addr)
 return phys_addr;
 }

+void riscv_cpu_unassigned_access(CPUState *cs, hwaddr addr, bool is_write,
+ bool is_exec, int unused, unsigned size)
+{
+RISCVCPU *cpu = RISCV_CPU(cs);
+CPURISCVState *env = &cpu->env;
+
+if (is_write) {
+cs->exception_index = RISCV_EXCP_STORE_AMO_ACCESS_FAULT;
+} else {
+cs->exception_index = RISCV_EXCP_LOAD_ACCESS_FAULT;
+}
+
+env->badaddr = addr;
+riscv_raise_exception(&cpu->env, cs->exception_index, GETPC());
+}
+
 void riscv_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
MMUAccessType access_type, int mmu_idx,
    uintptr_t retaddr)


Reviewed-by: Palmer Dabbelt 



Re: [Qemu-devel] [PATCH v1 0/4] Miscellaneous patches from the RISC-V fork

2019-06-14 Thread Palmer Dabbelt

On Fri, 17 May 2019 15:10:56 PDT (-0700), Alistair Francis wrote:

This should be the last series bringing the patches from the RISC-V fork
into mainline QEMU.

Dayeol Lee (1):
  target/riscv: Fix PMP range boundary address bug

Michael Clark (3):
  disas/riscv: Disassemble reserved compressed encodings as illegal
  disas/riscv: Fix `rdinstreth` constraint
  target/riscv: Implement riscv_cpu_unassigned_access

 disas/riscv.c | 53 ++-
 target/riscv/cpu.c|  1 +
 target/riscv/cpu.h|  2 ++
 target/riscv/cpu_helper.c | 16 
 target/riscv/pmp.c|  2 +-
 5 files changed, 55 insertions(+), 19 deletions(-)


There's some minor issues with two of these, but since they're all independent
I'm going to take the other two right now.

Thanks!



Re: [Qemu-devel] [PATCH for 4.1 v3] target/riscv: Expose time CSRs when allowed by [m|s]counteren

2019-06-14 Thread Palmer Dabbelt

On Tue, 28 May 2019 11:30:20 PDT (-0700), jonat...@fintelia.io wrote:

Currently mcounteren.TM acts as though it is hardwired to zero, even though 
QEMU allows it to be set. This change resolves the issue by allowing reads to 
the time and timeh control registers when running in a privileged mode where 
such accesses are allowed.

The frequency of the time register is stored in the time_freq field of each 
hart so that it is accessible during CSR reads, but must be the same across all 
harts. Each board can initialize it to a custom value, although all currently 
use a 10 MHz frequency.

Signed-off-by: Jonathan Behrens 
---
 hw/riscv/riscv_hart.c   |  4 
 hw/riscv/sifive_clint.c | 30 ++
 hw/riscv/sifive_e.c |  2 ++
 hw/riscv/sifive_u.c |  4 +++-
 hw/riscv/spike.c|  6 +-
 hw/riscv/virt.c |  4 +++-
 include/hw/riscv/riscv_hart.h   |  1 +
 include/hw/riscv/sifive_clint.h |  4 
 include/hw/riscv/sifive_e.h |  4 
 include/hw/riscv/sifive_u.h |  1 +
 include/hw/riscv/spike.h|  1 +
 include/hw/riscv/virt.h |  1 +
 target/riscv/cpu.h  |  2 ++
 target/riscv/csr.c  | 17 +++--
 14 files changed, 60 insertions(+), 21 deletions(-)

diff --git a/hw/riscv/riscv_hart.c b/hw/riscv/riscv_hart.c
index e34a26a0ef..c39cd55330 100644
--- a/hw/riscv/riscv_hart.c
+++ b/hw/riscv/riscv_hart.c
@@ -19,6 +19,7 @@
  */

 #include "qemu/osdep.h"
+#include "qemu/timer.h"
 #include "qapi/error.h"
 #include "hw/sysbus.h"
 #include "target/riscv/cpu.h"
@@ -27,6 +28,8 @@
 static Property riscv_harts_props[] = {
 DEFINE_PROP_UINT32("num-harts", RISCVHartArrayState, num_harts, 1),
 DEFINE_PROP_STRING("cpu-type", RISCVHartArrayState, cpu_type),
+DEFINE_PROP_UINT64("timebase-frequency", RISCVHartArrayState, time_freq,
+   NANOSECONDS_PER_SECOND),
 DEFINE_PROP_END_OF_LIST(),
 };

@@ -49,6 +52,7 @@ static void riscv_harts_realize(DeviceState *dev, Error 
**errp)
 sizeof(RISCVCPU), s->cpu_type,
 &error_abort, NULL);
 s->harts[n].env.mhartid = n;
+s->harts[n].env.time_freq = s->time_freq;
 qemu_register_reset(riscv_harts_cpu_reset, &s->harts[n]);
 object_property_set_bool(OBJECT(&s->harts[n]), true,
  "realized", &err);
diff --git a/hw/riscv/sifive_clint.c b/hw/riscv/sifive_clint.c
index d4c159e937..71edf4dcc6 100644
--- a/hw/riscv/sifive_clint.c
+++ b/hw/riscv/sifive_clint.c
@@ -26,10 +26,10 @@
 #include "hw/riscv/sifive_clint.h"
 #include "qemu/timer.h"

-static uint64_t cpu_riscv_read_rtc(void)
+static uint64_t cpu_riscv_read_rtc(CPURISCVState *env)
 {
 return muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL),
-SIFIVE_CLINT_TIMEBASE_FREQ, NANOSECONDS_PER_SECOND);
+env->time_freq, NANOSECONDS_PER_SECOND);
 }

 /*
@@ -41,7 +41,7 @@ static void sifive_clint_write_timecmp(RISCVCPU *cpu, 
uint64_t value)
 uint64_t next;
 uint64_t diff;

-uint64_t rtc_r = cpu_riscv_read_rtc();
+uint64_t rtc_r = cpu_riscv_read_rtc(&cpu->env);

 cpu->env.timecmp = value;
 if (cpu->env.timecmp <= rtc_r) {
@@ -56,7 +56,7 @@ static void sifive_clint_write_timecmp(RISCVCPU *cpu, 
uint64_t value)
 diff = cpu->env.timecmp - rtc_r;
 /* back to ns (note args switched in muldiv64) */
 next = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
-muldiv64(diff, NANOSECONDS_PER_SECOND, SIFIVE_CLINT_TIMEBASE_FREQ);
+muldiv64(diff, NANOSECONDS_PER_SECOND, cpu->env.time_freq);
 timer_mod(cpu->env.timer, next);
 }

@@ -107,11 +107,25 @@ static uint64_t sifive_clint_read(void *opaque, hwaddr 
addr, unsigned size)
 return 0;
 }
 } else if (addr == clint->time_base) {
-/* time_lo */
-return cpu_riscv_read_rtc() & 0x;
+/* All harts must have the same time frequency, so just use hart 0 */
+CPUState *cpu = qemu_get_cpu(0);
+CPURISCVState *env = cpu ? cpu->env_ptr : NULL;
+if (!env) {
+error_report("clint: hart 0 not valid?!");
+} else {
+/* time_lo */
+return cpu_riscv_read_rtc(env) & 0x;
+}
 } else if (addr == clint->time_base + 4) {
-/* time_hi */
-return (cpu_riscv_read_rtc() >> 32) & 0x;
+/* All harts must have the same time frequency, so just use hart 0 */
+CPUState *cpu = qemu_get_cpu(0);
+CPURISCVState *env = cpu ? cpu->env_ptr : NULL;
+if (!env) {
+error_report("clint: hart 0 not valid?!");
+} else {
+/* time_hi */
+return (cpu_riscv_read_rtc(env) >> 32) & 0x;
+}
 }

 error_report("clint: invalid read: %08x", (uint32_t)addr);
diff --git a/hw/riscv/sifive_e.c b/hw/riscv/sifive_e.c
index 80ac56fa7d..2d6f768ff1 100644
--- a/hw/risc

Re: [Qemu-devel] [PULL 01/29] SiFive RISC-V GPIO Device

2019-06-14 Thread Palmer Dabbelt

On Thu, 30 May 2019 03:57:12 PDT (-0700), Peter Maydell wrote:

On Sun, 26 May 2019 at 02:10, Palmer Dabbelt  wrote:


From: Fabien Chouteau 

QEMU model of the GPIO device on the SiFive E300 series SOCs.

The pins are not used by a board definition yet, however this
implementation can already be used to trigger GPIO interrupts from the
software by configuring a pin as both output and input.

Signed-off-by: Fabien Chouteau 
Reviewed-by: Palmer Dabbelt 
Signed-off-by: Palmer Dabbelt 


Hi; this patch causes Coverity to complain about a memory
leak (CID 1401707):


 static void riscv_sifive_e_soc_realize(DeviceState *dev, Error **errp)
 {
 const struct MemmapEntry *memmap = sifive_e_memmap;
+Error *err = NULL;

 SiFiveESoCState *s = RISCV_E_SOC(dev);
 MemoryRegion *sys_mem = get_system_memory();
@@ -184,8 +188,28 @@ static void riscv_sifive_e_soc_realize(DeviceState *dev, 
Error **errp)
 sifive_mmio_emulate(sys_mem, "riscv.sifive.e.aon",
 memmap[SIFIVE_E_AON].base, memmap[SIFIVE_E_AON].size);
 sifive_prci_create(memmap[SIFIVE_E_PRCI].base);
-sifive_mmio_emulate(sys_mem, "riscv.sifive.e.gpio0",
-memmap[SIFIVE_E_GPIO0].base, memmap[SIFIVE_E_GPIO0].size);
+
+/* GPIO */
+
+object_property_set_bool(OBJECT(&s->gpio), true, "realized", &err);
+if (err) {
+error_propagate(errp, err);
+return;
+}


This function allocated xip_mem and mask_rom via g_new() but
then this error-exit doesn't free them.

The best way to fix this is to stop doing separate memory
allocations at all -- instead just have fields in the
SiFiveESoCState struct
   MemoryRegion xip_mem;
   Memory_Region mask_rom;

and pass &s->xip_mem etc where currently the code uses xip_mem.


Sorry this took a while to fix, I've just sent a patch to fix the memory leak.



[Qemu-devel] [PATCH] RISC-V: Fix a memory leak when realizing a sifive_e

2019-06-14 Thread Palmer Dabbelt
Coverity pointed out a memory leak in riscv_sifive_e_soc_realize(),
where a pair of recently added MemoryRegion instances would not be freed
if there were errors elsewhere in the function.  The fix here is to
simply not use dynamic allocation for these instances: there's always
one of each in SiFiveESoCState, so instead we just include them within
the struct.

Thanks to Peter for pointing out the bug and suggesting the fix!

Fixes: 30efbf330a45 ("SiFive RISC-V GPIO Device")
Signed-off-by: Palmer Dabbelt 
---
 hw/riscv/sifive_e.c | 12 +---
 include/hw/riscv/sifive_e.h |  2 ++
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/hw/riscv/sifive_e.c b/hw/riscv/sifive_e.c
index 80ac56fa7d5e..83375afcd1d6 100644
--- a/hw/riscv/sifive_e.c
+++ b/hw/riscv/sifive_e.c
@@ -158,17 +158,15 @@ static void riscv_sifive_e_soc_realize(DeviceState *dev, 
Error **errp)
 
 SiFiveESoCState *s = RISCV_E_SOC(dev);
 MemoryRegion *sys_mem = get_system_memory();
-MemoryRegion *xip_mem = g_new(MemoryRegion, 1);
-MemoryRegion *mask_rom = g_new(MemoryRegion, 1);
 
 object_property_set_bool(OBJECT(&s->cpus), true, "realized",
 &error_abort);
 
 /* Mask ROM */
-memory_region_init_rom(mask_rom, NULL, "riscv.sifive.e.mrom",
+memory_region_init_rom(&s->mask_rom, NULL, "riscv.sifive.e.mrom",
 memmap[SIFIVE_E_MROM].size, &error_fatal);
 memory_region_add_subregion(sys_mem,
-memmap[SIFIVE_E_MROM].base, mask_rom);
+memmap[SIFIVE_E_MROM].base, &s->mask_rom);
 
 /* MMIO */
 s->plic = sifive_plic_create(memmap[SIFIVE_E_PLIC].base,
@@ -228,10 +226,10 @@ static void riscv_sifive_e_soc_realize(DeviceState *dev, 
Error **errp)
 memmap[SIFIVE_E_PWM2].base, memmap[SIFIVE_E_PWM2].size);
 
 /* Flash memory */
-memory_region_init_ram(xip_mem, NULL, "riscv.sifive.e.xip",
+memory_region_init_ram(&s->xip_mem, NULL, "riscv.sifive.e.xip",
 memmap[SIFIVE_E_XIP].size, &error_fatal);
-memory_region_set_readonly(xip_mem, true);
-memory_region_add_subregion(sys_mem, memmap[SIFIVE_E_XIP].base, xip_mem);
+memory_region_set_readonly(&s->xip_mem, true);
+memory_region_add_subregion(sys_mem, memmap[SIFIVE_E_XIP].base, 
&s->xip_mem);
 }
 
 static void riscv_sifive_e_machine_init(MachineClass *mc)
diff --git a/include/hw/riscv/sifive_e.h b/include/hw/riscv/sifive_e.h
index 3b14eb74621f..d175b24cb209 100644
--- a/include/hw/riscv/sifive_e.h
+++ b/include/hw/riscv/sifive_e.h
@@ -33,6 +33,8 @@ typedef struct SiFiveESoCState {
 RISCVHartArrayState cpus;
 DeviceState *plic;
 SIFIVEGPIOState gpio;
+MemoryRegion xip_mem;
+MemoryRegion mask_rom;
 } SiFiveESoCState;
 
 typedef struct SiFiveEState {
-- 
2.21.0




Re: [Qemu-devel] [PATCH] RISC-V: Fix a memory leak when realizing a sifive_e

2019-06-16 Thread Palmer Dabbelt

On Fri, 14 Jun 2019 05:25:50 PDT (-0700), phi...@redhat.com wrote:

On 6/14/19 2:08 PM, Palmer Dabbelt wrote:

Coverity pointed out a memory leak in riscv_sifive_e_soc_realize(),
where a pair of recently added MemoryRegion instances would not be freed
if there were errors elsewhere in the function.  The fix here is to
simply not use dynamic allocation for these instances: there's always
one of each in SiFiveESoCState, so instead we just include them within
the struct.

Thanks to Peter for pointing out the bug and suggesting the fix!


a.k.a. Suggested-by: Peter Maydell 

Maybe the thanks can go below the '---' tag, so it doesn't stay in the
git history.


Works for me.





Fixes: 30efbf330a45 ("SiFive RISC-V GPIO Device")
Signed-off-by: Palmer Dabbelt 


Reviewed-by: Philippe Mathieu-Daudé 


Thanks!




---
 hw/riscv/sifive_e.c | 12 +---
 include/hw/riscv/sifive_e.h |  2 ++
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/hw/riscv/sifive_e.c b/hw/riscv/sifive_e.c
index 80ac56fa7d5e..83375afcd1d6 100644
--- a/hw/riscv/sifive_e.c
+++ b/hw/riscv/sifive_e.c
@@ -158,17 +158,15 @@ static void riscv_sifive_e_soc_realize(DeviceState *dev, 
Error **errp)

 SiFiveESoCState *s = RISCV_E_SOC(dev);
 MemoryRegion *sys_mem = get_system_memory();
-MemoryRegion *xip_mem = g_new(MemoryRegion, 1);
-MemoryRegion *mask_rom = g_new(MemoryRegion, 1);

 object_property_set_bool(OBJECT(&s->cpus), true, "realized",
 &error_abort);

 /* Mask ROM */
-memory_region_init_rom(mask_rom, NULL, "riscv.sifive.e.mrom",
+memory_region_init_rom(&s->mask_rom, NULL, "riscv.sifive.e.mrom",
 memmap[SIFIVE_E_MROM].size, &error_fatal);
 memory_region_add_subregion(sys_mem,
-memmap[SIFIVE_E_MROM].base, mask_rom);
+memmap[SIFIVE_E_MROM].base, &s->mask_rom);

 /* MMIO */
 s->plic = sifive_plic_create(memmap[SIFIVE_E_PLIC].base,
@@ -228,10 +226,10 @@ static void riscv_sifive_e_soc_realize(DeviceState *dev, 
Error **errp)
 memmap[SIFIVE_E_PWM2].base, memmap[SIFIVE_E_PWM2].size);

 /* Flash memory */
-memory_region_init_ram(xip_mem, NULL, "riscv.sifive.e.xip",
+memory_region_init_ram(&s->xip_mem, NULL, "riscv.sifive.e.xip",
 memmap[SIFIVE_E_XIP].size, &error_fatal);
-memory_region_set_readonly(xip_mem, true);
-memory_region_add_subregion(sys_mem, memmap[SIFIVE_E_XIP].base, xip_mem);
+memory_region_set_readonly(&s->xip_mem, true);
+memory_region_add_subregion(sys_mem, memmap[SIFIVE_E_XIP].base, 
&s->xip_mem);
 }

 static void riscv_sifive_e_machine_init(MachineClass *mc)
diff --git a/include/hw/riscv/sifive_e.h b/include/hw/riscv/sifive_e.h
index 3b14eb74621f..d175b24cb209 100644
--- a/include/hw/riscv/sifive_e.h
+++ b/include/hw/riscv/sifive_e.h
@@ -33,6 +33,8 @@ typedef struct SiFiveESoCState {
 RISCVHartArrayState cpus;
 DeviceState *plic;
 SIFIVEGPIOState gpio;
+MemoryRegion xip_mem;
+MemoryRegion mask_rom;
 } SiFiveESoCState;

 typedef struct SiFiveEState {





Re: [Qemu-devel] [PATCH] riscv/Kconfig: enable PCI_DEVICES

2019-03-12 Thread Palmer Dabbelt

On Mon, 11 Mar 2019 06:52:33 PDT (-0700), pbonz...@redhat.com wrote:

On 11/03/19 13:46, Thomas Huth wrote:

On 11/03/2019 10.12, David Abdurachmanov wrote:

Re-enable PCI_DEVICES for RISC-V.
The patch is based on other /Kconfig.

Signed-off-by: David Abdurachmanov 
Fixes: 82a230d5a303 ("riscv-softmmu.mak: replace CONFIG_* with Kconfig "select" 
directives")
---
 hw/riscv/Kconfig | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig
index e0ee3043a6..8c7fc1f31d 100644
--- a/hw/riscv/Kconfig
+++ b/hw/riscv/Kconfig
@@ -26,6 +26,9 @@ config SPIKE

 config RISCV_VIRT
 bool
+imply PCI_DEVICES
+imply TEST_DEVICES
+select PCI
 select HART
 select SERIAL
 select VIRTIO_MMIO



Reviewed-by: Thomas Huth 



Queued, thanks.


Thanks for picking this up!



[Qemu-devel] [PULL 25/29] target/riscv: Remove shift and slt insn manual decoding

2019-03-12 Thread Palmer Dabbelt
From: Bastian Koppelmann 

Reviewed-by: Richard Henderson 
Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 
Signed-off-by: Palmer Dabbelt 
---
 target/riscv/insn_trans/trans_rvi.inc.c | 93 +
 target/riscv/translate.c| 59 +---
 2 files changed, 81 insertions(+), 71 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvi.inc.c 
b/target/riscv/insn_trans/trans_rvi.inc.c
index 8879f2da35c7..88ef0003ec17 100644
--- a/target/riscv/insn_trans/trans_rvi.inc.c
+++ b/target/riscv/insn_trans/trans_rvi.inc.c
@@ -220,30 +220,25 @@ static bool trans_addi(DisasContext *ctx, arg_addi *a)
 return gen_arith_imm(ctx, a, &tcg_gen_add_tl);
 }
 
-static bool trans_slti(DisasContext *ctx, arg_slti *a)
+static void gen_slt(TCGv ret, TCGv s1, TCGv s2)
 {
-TCGv source1;
-source1 = tcg_temp_new();
-gen_get_gpr(source1, a->rs1);
+tcg_gen_setcond_tl(TCG_COND_LT, ret, s1, s2);
+}
+
+static void gen_sltu(TCGv ret, TCGv s1, TCGv s2)
+{
+tcg_gen_setcond_tl(TCG_COND_LTU, ret, s1, s2);
+}
 
-tcg_gen_setcondi_tl(TCG_COND_LT, source1, source1, a->imm);
 
-gen_set_gpr(a->rd, source1);
-tcg_temp_free(source1);
-return true;
+static bool trans_slti(DisasContext *ctx, arg_slti *a)
+{
+return gen_arith_imm(ctx, a, &gen_slt);
 }
 
 static bool trans_sltiu(DisasContext *ctx, arg_sltiu *a)
 {
-TCGv source1;
-source1 = tcg_temp_new();
-gen_get_gpr(source1, a->rs1);
-
-tcg_gen_setcondi_tl(TCG_COND_LTU, source1, source1, a->imm);
-
-gen_set_gpr(a->rd, source1);
-tcg_temp_free(source1);
-return true;
+return gen_arith_imm(ctx, a, &gen_sltu);
 }
 
 static bool trans_xori(DisasContext *ctx, arg_xori *a)
@@ -322,20 +317,17 @@ static bool trans_sub(DisasContext *ctx, arg_sub *a)
 
 static bool trans_sll(DisasContext *ctx, arg_sll *a)
 {
-gen_arith(ctx, OPC_RISC_SLL, a->rd, a->rs1, a->rs2);
-return true;
+return gen_shift(ctx, a, &tcg_gen_shl_tl);
 }
 
 static bool trans_slt(DisasContext *ctx, arg_slt *a)
 {
-gen_arith(ctx, OPC_RISC_SLT, a->rd, a->rs1, a->rs2);
-return true;
+return trans_arith(ctx, a, &gen_slt);
 }
 
 static bool trans_sltu(DisasContext *ctx, arg_sltu *a)
 {
-gen_arith(ctx, OPC_RISC_SLTU, a->rd, a->rs1, a->rs2);
-return true;
+return trans_arith(ctx, a, &gen_sltu);
 }
 
 static bool trans_xor(DisasContext *ctx, arg_xor *a)
@@ -345,14 +337,12 @@ static bool trans_xor(DisasContext *ctx, arg_xor *a)
 
 static bool trans_srl(DisasContext *ctx, arg_srl *a)
 {
-gen_arith(ctx, OPC_RISC_SRL, a->rd, a->rs1, a->rs2);
-return true;
+return gen_shift(ctx, a, &tcg_gen_shr_tl);
 }
 
 static bool trans_sra(DisasContext *ctx, arg_sra *a)
 {
-gen_arith(ctx, OPC_RISC_SRA, a->rd, a->rs1, a->rs2);
-return true;
+return gen_shift(ctx, a, &tcg_gen_sar_tl);
 }
 
 static bool trans_or(DisasContext *ctx, arg_or *a)
@@ -419,19 +409,62 @@ static bool trans_subw(DisasContext *ctx, arg_subw *a)
 
 static bool trans_sllw(DisasContext *ctx, arg_sllw *a)
 {
-gen_arith(ctx, OPC_RISC_SLLW, a->rd, a->rs1, a->rs2);
+TCGv source1 = tcg_temp_new();
+TCGv source2 = tcg_temp_new();
+
+gen_get_gpr(source1, a->rs1);
+gen_get_gpr(source2, a->rs2);
+
+tcg_gen_andi_tl(source2, source2, 0x1F);
+tcg_gen_shl_tl(source1, source1, source2);
+
+tcg_gen_ext32s_tl(source1, source1);
+gen_set_gpr(a->rd, source1);
+tcg_temp_free(source1);
+tcg_temp_free(source2);
 return true;
 }
 
 static bool trans_srlw(DisasContext *ctx, arg_srlw *a)
 {
-gen_arith(ctx, OPC_RISC_SRLW, a->rd, a->rs1, a->rs2);
+TCGv source1 = tcg_temp_new();
+TCGv source2 = tcg_temp_new();
+
+gen_get_gpr(source1, a->rs1);
+gen_get_gpr(source2, a->rs2);
+
+/* clear upper 32 */
+tcg_gen_ext32u_tl(source1, source1);
+tcg_gen_andi_tl(source2, source2, 0x1F);
+tcg_gen_shr_tl(source1, source1, source2);
+
+tcg_gen_ext32s_tl(source1, source1);
+gen_set_gpr(a->rd, source1);
+tcg_temp_free(source1);
+tcg_temp_free(source2);
 return true;
 }
 
 static bool trans_sraw(DisasContext *ctx, arg_sraw *a)
 {
-gen_arith(ctx, OPC_RISC_SRAW, a->rd, a->rs1, a->rs2);
+TCGv source1 = tcg_temp_new();
+TCGv source2 = tcg_temp_new();
+
+gen_get_gpr(source1, a->rs1);
+gen_get_gpr(source2, a->rs2);
+
+/*
+ * first, trick to get it to act like working on 32 bits (get rid of
+ * upper 32, sign extend to fill space)
+ */
+tcg_gen_ext32s_tl(source1, source1);
+tcg_gen_andi_tl(source2, source2, 0x1F);
+tcg_gen_sar_tl(source1, source1, source2);
+
+gen_set_gpr(a->rd, source1);
+tcg_temp_free(source1);
+tcg_temp_free(source2);
+
 return true;
 }
 #endif
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 8eb883463322..9ae40f65096f

[Qemu-devel] [PULL 28/29] target/riscv: Remove gen_system()

2019-03-12 Thread Palmer Dabbelt
From: Bastian Koppelmann 

with all 16 bit insns moved to decodetree no path is falling back to
gen_system(), so we can remove it.

Reviewed-by: Richard Henderson 
Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 
Signed-off-by: Palmer Dabbelt 
---
 target/riscv/translate.c | 34 --
 1 file changed, 34 deletions(-)

diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index dedf4189d5b7..92be090bc7bb 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -473,33 +473,6 @@ static void gen_set_rm(DisasContext *ctx, int rm)
 tcg_temp_free_i32(t0);
 }
 
-static void gen_system(DisasContext *ctx, uint32_t opc, int rd, int rs1,
-   int csr)
-{
-tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next);
-
-switch (opc) {
-case OPC_RISC_ECALL:
-switch (csr) {
-case 0x0: /* ECALL */
-/* always generates U-level ECALL, fixed in do_interrupt handler */
-generate_exception(ctx, RISCV_EXCP_U_ECALL);
-tcg_gen_exit_tb(NULL, 0); /* no chaining */
-ctx->base.is_jmp = DISAS_NORETURN;
-break;
-case 0x1: /* EBREAK */
-generate_exception(ctx, RISCV_EXCP_BREAKPOINT);
-tcg_gen_exit_tb(NULL, 0); /* no chaining */
-ctx->base.is_jmp = DISAS_NORETURN;
-break;
-default:
-gen_exception_illegal(ctx);
-break;
-}
-break;
-}
-}
-
 static void decode_RV32_64C0(DisasContext *ctx)
 {
 uint8_t funct3 = extract32(ctx->opcode, 13, 3);
@@ -680,7 +653,6 @@ bool decode_insn16(DisasContext *ctx, uint16_t insn);
 
 static void decode_RV32_64G(DisasContext *ctx)
 {
-int rs1, rd;
 uint32_t op;
 
 /* We do not do misaligned address check here: the address should never be
@@ -689,14 +661,8 @@ static void decode_RV32_64G(DisasContext *ctx)
  * perform the misaligned instruction fetch */
 
 op = MASK_OP_MAJOR(ctx->opcode);
-rs1 = GET_RS1(ctx->opcode);
-rd = GET_RD(ctx->opcode);
 
 switch (op) {
-case OPC_RISC_SYSTEM:
-gen_system(ctx, MASK_OP_SYSTEM(ctx->opcode), rd, rs1,
-   (ctx->opcode & 0xFFF0) >> 20);
-break;
 default:
 gen_exception_illegal(ctx);
 break;
-- 
2.19.2




[Qemu-devel] [PULL 21/29] target/riscv: Remove manual decoding from gen_load()

2019-03-12 Thread Palmer Dabbelt
From: Bastian Koppelmann 

With decodetree we don't need to convert RISC-V opcodes into to MemOps
as the old gen_load() did.

Reviewed-by: Richard Henderson 
Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 
Signed-off-by: Palmer Dabbelt 
---
 target/riscv/insn_trans/trans_rvi.inc.c | 35 +++--
 target/riscv/translate.c|  6 +++--
 2 files changed, 25 insertions(+), 16 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvi.inc.c 
b/target/riscv/insn_trans/trans_rvi.inc.c
index ae4b0a2bcb78..cc361ed4d151 100644
--- a/target/riscv/insn_trans/trans_rvi.inc.c
+++ b/target/riscv/insn_trans/trans_rvi.inc.c
@@ -129,34 +129,43 @@ static bool trans_bgeu(DisasContext *ctx, arg_bgeu *a)
 return gen_branch(ctx, a, TCG_COND_GEU);
 }
 
-static bool trans_lb(DisasContext *ctx, arg_lb *a)
+static bool gen_load(DisasContext *ctx, arg_lb *a, TCGMemOp memop)
 {
-gen_load(ctx, OPC_RISC_LB, a->rd, a->rs1, a->imm);
+TCGv t0 = tcg_temp_new();
+TCGv t1 = tcg_temp_new();
+gen_get_gpr(t0, a->rs1);
+tcg_gen_addi_tl(t0, t0, a->imm);
+
+tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, memop);
+gen_set_gpr(a->rd, t1);
+tcg_temp_free(t0);
+tcg_temp_free(t1);
 return true;
 }
 
+static bool trans_lb(DisasContext *ctx, arg_lb *a)
+{
+return gen_load(ctx, a, MO_SB);
+}
+
 static bool trans_lh(DisasContext *ctx, arg_lh *a)
 {
-gen_load(ctx, OPC_RISC_LH, a->rd, a->rs1, a->imm);
-return true;
+return gen_load(ctx, a, MO_TESW);
 }
 
 static bool trans_lw(DisasContext *ctx, arg_lw *a)
 {
-gen_load(ctx, OPC_RISC_LW, a->rd, a->rs1, a->imm);
-return true;
+return gen_load(ctx, a, MO_TESL);
 }
 
 static bool trans_lbu(DisasContext *ctx, arg_lbu *a)
 {
-gen_load(ctx, OPC_RISC_LBU, a->rd, a->rs1, a->imm);
-return true;
+return gen_load(ctx, a, MO_UB);
 }
 
 static bool trans_lhu(DisasContext *ctx, arg_lhu *a)
 {
-gen_load(ctx, OPC_RISC_LHU, a->rd, a->rs1, a->imm);
-return true;
+return gen_load(ctx, a, MO_TEUW);
 }
 
 static bool trans_sb(DisasContext *ctx, arg_sb *a)
@@ -180,14 +189,12 @@ static bool trans_sw(DisasContext *ctx, arg_sw *a)
 #ifdef TARGET_RISCV64
 static bool trans_lwu(DisasContext *ctx, arg_lwu *a)
 {
-gen_load(ctx, OPC_RISC_LWU, a->rd, a->rs1, a->imm);
-return true;
+return gen_load(ctx, a, MO_TEUL);
 }
 
 static bool trans_ld(DisasContext *ctx, arg_ld *a)
 {
-gen_load(ctx, OPC_RISC_LD, a->rd, a->rs1, a->imm);
-return true;
+return gen_load(ctx, a, MO_TEQ);
 }
 
 static bool trans_sd(DisasContext *ctx, arg_sd *a)
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index a3d5cdbad82d..99d6d3b4ae91 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -531,7 +531,8 @@ static void gen_jal(DisasContext *ctx, int rd, target_ulong 
imm)
 ctx->base.is_jmp = DISAS_NORETURN;
 }
 
-static void gen_load(DisasContext *ctx, uint32_t opc, int rd, int rs1,
+#ifdef TARGET_RISCV64
+static void gen_load_c(DisasContext *ctx, uint32_t opc, int rd, int rs1,
 target_long imm)
 {
 TCGv t0 = tcg_temp_new();
@@ -550,6 +551,7 @@ static void gen_load(DisasContext *ctx, uint32_t opc, int 
rd, int rs1,
 tcg_temp_free(t0);
 tcg_temp_free(t1);
 }
+#endif
 
 static void gen_store(DisasContext *ctx, uint32_t opc, int rs1, int rs2,
 target_long imm)
@@ -723,7 +725,7 @@ static void decode_RV32_64C0(DisasContext *ctx)
 case 3:
 #if defined(TARGET_RISCV64)
 /* C.LD(RV64/128) -> ld rd', offset[7:3](rs1')*/
-gen_load(ctx, OPC_RISC_LD, rd_rs2, rs1s,
+gen_load_c(ctx, OPC_RISC_LD, rd_rs2, rs1s,
  GET_C_LD_IMM(ctx->opcode));
 #else
 /* C.FLW (RV32) -> flw rd', offset[6:2](rs1')*/
-- 
2.19.2




[Qemu-devel] [PULL 29/29] target/riscv: Remove decode_RV32_64G()

2019-03-12 Thread Palmer Dabbelt
From: Bastian Koppelmann 

decodetree handles all instructions now so the fallback is not necessary
anymore.

Reviewed-by: Richard Henderson 
Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 
Signed-off-by: Palmer Dabbelt 
---
 target/riscv/translate.c | 21 +
 1 file changed, 1 insertion(+), 20 deletions(-)

diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 92be090bc7bb..049fa65c6611 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -651,24 +651,6 @@ bool decode_insn16(DisasContext *ctx, uint16_t insn);
 #include "decode_insn16.inc.c"
 #include "insn_trans/trans_rvc.inc.c"
 
-static void decode_RV32_64G(DisasContext *ctx)
-{
-uint32_t op;
-
-/* We do not do misaligned address check here: the address should never be
- * misaligned at this point. Instructions that set PC must do the check,
- * since epc must be the address of the instruction that caused us to
- * perform the misaligned instruction fetch */
-
-op = MASK_OP_MAJOR(ctx->opcode);
-
-switch (op) {
-default:
-gen_exception_illegal(ctx);
-break;
-}
-}
-
 static void decode_opc(DisasContext *ctx)
 {
 /* check for compressed insn */
@@ -685,8 +667,7 @@ static void decode_opc(DisasContext *ctx)
 } else {
 ctx->pc_succ_insn = ctx->base.pc_next + 4;
 if (!decode_insn32(ctx, ctx->opcode)) {
-/* fallback to old decoder */
-decode_RV32_64G(ctx);
+gen_exception_illegal(ctx);
 }
 }
 }
-- 
2.19.2




[Qemu-devel] [PULL 27/29] target/riscv: Rename trans_arith to gen_arith

2019-03-12 Thread Palmer Dabbelt
From: Bastian Koppelmann 

Reviewed-by: Richard Henderson 
Signed-off-by: Bastian Koppelmann 
Signed-off-by: Palmer Dabbelt 
---
 target/riscv/insn_trans/trans_rvi.inc.c | 18 +-
 target/riscv/insn_trans/trans_rvm.inc.c | 14 +++---
 target/riscv/translate.c|  4 ++--
 3 files changed, 18 insertions(+), 18 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvi.inc.c 
b/target/riscv/insn_trans/trans_rvi.inc.c
index 88ef0003ec17..d420a4d8b2e9 100644
--- a/target/riscv/insn_trans/trans_rvi.inc.c
+++ b/target/riscv/insn_trans/trans_rvi.inc.c
@@ -307,12 +307,12 @@ static bool trans_srai(DisasContext *ctx, arg_srai *a)
 
 static bool trans_add(DisasContext *ctx, arg_add *a)
 {
-return trans_arith(ctx, a, &tcg_gen_add_tl);
+return gen_arith(ctx, a, &tcg_gen_add_tl);
 }
 
 static bool trans_sub(DisasContext *ctx, arg_sub *a)
 {
-return trans_arith(ctx, a, &tcg_gen_sub_tl);
+return gen_arith(ctx, a, &tcg_gen_sub_tl);
 }
 
 static bool trans_sll(DisasContext *ctx, arg_sll *a)
@@ -322,17 +322,17 @@ static bool trans_sll(DisasContext *ctx, arg_sll *a)
 
 static bool trans_slt(DisasContext *ctx, arg_slt *a)
 {
-return trans_arith(ctx, a, &gen_slt);
+return gen_arith(ctx, a, &gen_slt);
 }
 
 static bool trans_sltu(DisasContext *ctx, arg_sltu *a)
 {
-return trans_arith(ctx, a, &gen_sltu);
+return gen_arith(ctx, a, &gen_sltu);
 }
 
 static bool trans_xor(DisasContext *ctx, arg_xor *a)
 {
-return trans_arith(ctx, a, &tcg_gen_xor_tl);
+return gen_arith(ctx, a, &tcg_gen_xor_tl);
 }
 
 static bool trans_srl(DisasContext *ctx, arg_srl *a)
@@ -347,12 +347,12 @@ static bool trans_sra(DisasContext *ctx, arg_sra *a)
 
 static bool trans_or(DisasContext *ctx, arg_or *a)
 {
-return trans_arith(ctx, a, &tcg_gen_or_tl);
+return gen_arith(ctx, a, &tcg_gen_or_tl);
 }
 
 static bool trans_and(DisasContext *ctx, arg_and *a)
 {
-return trans_arith(ctx, a, &tcg_gen_and_tl);
+return gen_arith(ctx, a, &tcg_gen_and_tl);
 }
 
 #ifdef TARGET_RISCV64
@@ -399,12 +399,12 @@ static bool trans_sraiw(DisasContext *ctx, arg_sraiw *a)
 
 static bool trans_addw(DisasContext *ctx, arg_addw *a)
 {
-return trans_arith(ctx, a, &gen_addw);
+return gen_arith(ctx, a, &gen_addw);
 }
 
 static bool trans_subw(DisasContext *ctx, arg_subw *a)
 {
-return trans_arith(ctx, a, &gen_subw);
+return gen_arith(ctx, a, &gen_subw);
 }
 
 static bool trans_sllw(DisasContext *ctx, arg_sllw *a)
diff --git a/target/riscv/insn_trans/trans_rvm.inc.c 
b/target/riscv/insn_trans/trans_rvm.inc.c
index d2bf2f171904..204af225f8f3 100644
--- a/target/riscv/insn_trans/trans_rvm.inc.c
+++ b/target/riscv/insn_trans/trans_rvm.inc.c
@@ -22,7 +22,7 @@
 static bool trans_mul(DisasContext *ctx, arg_mul *a)
 {
 REQUIRE_EXT(ctx, RVM);
-return trans_arith(ctx, a, &tcg_gen_mul_tl);
+return gen_arith(ctx, a, &tcg_gen_mul_tl);
 }
 
 static bool trans_mulh(DisasContext *ctx, arg_mulh *a)
@@ -44,7 +44,7 @@ static bool trans_mulh(DisasContext *ctx, arg_mulh *a)
 static bool trans_mulhsu(DisasContext *ctx, arg_mulhsu *a)
 {
 REQUIRE_EXT(ctx, RVM);
-return trans_arith(ctx, a, &gen_mulhsu);
+return gen_arith(ctx, a, &gen_mulhsu);
 }
 
 static bool trans_mulhu(DisasContext *ctx, arg_mulhu *a)
@@ -66,32 +66,32 @@ static bool trans_mulhu(DisasContext *ctx, arg_mulhu *a)
 static bool trans_div(DisasContext *ctx, arg_div *a)
 {
 REQUIRE_EXT(ctx, RVM);
-return trans_arith(ctx, a, &gen_div);
+return gen_arith(ctx, a, &gen_div);
 }
 
 static bool trans_divu(DisasContext *ctx, arg_divu *a)
 {
 REQUIRE_EXT(ctx, RVM);
-return trans_arith(ctx, a, &gen_divu);
+return gen_arith(ctx, a, &gen_divu);
 }
 
 static bool trans_rem(DisasContext *ctx, arg_rem *a)
 {
 REQUIRE_EXT(ctx, RVM);
-return trans_arith(ctx, a, &gen_rem);
+return gen_arith(ctx, a, &gen_rem);
 }
 
 static bool trans_remu(DisasContext *ctx, arg_remu *a)
 {
 REQUIRE_EXT(ctx, RVM);
-return trans_arith(ctx, a, &gen_remu);
+return gen_arith(ctx, a, &gen_remu);
 }
 
 #ifdef TARGET_RISCV64
 static bool trans_mulw(DisasContext *ctx, arg_mulw *a)
 {
 REQUIRE_EXT(ctx, RVM);
-return trans_arith(ctx, a, &gen_mulw);
+return gen_arith(ctx, a, &gen_mulw);
 }
 
 static bool trans_divw(DisasContext *ctx, arg_divw *a)
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 3cd7e16c63cf..dedf4189d5b7 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -629,8 +629,8 @@ static bool gen_arith_div_w(DisasContext *ctx, arg_r *a,
 
 #endif
 
-static bool trans_arith(DisasContext *ctx, arg_r *a,
-void(*func)(TCGv, TCGv, TCGv))
+static bool gen_arith(DisasContext *ctx, arg_r *a,
+  void(*func)(TCGv, TCGv, TCGv))
 {
 TCGv source1, source2;
 source1 = tcg_temp_new();
-- 
2.19.2




[Qemu-devel] [PULL 26/29] target/riscv: Remove manual decoding of RV32/64M insn

2019-03-12 Thread Palmer Dabbelt
From: Bastian Koppelmann 

Reviewed-by: Richard Henderson 
Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 
Signed-off-by: Palmer Dabbelt 
---
 target/riscv/insn_trans/trans_rvm.inc.c |  55 ++--
 target/riscv/translate.c| 320 ++--
 2 files changed, 164 insertions(+), 211 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvm.inc.c 
b/target/riscv/insn_trans/trans_rvm.inc.c
index 69631c9e3783..d2bf2f171904 100644
--- a/target/riscv/insn_trans/trans_rvm.inc.c
+++ b/target/riscv/insn_trans/trans_rvm.inc.c
@@ -22,92 +22,99 @@
 static bool trans_mul(DisasContext *ctx, arg_mul *a)
 {
 REQUIRE_EXT(ctx, RVM);
-gen_arith(ctx, OPC_RISC_MUL, a->rd, a->rs1, a->rs2);
-return true;
+return trans_arith(ctx, a, &tcg_gen_mul_tl);
 }
 
 static bool trans_mulh(DisasContext *ctx, arg_mulh *a)
 {
 REQUIRE_EXT(ctx, RVM);
-gen_arith(ctx, OPC_RISC_MULH, a->rd, a->rs1, a->rs2);
+TCGv source1 = tcg_temp_new();
+TCGv source2 = tcg_temp_new();
+gen_get_gpr(source1, a->rs1);
+gen_get_gpr(source2, a->rs2);
+
+tcg_gen_muls2_tl(source2, source1, source1, source2);
+
+gen_set_gpr(a->rd, source1);
+tcg_temp_free(source1);
+tcg_temp_free(source2);
 return true;
 }
 
 static bool trans_mulhsu(DisasContext *ctx, arg_mulhsu *a)
 {
 REQUIRE_EXT(ctx, RVM);
-gen_arith(ctx, OPC_RISC_MULHSU, a->rd, a->rs1, a->rs2);
-return true;
+return trans_arith(ctx, a, &gen_mulhsu);
 }
 
 static bool trans_mulhu(DisasContext *ctx, arg_mulhu *a)
 {
 REQUIRE_EXT(ctx, RVM);
-gen_arith(ctx, OPC_RISC_MULHU, a->rd, a->rs1, a->rs2);
+TCGv source1 = tcg_temp_new();
+TCGv source2 = tcg_temp_new();
+gen_get_gpr(source1, a->rs1);
+gen_get_gpr(source2, a->rs2);
+
+tcg_gen_mulu2_tl(source2, source1, source1, source2);
+
+gen_set_gpr(a->rd, source1);
+tcg_temp_free(source1);
+tcg_temp_free(source2);
 return true;
 }
 
 static bool trans_div(DisasContext *ctx, arg_div *a)
 {
 REQUIRE_EXT(ctx, RVM);
-gen_arith(ctx, OPC_RISC_DIV, a->rd, a->rs1, a->rs2);
-return true;
+return trans_arith(ctx, a, &gen_div);
 }
 
 static bool trans_divu(DisasContext *ctx, arg_divu *a)
 {
 REQUIRE_EXT(ctx, RVM);
-gen_arith(ctx, OPC_RISC_DIVU, a->rd, a->rs1, a->rs2);
-return true;
+return trans_arith(ctx, a, &gen_divu);
 }
 
 static bool trans_rem(DisasContext *ctx, arg_rem *a)
 {
 REQUIRE_EXT(ctx, RVM);
-gen_arith(ctx, OPC_RISC_REM, a->rd, a->rs1, a->rs2);
-return true;
+return trans_arith(ctx, a, &gen_rem);
 }
 
 static bool trans_remu(DisasContext *ctx, arg_remu *a)
 {
 REQUIRE_EXT(ctx, RVM);
-gen_arith(ctx, OPC_RISC_REMU, a->rd, a->rs1, a->rs2);
-return true;
+return trans_arith(ctx, a, &gen_remu);
 }
 
 #ifdef TARGET_RISCV64
 static bool trans_mulw(DisasContext *ctx, arg_mulw *a)
 {
 REQUIRE_EXT(ctx, RVM);
-gen_arith(ctx, OPC_RISC_MULW, a->rd, a->rs1, a->rs2);
-return true;
+return trans_arith(ctx, a, &gen_mulw);
 }
 
 static bool trans_divw(DisasContext *ctx, arg_divw *a)
 {
 REQUIRE_EXT(ctx, RVM);
-gen_arith(ctx, OPC_RISC_DIVW, a->rd, a->rs1, a->rs2);
-return true;
+return gen_arith_div_w(ctx, a, &gen_div);
 }
 
 static bool trans_divuw(DisasContext *ctx, arg_divuw *a)
 {
 REQUIRE_EXT(ctx, RVM);
-gen_arith(ctx, OPC_RISC_DIVUW, a->rd, a->rs1, a->rs2);
-return true;
+return gen_arith_div_w(ctx, a, &gen_divu);
 }
 
 static bool trans_remw(DisasContext *ctx, arg_remw *a)
 {
 REQUIRE_EXT(ctx, RVM);
-gen_arith(ctx, OPC_RISC_REMW, a->rd, a->rs1, a->rs2);
-return true;
+return gen_arith_div_w(ctx, a, &gen_rem);
 }
 
 static bool trans_remuw(DisasContext *ctx, arg_remuw *a)
 {
 REQUIRE_EXT(ctx, RVM);
-gen_arith(ctx, OPC_RISC_REMUW, a->rd, a->rs1, a->rs2);
-return true;
+return gen_arith_div_w(ctx, a, &gen_remu);
 }
 #endif
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 9ae40f65096f..3cd7e16c63cf 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -188,193 +188,112 @@ static void gen_mulhsu(TCGv ret, TCGv arg1, TCGv arg2)
 tcg_temp_free(rh);
 }
 
-static void gen_arith(DisasContext *ctx, uint32_t opc, int rd, int rs1,
-int rs2)
-{
-TCGv source1, source2, cond1, cond2, zeroreg, resultopt1;
-source1 = tcg_temp_new();
-source2 = tcg_temp_new();
-gen_get_gpr(source1, rs1);
-gen_get_gpr(source2, rs2);
-
-switch (opc) {
-CASE_OP_32_64(OPC_RISC_MUL):
-if (!has_ext(ctx, RVM)) {
-goto do_illegal;
-}
-tcg_gen_mul_tl(source1, source1, source2);
-break;
-case OPC_RISC_MULH:
-if (!has_ext(ctx, RVM)) {
-goto do_illegal;
-}
-tcg_gen_muls2_tl(source2, sour

[Qemu-devel] [PULL 18/29] target/riscv: Convert quadrant 2 of RVXC insns to decodetree

2019-03-12 Thread Palmer Dabbelt
From: Bastian Koppelmann 

Reviewed-by: Richard Henderson 
Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 
Signed-off-by: Palmer Dabbelt 
---
 target/riscv/insn16.decode  |  31 
 target/riscv/insn_trans/trans_rvc.inc.c | 101 
 target/riscv/translate.c|  83 +--
 3 files changed, 134 insertions(+), 81 deletions(-)

diff --git a/target/riscv/insn16.decode b/target/riscv/insn16.decode
index 29dade0fa1ae..0829e3bc592d 100644
--- a/target/riscv/insn16.decode
+++ b/target/riscv/insn16.decode
@@ -20,6 +20,7 @@
 %rd7:5
 %rs1_3 7:3!function=ex_rvc_register
 %rs2_3 2:3!function=ex_rvc_register
+%rs2_5 2:5
 
 # Immediates:
 %imm_ci12:s1 2:5
@@ -30,6 +31,10 @@
 %imm_cj12:s1 8:1 9:2 6:1 7:1 2:1 11:1 3:3 !function=ex_shift_1
 
 %nzuimm_6bit   12:1 2:5
+%uimm_6bit_ld 2:3 12:1 5:2   !function=ex_shift_3
+%uimm_6bit_lw 2:2 12:1 4:3   !function=ex_shift_2
+%uimm_6bit_sd 7:3 10:3   !function=ex_shift_3
+%uimm_6bit_sw 7:2 9:4!function=ex_shift_2
 
 %imm_addi16sp  12:s1 3:2 5:1 2:1 6:1 !function=ex_shift_4
 %imm_lui   12:s1 2:5 !function=ex_shift_12
@@ -48,10 +53,15 @@
 &c_j   imm
 &c_shift   shamt  rd
 
+&c_ld  uimm  rd
+&c_sd  uimm  rs2
 
 &c_addi16sp_lui  imm_lui imm_addi16sp rd
+&c_flwsp_ldspuimm_flwsp uimm_ldsp rd
+&c_fswsp_sdspuimm_fswsp uimm_sdsp rs2
 
 # Formats 16:
+@cr  . .  .. &cr  rs2=%rs2_5  %rd
 @ci... . . .  .. &ci imm=%imm_ci  %rd
 @ciw   ...    ... .. &ciwnzuimm=%nzuimm_ciw   rd=%rs2_3
 @cl_d  ... ... ... .. ... .. &cl_dw  uimm=%uimm_cl_d  rs1=%rs1_3  rd=%rs2_3
@@ -64,9 +74,19 @@
 @cb... ... ... .. ... .. &cb imm=%imm_cb  rs1=%rs1_3
 @cj...... .. &c_jimm=%imm_cj
 
+@c_ld  ... . .  . .. &c_ld uimm=%uimm_6bit_ld  %rd
+@c_lw  ... . .  . .. &c_ld uimm=%uimm_6bit_lw  %rd
+@c_sd  ... . .  . .. &c_sd uimm=%uimm_6bit_sd  rs2=%rs2_5
+@c_sw  ... . .  . .. &c_sd uimm=%uimm_6bit_sw  rs2=%rs2_5
+
 @c_addi16sp_lui ... .  . . .. &c_addi16sp_lui %imm_lui %imm_addi16sp 
%rd
+@c_flwsp_ldsp   ... .  . . .. &c_flwsp_ldsp uimm_flwsp=%uimm_6bit_lw \
+uimm_ldsp=%uimm_6bit_ld %rd
+@c_fswsp_sdsp   ... .  . . .. &c_fswsp_sdsp uimm_fswsp=%uimm_6bit_sw \
+uimm_sdsp=%uimm_6bit_sd rs2=%rs2_5
 
 @c_shift... . .. ... . .. &c_shift rd=%rs1_3 shamt=%nzuimm_6bit
+@c_shift2   ... . .. ... . .. &c_shift rd=%rdshamt=%nzuimm_6bit
 
 @c_andi ... . .. ... . .. &ci imm=%imm_ci rd=%rs1_3
 
@@ -96,3 +116,14 @@ c_addw100 1 11 ... 01 ... 01 @cs_2
 c_j   101 ... 01 @cj
 c_beqz110  ... ...  . 01 @cb
 c_bnez111  ... ...  . 01 @cb
+
+# *** RV64C Standard Extension (Quadrant 2) ***
+c_slli000 .  .  . 10 @c_shift2
+c_fldsp   001 .  .  . 10 @c_ld
+c_lwsp010 .  .  . 10 @c_lw
+c_flwsp_ldsp  011 .  .  . 10 @c_flwsp_ldsp 
#C.LDSP:RV64;C.FLWSP:RV32
+c_jr_mv   100 0  .  . 10 @cr
+c_ebreak_jalr_add 100 1  .  . 10 @cr
+c_fsdsp   101   ..  . 10 @c_sd
+c_swsp110 .  .  . 10 @c_sw
+c_fswsp_sdsp  111 .  .  . 10 @c_fswsp_sdsp 
#C.SDSP:RV64;C.FSWSP:RV32
diff --git a/target/riscv/insn_trans/trans_rvc.inc.c 
b/target/riscv/insn_trans/trans_rvc.inc.c
index b06c435c9800..bcdf64d3b705 100644
--- a/target/riscv/insn_trans/trans_rvc.inc.c
+++ b/target/riscv/insn_trans/trans_rvc.inc.c
@@ -224,3 +224,104 @@ static bool trans_c_bnez(DisasContext *ctx, arg_c_bnez *a)
 arg_bne arg = { .rs1 = a->rs1, .rs2 = 0, .imm = a->imm };
 return trans_bne(ctx, &arg);
 }
+
+static bool trans_c_slli(DisasContext *ctx, arg_c_slli *a)
+{
+int shamt = a->shamt;
+if (shamt == 0) {
+/* For RV128 a shamt of 0 means a shift by 64 */
+shamt = 64;
+}
+/* Ensure, that shamt[5] is zero for RV32 */
+if (shamt >= TARGET_LONG_BITS) {
+return false;
+}
+
+arg_slli arg = { .rd = a->rd, .rs1 = a->rd, .shamt = a->shamt };
+return trans_slli(ctx, &arg);
+}
+
+static bool trans_c_fldsp(DisasContext *ctx, arg_c_fldsp *a)
+{
+arg_fld arg = { .rd = a->rd, .rs1 = 2, .imm = a->uimm };
+return trans_fld(ctx, &arg);
+}
+
+static bool trans_c_lwsp(DisasContext *ctx, arg_c_lwsp *a)
+{
+arg_lw arg = { .rd = a->rd, .rs1 = 2, .imm = a->uimm };
+return trans_lw(ctx, &arg);
+}
+
+static bool trans_c_flwsp_ldsp(DisasContext *ctx, arg_c_flwsp_ldsp *a)
+{
+#ifdef TARGET_RISCV32
+/* C.FLWSP */
+arg_flw

[Qemu-devel] [PULL 24/29] target/riscv: make ADD/SUB/OR/XOR/AND insn use arg lists

2019-03-12 Thread Palmer Dabbelt
From: Bastian Koppelmann 

manual decoding in gen_arith() is not necessary with decodetree. For now
the function is called trans_arith as the original gen_arith still
exists. The former will be renamed to gen_arith as soon as the old
gen_arith can be removed.

Reviewed-by: Richard Henderson 
Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 
Signed-off-by: Palmer Dabbelt 
---
 target/riscv/insn32.decode  |  3 +-
 target/riscv/insn_trans/trans_rvi.inc.c | 21 +
 target/riscv/translate.c| 40 +++--
 3 files changed, 34 insertions(+), 30 deletions(-)

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index d6b4197841f5..6f3ab7aa52d3 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -36,11 +36,12 @@
 # Argument sets:
 &bimm rs2 rs1
 &iimm rs1 rd
+&rrd rs1 rs2
 &shift shamt rs1 rd
 &atomicaq rl rs2 rs1 rd
 
 # Formats 32:
-@r   ...   . . ... . ...   %rs2 %rs1 
%rd
+@r   ...   . . ... . ... &r%rs2 %rs1 
%rd
 @i   . ... . ... &i  imm=%imm_i %rs1 
%rd
 @b   ...   . . ... . ... &b  imm=%imm_b %rs2 %rs1
 @s   ...   . . ... . ... imm=%imm_s %rs2 %rs1
diff --git a/target/riscv/insn_trans/trans_rvi.inc.c 
b/target/riscv/insn_trans/trans_rvi.inc.c
index 0265740bdb69..8879f2da35c7 100644
--- a/target/riscv/insn_trans/trans_rvi.inc.c
+++ b/target/riscv/insn_trans/trans_rvi.inc.c
@@ -312,14 +312,12 @@ static bool trans_srai(DisasContext *ctx, arg_srai *a)
 
 static bool trans_add(DisasContext *ctx, arg_add *a)
 {
-gen_arith(ctx, OPC_RISC_ADD, a->rd, a->rs1, a->rs2);
-return true;
+return trans_arith(ctx, a, &tcg_gen_add_tl);
 }
 
 static bool trans_sub(DisasContext *ctx, arg_sub *a)
 {
-gen_arith(ctx, OPC_RISC_SUB, a->rd, a->rs1, a->rs2);
-return true;
+return trans_arith(ctx, a, &tcg_gen_sub_tl);
 }
 
 static bool trans_sll(DisasContext *ctx, arg_sll *a)
@@ -342,8 +340,7 @@ static bool trans_sltu(DisasContext *ctx, arg_sltu *a)
 
 static bool trans_xor(DisasContext *ctx, arg_xor *a)
 {
-gen_arith(ctx, OPC_RISC_XOR, a->rd, a->rs1, a->rs2);
-return true;
+return trans_arith(ctx, a, &tcg_gen_xor_tl);
 }
 
 static bool trans_srl(DisasContext *ctx, arg_srl *a)
@@ -360,14 +357,12 @@ static bool trans_sra(DisasContext *ctx, arg_sra *a)
 
 static bool trans_or(DisasContext *ctx, arg_or *a)
 {
-gen_arith(ctx, OPC_RISC_OR, a->rd, a->rs1, a->rs2);
-return true;
+return trans_arith(ctx, a, &tcg_gen_or_tl);
 }
 
 static bool trans_and(DisasContext *ctx, arg_and *a)
 {
-gen_arith(ctx, OPC_RISC_AND, a->rd, a->rs1, a->rs2);
-return true;
+return trans_arith(ctx, a, &tcg_gen_and_tl);
 }
 
 #ifdef TARGET_RISCV64
@@ -414,14 +409,12 @@ static bool trans_sraiw(DisasContext *ctx, arg_sraiw *a)
 
 static bool trans_addw(DisasContext *ctx, arg_addw *a)
 {
-gen_arith(ctx, OPC_RISC_ADDW, a->rd, a->rs1, a->rs2);
-return true;
+return trans_arith(ctx, a, &gen_addw);
 }
 
 static bool trans_subw(DisasContext *ctx, arg_subw *a)
 {
-gen_arith(ctx, OPC_RISC_SUBW, a->rd, a->rs1, a->rs2);
-return true;
+return trans_arith(ctx, a, &gen_subw);
 }
 
 static bool trans_sllw(DisasContext *ctx, arg_sllw *a)
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 0157758a160a..8eb883463322 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -198,12 +198,6 @@ static void gen_arith(DisasContext *ctx, uint32_t opc, int 
rd, int rs1,
 gen_get_gpr(source2, rs2);
 
 switch (opc) {
-CASE_OP_32_64(OPC_RISC_ADD):
-tcg_gen_add_tl(source1, source1, source2);
-break;
-CASE_OP_32_64(OPC_RISC_SUB):
-tcg_gen_sub_tl(source1, source1, source2);
-break;
 #if defined(TARGET_RISCV64)
 case OPC_RISC_SLLW:
 tcg_gen_andi_tl(source2, source2, 0x1F);
@@ -220,9 +214,6 @@ static void gen_arith(DisasContext *ctx, uint32_t opc, int 
rd, int rs1,
 case OPC_RISC_SLTU:
 tcg_gen_setcond_tl(TCG_COND_LTU, source1, source1, source2);
 break;
-case OPC_RISC_XOR:
-tcg_gen_xor_tl(source1, source1, source2);
-break;
 #if defined(TARGET_RISCV64)
 case OPC_RISC_SRLW:
 /* clear upper 32 */
@@ -248,12 +239,6 @@ static void gen_arith(DisasContext *ctx, uint32_t opc, int 
rd, int rs1,
 tcg_gen_andi_tl(source2, source2, TARGET_LONG_BITS - 1);
 tcg_gen_sar_tl(source1, source1, source2);
 break;
-case OPC_RISC_OR:
-tcg_gen_or_tl(source1, source1, source2);
-break;
-case OPC_RISC_AND:
-tcg_gen_and_tl(source1, source1, source2);
-break;
 CASE_OP_32_64(OPC_RISC_MUL):
 if (!

[Qemu-devel] [PULL 12/29] target/riscv: Convert RV64F insns to decodetree

2019-03-12 Thread Palmer Dabbelt
From: Bastian Koppelmann 

Acked-by: Alistair Francis 
Reviewed-by: Richard Henderson 
Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 
Signed-off-by: Palmer Dabbelt 
---
 target/riscv/insn32-64.decode   |  6 +++
 target/riscv/insn_trans/trans_rvf.inc.c | 60 +
 2 files changed, 66 insertions(+)

diff --git a/target/riscv/insn32-64.decode b/target/riscv/insn32-64.decode
index 0bee95c9840d..6319f872ac1d 100644
--- a/target/riscv/insn32-64.decode
+++ b/target/riscv/insn32-64.decode
@@ -56,3 +56,9 @@ amomin_d   1 . . . . 011 . 010 @atom_st
 amomax_d   10100 . . . . 011 . 010 @atom_st
 amominu_d  11000 . . . . 011 . 010 @atom_st
 amomaxu_d  11100 . . . . 011 . 010 @atom_st
+
+# *** RV64F Standard Extension (in addition to RV32F) ***
+fcvt_l_s   110  00010 . ... . 1010011 @r2_rm
+fcvt_lu_s  110  00011 . ... . 1010011 @r2_rm
+fcvt_s_l   1101000  00010 . ... . 1010011 @r2_rm
+fcvt_s_lu  1101000  00011 . ... . 1010011 @r2_rm
diff --git a/target/riscv/insn_trans/trans_rvf.inc.c 
b/target/riscv/insn_trans/trans_rvf.inc.c
index 0f837903491b..172dbfa919b6 100644
--- a/target/riscv/insn_trans/trans_rvf.inc.c
+++ b/target/riscv/insn_trans/trans_rvf.inc.c
@@ -377,3 +377,63 @@ static bool trans_fmv_w_x(DisasContext *ctx, arg_fmv_w_x 
*a)
 
 return true;
 }
+
+#ifdef TARGET_RISCV64
+static bool trans_fcvt_l_s(DisasContext *ctx, arg_fcvt_l_s *a)
+{
+REQUIRE_FPU;
+REQUIRE_EXT(ctx, RVF);
+
+TCGv t0 = tcg_temp_new();
+gen_set_rm(ctx, a->rm);
+gen_helper_fcvt_l_s(t0, cpu_env, cpu_fpr[a->rs1]);
+gen_set_gpr(a->rd, t0);
+tcg_temp_free(t0);
+return true;
+}
+
+static bool trans_fcvt_lu_s(DisasContext *ctx, arg_fcvt_lu_s *a)
+{
+REQUIRE_FPU;
+REQUIRE_EXT(ctx, RVF);
+
+TCGv t0 = tcg_temp_new();
+gen_set_rm(ctx, a->rm);
+gen_helper_fcvt_lu_s(t0, cpu_env, cpu_fpr[a->rs1]);
+gen_set_gpr(a->rd, t0);
+tcg_temp_free(t0);
+return true;
+}
+
+static bool trans_fcvt_s_l(DisasContext *ctx, arg_fcvt_s_l *a)
+{
+REQUIRE_FPU;
+REQUIRE_EXT(ctx, RVF);
+
+TCGv t0 = tcg_temp_new();
+gen_get_gpr(t0, a->rs1);
+
+gen_set_rm(ctx, a->rm);
+gen_helper_fcvt_s_l(cpu_fpr[a->rd], cpu_env, t0);
+
+mark_fs_dirty(ctx);
+tcg_temp_free(t0);
+return true;
+}
+
+static bool trans_fcvt_s_lu(DisasContext *ctx, arg_fcvt_s_lu *a)
+{
+REQUIRE_FPU;
+REQUIRE_EXT(ctx, RVF);
+
+TCGv t0 = tcg_temp_new();
+gen_get_gpr(t0, a->rs1);
+
+gen_set_rm(ctx, a->rm);
+gen_helper_fcvt_s_lu(cpu_fpr[a->rd], cpu_env, t0);
+
+mark_fs_dirty(ctx);
+tcg_temp_free(t0);
+return true;
+}
+#endif
-- 
2.19.2




[Qemu-devel] [PULL 23/29] target/riscv: Move gen_arith_imm() decoding into trans_* functions

2019-03-12 Thread Palmer Dabbelt
From: Bastian Koppelmann 

gen_arith_imm() does a lot of decoding manually, which was hard to read
in case of the shift instructions and is not necessary anymore with
decodetree.

Reviewed-by: Richard Henderson 
Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 
Signed-off-by: Palmer Dabbelt 
---
 target/riscv/insn32.decode  |   3 +-
 target/riscv/insn_trans/trans_rvi.inc.c |  98 +-
 target/riscv/translate.c| 107 ++--
 3 files changed, 108 insertions(+), 100 deletions(-)

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index ecc46a50cc27..d6b4197841f5 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -35,12 +35,13 @@
 
 # Argument sets:
 &bimm rs2 rs1
+&iimm rs1 rd
 &shift shamt rs1 rd
 &atomicaq rl rs2 rs1 rd
 
 # Formats 32:
 @r   ...   . . ... . ...   %rs2 %rs1 
%rd
-@i   . ... . ... imm=%imm_i %rs1 
%rd
+@i   . ... . ... &i  imm=%imm_i %rs1 
%rd
 @b   ...   . . ... . ... &b  imm=%imm_b %rs2 %rs1
 @s   ...   . . ... . ... imm=%imm_s %rs2 %rs1
 @u     . ... imm=%imm_u  
%rd
diff --git a/target/riscv/insn_trans/trans_rvi.inc.c 
b/target/riscv/insn_trans/trans_rvi.inc.c
index 5a09c6335ae0..0265740bdb69 100644
--- a/target/riscv/insn_trans/trans_rvi.inc.c
+++ b/target/riscv/insn_trans/trans_rvi.inc.c
@@ -217,52 +217,96 @@ static bool trans_sd(DisasContext *ctx, arg_sd *a)
 
 static bool trans_addi(DisasContext *ctx, arg_addi *a)
 {
-gen_arith_imm(ctx, OPC_RISC_ADDI, a->rd, a->rs1, a->imm);
-return true;
+return gen_arith_imm(ctx, a, &tcg_gen_add_tl);
 }
 
 static bool trans_slti(DisasContext *ctx, arg_slti *a)
 {
-gen_arith_imm(ctx, OPC_RISC_SLTI, a->rd, a->rs1, a->imm);
+TCGv source1;
+source1 = tcg_temp_new();
+gen_get_gpr(source1, a->rs1);
+
+tcg_gen_setcondi_tl(TCG_COND_LT, source1, source1, a->imm);
+
+gen_set_gpr(a->rd, source1);
+tcg_temp_free(source1);
 return true;
 }
 
 static bool trans_sltiu(DisasContext *ctx, arg_sltiu *a)
 {
-gen_arith_imm(ctx, OPC_RISC_SLTIU, a->rd, a->rs1, a->imm);
+TCGv source1;
+source1 = tcg_temp_new();
+gen_get_gpr(source1, a->rs1);
+
+tcg_gen_setcondi_tl(TCG_COND_LTU, source1, source1, a->imm);
+
+gen_set_gpr(a->rd, source1);
+tcg_temp_free(source1);
 return true;
 }
 
 static bool trans_xori(DisasContext *ctx, arg_xori *a)
 {
-gen_arith_imm(ctx, OPC_RISC_XORI, a->rd, a->rs1, a->imm);
-return true;
+return gen_arith_imm(ctx, a, &tcg_gen_xor_tl);
 }
 static bool trans_ori(DisasContext *ctx, arg_ori *a)
 {
-gen_arith_imm(ctx, OPC_RISC_ORI, a->rd, a->rs1, a->imm);
-return true;
+return gen_arith_imm(ctx, a, &tcg_gen_or_tl);
 }
 static bool trans_andi(DisasContext *ctx, arg_andi *a)
 {
-gen_arith_imm(ctx, OPC_RISC_ANDI, a->rd, a->rs1, a->imm);
-return true;
+return gen_arith_imm(ctx, a, &tcg_gen_and_tl);
 }
 static bool trans_slli(DisasContext *ctx, arg_slli *a)
 {
-gen_arith_imm(ctx, OPC_RISC_SLLI, a->rd, a->rs1, a->shamt);
+if (a->shamt >= TARGET_LONG_BITS) {
+return false;
+}
+
+if (a->rd != 0) {
+TCGv t = tcg_temp_new();
+gen_get_gpr(t, a->rs1);
+
+tcg_gen_shli_tl(t, t, a->shamt);
+
+gen_set_gpr(a->rd, t);
+tcg_temp_free(t);
+} /* NOP otherwise */
 return true;
 }
 
 static bool trans_srli(DisasContext *ctx, arg_srli *a)
 {
-gen_arith_imm(ctx, OPC_RISC_SHIFT_RIGHT_I, a->rd, a->rs1, a->shamt);
+if (a->shamt >= TARGET_LONG_BITS) {
+return false;
+}
+
+if (a->rd != 0) {
+TCGv t = tcg_temp_new();
+gen_get_gpr(t, a->rs1);
+
+tcg_gen_shri_tl(t, t, a->shamt);
+gen_set_gpr(a->rd, t);
+tcg_temp_free(t);
+} /* NOP otherwise */
 return true;
 }
 
 static bool trans_srai(DisasContext *ctx, arg_srai *a)
 {
-gen_arith_imm(ctx, OPC_RISC_SHIFT_RIGHT_I, a->rd, a->rs1, a->shamt | 
0x400);
+if (a->shamt >= TARGET_LONG_BITS) {
+return false;
+}
+
+if (a->rd != 0) {
+TCGv t = tcg_temp_new();
+gen_get_gpr(t, a->rs1);
+
+tcg_gen_sari_tl(t, t, a->shamt);
+gen_set_gpr(a->rd, t);
+tcg_temp_free(t);
+} /* NOP otherwise */
 return true;
 }
 
@@ -329,26 +373,42 @@ static bool trans_and(DisasContext *ctx, arg_and *a)
 #ifdef TARGET_RISCV64
 static bool trans_addiw(DisasContext *ctx, arg_addiw *a)
 {
-gen_arith_imm(ctx, OPC_RISC_ADDIW, a->rd, a->rs1, a->imm);
-return true;
+return gen_arith_

[Qemu-devel] [PULL 22/29] target/riscv: Remove manual decoding from gen_store()

2019-03-12 Thread Palmer Dabbelt
From: Bastian Koppelmann 

With decodetree we don't need to convert RISC-V opcodes into to MemOps
as the old gen_store() did.

Reviewed-by: Richard Henderson 
Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 
Signed-off-by: Palmer Dabbelt 
---
 target/riscv/insn_trans/trans_rvi.inc.c | 27 +
 target/riscv/translate.c|  8 +---
 2 files changed, 24 insertions(+), 11 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvi.inc.c 
b/target/riscv/insn_trans/trans_rvi.inc.c
index cc361ed4d151..5a09c6335ae0 100644
--- a/target/riscv/insn_trans/trans_rvi.inc.c
+++ b/target/riscv/insn_trans/trans_rvi.inc.c
@@ -168,22 +168,34 @@ static bool trans_lhu(DisasContext *ctx, arg_lhu *a)
 return gen_load(ctx, a, MO_TEUW);
 }
 
-static bool trans_sb(DisasContext *ctx, arg_sb *a)
+static bool gen_store(DisasContext *ctx, arg_sb *a, TCGMemOp memop)
 {
-gen_store(ctx, OPC_RISC_SB, a->rs1, a->rs2, a->imm);
+TCGv t0 = tcg_temp_new();
+TCGv dat = tcg_temp_new();
+gen_get_gpr(t0, a->rs1);
+tcg_gen_addi_tl(t0, t0, a->imm);
+gen_get_gpr(dat, a->rs2);
+
+tcg_gen_qemu_st_tl(dat, t0, ctx->mem_idx, memop);
+tcg_temp_free(t0);
+tcg_temp_free(dat);
 return true;
 }
 
+
+static bool trans_sb(DisasContext *ctx, arg_sb *a)
+{
+return gen_store(ctx, a, MO_SB);
+}
+
 static bool trans_sh(DisasContext *ctx, arg_sh *a)
 {
-gen_store(ctx, OPC_RISC_SH, a->rs1, a->rs2, a->imm);
-return true;
+return gen_store(ctx, a, MO_TESW);
 }
 
 static bool trans_sw(DisasContext *ctx, arg_sw *a)
 {
-gen_store(ctx, OPC_RISC_SW, a->rs1, a->rs2, a->imm);
-return true;
+return gen_store(ctx, a, MO_TESL);
 }
 
 #ifdef TARGET_RISCV64
@@ -199,8 +211,7 @@ static bool trans_ld(DisasContext *ctx, arg_ld *a)
 
 static bool trans_sd(DisasContext *ctx, arg_sd *a)
 {
-gen_store(ctx, OPC_RISC_SD, a->rs1, a->rs2, a->imm);
-return true;
+return gen_store(ctx, a, MO_TEQ);
 }
 #endif
 
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 99d6d3b4ae91..cdc08b1bff20 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -56,6 +56,7 @@ typedef struct DisasContext {
 int frm;
 } DisasContext;
 
+#ifdef TARGET_RISCV64
 /* convert riscv funct3 to qemu memop for load/store */
 static const int tcg_memop_lookup[8] = {
 [0 ... 7] = -1,
@@ -69,6 +70,7 @@ static const int tcg_memop_lookup[8] = {
 [6] = MO_TEUL,
 #endif
 };
+#endif
 
 #ifdef TARGET_RISCV64
 #define CASE_OP_32_64(X) case X: case glue(X, W)
@@ -551,9 +553,8 @@ static void gen_load_c(DisasContext *ctx, uint32_t opc, int 
rd, int rs1,
 tcg_temp_free(t0);
 tcg_temp_free(t1);
 }
-#endif
 
-static void gen_store(DisasContext *ctx, uint32_t opc, int rs1, int rs2,
+static void gen_store_c(DisasContext *ctx, uint32_t opc, int rs1, int rs2,
 target_long imm)
 {
 TCGv t0 = tcg_temp_new();
@@ -572,6 +573,7 @@ static void gen_store(DisasContext *ctx, uint32_t opc, int 
rs1, int rs2,
 tcg_temp_free(t0);
 tcg_temp_free(dat);
 }
+#endif
 
 #ifndef CONFIG_USER_ONLY
 /* The states of mstatus_fs are:
@@ -736,7 +738,7 @@ static void decode_RV32_64C0(DisasContext *ctx)
 case 7:
 #if defined(TARGET_RISCV64)
 /* C.SD (RV64/128) -> sd rs2', offset[7:3](rs1')*/
-gen_store(ctx, OPC_RISC_SD, rs1s, rd_rs2,
+gen_store_c(ctx, OPC_RISC_SD, rs1s, rd_rs2,
   GET_C_LD_IMM(ctx->opcode));
 #else
 /* C.FSW (RV32) -> fsw rs2', offset[6:2](rs1')*/
-- 
2.19.2




[Qemu-devel] [PULL 19/29] target/riscv: Remove gen_jalr()

2019-03-12 Thread Palmer Dabbelt
From: Bastian Koppelmann 

trans_jalr() is the only caller, so move the code into trans_jalr().

Acked-by: Alistair Francis 
Reviewed-by: Richard Henderson 
Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 
Signed-off-by: Palmer Dabbelt 
---
 target/riscv/insn_trans/trans_rvi.inc.c | 28 +-
 target/riscv/translate.c| 38 -
 2 files changed, 27 insertions(+), 39 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvi.inc.c 
b/target/riscv/insn_trans/trans_rvi.inc.c
index 4a23372cb823..631a88906bce 100644
--- a/target/riscv/insn_trans/trans_rvi.inc.c
+++ b/target/riscv/insn_trans/trans_rvi.inc.c
@@ -42,7 +42,33 @@ static bool trans_jal(DisasContext *ctx, arg_jal *a)
 
 static bool trans_jalr(DisasContext *ctx, arg_jalr *a)
 {
-gen_jalr(ctx, OPC_RISC_JALR, a->rd, a->rs1, a->imm);
+/* no chaining with JALR */
+TCGLabel *misaligned = NULL;
+TCGv t0 = tcg_temp_new();
+
+
+gen_get_gpr(cpu_pc, a->rs1);
+tcg_gen_addi_tl(cpu_pc, cpu_pc, a->imm);
+tcg_gen_andi_tl(cpu_pc, cpu_pc, (target_ulong)-2);
+
+if (!has_ext(ctx, RVC)) {
+misaligned = gen_new_label();
+tcg_gen_andi_tl(t0, cpu_pc, 0x2);
+tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0x0, misaligned);
+}
+
+if (a->rd != 0) {
+tcg_gen_movi_tl(cpu_gpr[a->rd], ctx->pc_succ_insn);
+}
+tcg_gen_lookup_and_goto_ptr();
+
+if (misaligned) {
+gen_set_label(misaligned);
+gen_exception_inst_addr_mis(ctx);
+}
+ctx->base.is_jmp = DISAS_NORETURN;
+
+tcg_temp_free(t0);
 return true;
 }
 
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 80afa2c1e62b..9dee2ec24287 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -531,44 +531,6 @@ static void gen_jal(DisasContext *ctx, int rd, 
target_ulong imm)
 ctx->base.is_jmp = DISAS_NORETURN;
 }
 
-static void gen_jalr(DisasContext *ctx, uint32_t opc, int rd, int rs1,
- target_long imm)
-{
-/* no chaining with JALR */
-TCGLabel *misaligned = NULL;
-TCGv t0 = tcg_temp_new();
-
-switch (opc) {
-case OPC_RISC_JALR:
-gen_get_gpr(cpu_pc, rs1);
-tcg_gen_addi_tl(cpu_pc, cpu_pc, imm);
-tcg_gen_andi_tl(cpu_pc, cpu_pc, (target_ulong)-2);
-
-if (!has_ext(ctx, RVC)) {
-misaligned = gen_new_label();
-tcg_gen_andi_tl(t0, cpu_pc, 0x2);
-tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0x0, misaligned);
-}
-
-if (rd != 0) {
-tcg_gen_movi_tl(cpu_gpr[rd], ctx->pc_succ_insn);
-}
-tcg_gen_lookup_and_goto_ptr();
-
-if (misaligned) {
-gen_set_label(misaligned);
-gen_exception_inst_addr_mis(ctx);
-}
-ctx->base.is_jmp = DISAS_NORETURN;
-break;
-
-default:
-gen_exception_illegal(ctx);
-break;
-}
-tcg_temp_free(t0);
-}
-
 static void gen_branch(DisasContext *ctx, uint32_t opc, int rs1, int rs2,
target_long bimm)
 {
-- 
2.19.2




[Qemu-devel] [PULL 17/29] target/riscv: Convert quadrant 1 of RVXC insns to decodetree

2019-03-12 Thread Palmer Dabbelt
From: Bastian Koppelmann 

Reviewed-by: Richard Henderson 
Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 
Signed-off-by: Palmer Dabbelt 
---
 target/riscv/insn16.decode  |  43 +++
 target/riscv/insn_trans/trans_rvc.inc.c | 151 
 target/riscv/translate.c| 118 +-
 3 files changed, 195 insertions(+), 117 deletions(-)

diff --git a/target/riscv/insn16.decode b/target/riscv/insn16.decode
index 558c0c41f0b5..29dade0fa1ae 100644
--- a/target/riscv/insn16.decode
+++ b/target/riscv/insn16.decode
@@ -22,28 +22,53 @@
 %rs2_3 2:3!function=ex_rvc_register
 
 # Immediates:
+%imm_ci12:s1 2:5
 %nzuimm_ciw7:4 11:2 5:1 6:1   !function=ex_shift_2
 %uimm_cl_d 5:2 10:3   !function=ex_shift_3
 %uimm_cl_w 5:1 10:3 6:1   !function=ex_shift_2
+%imm_cb12:s1 5:2 2:1 10:2 3:2 !function=ex_shift_1
+%imm_cj12:s1 8:1 9:2 6:1 7:1 2:1 11:1 3:3 !function=ex_shift_1
+
+%nzuimm_6bit   12:1 2:5
+
+%imm_addi16sp  12:s1 3:2 5:1 2:1 6:1 !function=ex_shift_4
+%imm_lui   12:s1 2:5 !function=ex_shift_12
+
 
 
 # Argument sets:
 &cl   rs1 rd
 &cl_dw uimm   rs1 rd
+&ciimmrd
 &ciw   nzuimm rd
 &cs   rs1 rs2
 &cs_dw uimm   rs1 rs2
+&cbimmrs1
+&cr   rd  rs2
+&c_j   imm
+&c_shift   shamt  rd
+
 
+&c_addi16sp_lui  imm_lui imm_addi16sp rd
 
 # Formats 16:
+@ci... . . .  .. &ci imm=%imm_ci  %rd
 @ciw   ...    ... .. &ciwnzuimm=%nzuimm_ciw   rd=%rs2_3
 @cl_d  ... ... ... .. ... .. &cl_dw  uimm=%uimm_cl_d  rs1=%rs1_3  rd=%rs2_3
 @cl_w  ... ... ... .. ... .. &cl_dw  uimm=%uimm_cl_w  rs1=%rs1_3  rd=%rs2_3
 @cl... ... ... .. ... .. &cl  rs1=%rs1_3  rd=%rs2_3
 @cs... ... ... .. ... .. &cs  rs1=%rs1_3  
rs2=%rs2_3
+@cs_2  ... ... ... .. ... .. &cr  rd=%rs1_3   
rs2=%rs2_3
 @cs_d  ... ... ... .. ... .. &cs_dw  uimm=%uimm_cl_d  rs1=%rs1_3  
rs2=%rs2_3
 @cs_w  ... ... ... .. ... .. &cs_dw  uimm=%uimm_cl_w  rs1=%rs1_3  
rs2=%rs2_3
+@cb... ... ... .. ... .. &cb imm=%imm_cb  rs1=%rs1_3
+@cj...... .. &c_jimm=%imm_cj
 
+@c_addi16sp_lui ... .  . . .. &c_addi16sp_lui %imm_lui %imm_addi16sp 
%rd
+
+@c_shift... . .. ... . .. &c_shift rd=%rs1_3 shamt=%nzuimm_6bit
+
+@c_andi ... . .. ... . .. &ci imm=%imm_ci rd=%rs1_3
 
 # *** RV64C Standard Extension (Quadrant 0) ***
 c_addi4spn000 ... 00 @ciw
@@ -53,3 +78,21 @@ c_flw_ld  011  --- ... -- ... 00 @cl#Note: Must 
parse uimm manually
 c_fsd 101  ... ... .. ... 00 @cs_d
 c_sw  110  ... ... .. ... 00 @cs_w
 c_fsw_sd  111  --- ... -- ... 00 @cs#Note: Must parse uimm manually
+
+# *** RV64C Standard Extension (Quadrant 1) ***
+c_addi000 .  .  . 01 @ci
+c_jal_addiw   001 .  .  . 01 @ci #Note: parse rd and/or imm 
manually
+c_li  010 .  .  . 01 @ci
+c_addi16sp_lui011 .  .  . 01 @c_addi16sp_lui # shares opc with 
C.LUI
+c_srli100 . 00 ...  . 01 @c_shift
+c_srai100 . 01 ...  . 01 @c_shift
+c_andi100 . 10 ...  . 01 @c_andi
+c_sub 100 0 11 ... 00 ... 01 @cs_2
+c_xor 100 0 11 ... 01 ... 01 @cs_2
+c_or  100 0 11 ... 10 ... 01 @cs_2
+c_and 100 0 11 ... 11 ... 01 @cs_2
+c_subw100 1 11 ... 00 ... 01 @cs_2
+c_addw100 1 11 ... 01 ... 01 @cs_2
+c_j   101 ... 01 @cj
+c_beqz110  ... ...  . 01 @cb
+c_bnez111  ... ...  . 01 @cb
diff --git a/target/riscv/insn_trans/trans_rvc.inc.c 
b/target/riscv/insn_trans/trans_rvc.inc.c
index 93ec8aa30b95..b06c435c9800 100644
--- a/target/riscv/insn_trans/trans_rvc.inc.c
+++ b/target/riscv/insn_trans/trans_rvc.inc.c
@@ -73,3 +73,154 @@ static bool trans_c_fsw_sd(DisasContext *ctx, arg_c_fsw_sd 
*a)
 return false;
 #endif
 }
+
+static bool trans_c_addi(DisasContext *ctx, arg_c_addi *a)
+{
+if (a->imm == 0) {
+/* Hint: insn is valid but does not affect state */
+return true;
+}
+arg_addi arg = { .rd = a->rd, .rs1 = a->rd, .imm = a->imm };
+return trans_addi(ctx, &arg);
+}
+
+static bool trans_c_jal_addiw(DisasContext *ctx, arg_c_jal_addiw *a)
+{
+#ifdef TARGET_RISCV32
+/* C.JAL */
+arg_jal arg = { .rd = 1, .imm = a->imm };
+return trans_jal(ctx, &arg);
+#else
+/* C.ADDIW */
+arg_addiw arg = { .rd = a->rd, .rs1 = a->rd, .imm = a->imm };
+return trans_addiw(ctx, &arg);
+#endif
+}
+
+static bool trans_c_li(DisasContext *ctx, arg_c_li *a)
+{
+i

[Qemu-devel] [PULL 14/29] target/riscv: Convert RV64D insns to decodetree

2019-03-12 Thread Palmer Dabbelt
From: Bastian Koppelmann 

Acked-by: Alistair Francis 
Reviewed-by: Richard Henderson 
Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 
Signed-off-by: Palmer Dabbelt 
---
 target/riscv/insn32-64.decode   |   8 +
 target/riscv/insn_trans/trans_rvd.inc.c |  82 
 target/riscv/translate.c| 601 +---
 3 files changed, 91 insertions(+), 600 deletions(-)

diff --git a/target/riscv/insn32-64.decode b/target/riscv/insn32-64.decode
index 6319f872ac1d..380bf791bcdc 100644
--- a/target/riscv/insn32-64.decode
+++ b/target/riscv/insn32-64.decode
@@ -62,3 +62,11 @@ fcvt_l_s   110  00010 . ... . 1010011 @r2_rm
 fcvt_lu_s  110  00011 . ... . 1010011 @r2_rm
 fcvt_s_l   1101000  00010 . ... . 1010011 @r2_rm
 fcvt_s_lu  1101000  00011 . ... . 1010011 @r2_rm
+
+# *** RV64D Standard Extension (in addition to RV32D) ***
+fcvt_l_d   111  00010 . ... . 1010011 @r2_rm
+fcvt_lu_d  111  00011 . ... . 1010011 @r2_rm
+fmv_x_d1110001  0 . 000 . 1010011 @r2
+fcvt_d_l   1101001  00010 . ... . 1010011 @r2_rm
+fcvt_d_lu  1101001  00011 . ... . 1010011 @r2_rm
+fmv_d_x001  0 . 000 . 1010011 @r2
diff --git a/target/riscv/insn_trans/trans_rvd.inc.c 
b/target/riscv/insn_trans/trans_rvd.inc.c
index 98fc1cdc5a20..393fa0248ce9 100644
--- a/target/riscv/insn_trans/trans_rvd.inc.c
+++ b/target/riscv/insn_trans/trans_rvd.inc.c
@@ -358,3 +358,85 @@ static bool trans_fcvt_d_wu(DisasContext *ctx, 
arg_fcvt_d_wu *a)
 mark_fs_dirty(ctx);
 return true;
 }
+
+#ifdef TARGET_RISCV64
+
+static bool trans_fcvt_l_d(DisasContext *ctx, arg_fcvt_l_d *a)
+{
+REQUIRE_FPU;
+REQUIRE_EXT(ctx, RVD);
+
+TCGv t0 = tcg_temp_new();
+gen_set_rm(ctx, a->rm);
+gen_helper_fcvt_l_d(t0, cpu_env, cpu_fpr[a->rs1]);
+gen_set_gpr(a->rd, t0);
+tcg_temp_free(t0);
+return true;
+}
+
+static bool trans_fcvt_lu_d(DisasContext *ctx, arg_fcvt_lu_d *a)
+{
+REQUIRE_FPU;
+REQUIRE_EXT(ctx, RVD);
+
+TCGv t0 = tcg_temp_new();
+gen_set_rm(ctx, a->rm);
+gen_helper_fcvt_lu_d(t0, cpu_env, cpu_fpr[a->rs1]);
+gen_set_gpr(a->rd, t0);
+tcg_temp_free(t0);
+return true;
+}
+
+static bool trans_fmv_x_d(DisasContext *ctx, arg_fmv_x_d *a)
+{
+REQUIRE_FPU;
+REQUIRE_EXT(ctx, RVD);
+
+gen_set_gpr(a->rd, cpu_fpr[a->rs1]);
+return true;
+}
+
+static bool trans_fcvt_d_l(DisasContext *ctx, arg_fcvt_d_l *a)
+{
+REQUIRE_FPU;
+REQUIRE_EXT(ctx, RVD);
+
+TCGv t0 = tcg_temp_new();
+gen_get_gpr(t0, a->rs1);
+
+gen_set_rm(ctx, a->rm);
+gen_helper_fcvt_d_l(cpu_fpr[a->rd], cpu_env, t0);
+tcg_temp_free(t0);
+mark_fs_dirty(ctx);
+return true;
+}
+
+static bool trans_fcvt_d_lu(DisasContext *ctx, arg_fcvt_d_lu *a)
+{
+REQUIRE_FPU;
+REQUIRE_EXT(ctx, RVD);
+
+TCGv t0 = tcg_temp_new();
+gen_get_gpr(t0, a->rs1);
+
+gen_set_rm(ctx, a->rm);
+gen_helper_fcvt_d_lu(cpu_fpr[a->rd], cpu_env, t0);
+tcg_temp_free(t0);
+mark_fs_dirty(ctx);
+return true;
+}
+
+static bool trans_fmv_d_x(DisasContext *ctx, arg_fmv_d_x *a)
+{
+REQUIRE_FPU;
+REQUIRE_EXT(ctx, RVD);
+
+TCGv t0 = tcg_temp_new();
+gen_get_gpr(t0, a->rs1);
+
+tcg_gen_mov_tl(cpu_fpr[a->rd], t0);
+tcg_temp_free(t0);
+mark_fs_dirty(ctx);
+return true;
+}
+#endif
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index c201985ef37b..2e36deee82f4 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -186,44 +186,6 @@ static void gen_mulhsu(TCGv ret, TCGv arg1, TCGv arg2)
 tcg_temp_free(rh);
 }
 
-static void gen_fsgnj(DisasContext *ctx, uint32_t rd, uint32_t rs1,
-uint32_t rs2, int rm, uint64_t min)
-{
-switch (rm) {
-case 0: /* fsgnj */
-if (rs1 == rs2) { /* FMOV */
-tcg_gen_mov_i64(cpu_fpr[rd], cpu_fpr[rs1]);
-} else {
-tcg_gen_deposit_i64(cpu_fpr[rd], cpu_fpr[rs2], cpu_fpr[rs1],
-0, min == INT32_MIN ? 31 : 63);
-}
-break;
-case 1: /* fsgnjn */
-if (rs1 == rs2) { /* FNEG */
-tcg_gen_xori_i64(cpu_fpr[rd], cpu_fpr[rs1], min);
-} else {
-TCGv_i64 t0 = tcg_temp_new_i64();
-tcg_gen_not_i64(t0, cpu_fpr[rs2]);
-tcg_gen_deposit_i64(cpu_fpr[rd], t0, cpu_fpr[rs1],
-0, min == INT32_MIN ? 31 : 63);
-tcg_temp_free_i64(t0);
-}
-break;
-case 2: /* fsgnjx */
-if (rs1 == rs2) { /* FABS */
-tcg_gen_andi_i64(cpu_fpr[rd], cpu_fpr[rs1], ~min);
-} else {
-TCGv_i64 t0 = tcg_temp_new_i64();
-tcg_gen_andi_i64(t0, cpu_fpr[rs2], min);
-tcg_gen_xor_i64(cpu_fpr[rd], cpu_fpr[rs1], t0);
-tcg_temp_free_i64(t0);
-}
-break;
-default:
-gen_exception_

[Qemu-devel] [PULL 20/29] target/riscv: Remove manual decoding from gen_branch()

2019-03-12 Thread Palmer Dabbelt
From: Bastian Koppelmann 

We now utilizes argument-sets of decodetree such that no manual
decoding is necessary.

Reviewed-by: Richard Henderson 
Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 
Signed-off-by: Palmer Dabbelt 
---
 target/riscv/insn_trans/trans_rvi.inc.c | 46 +---
 target/riscv/translate.c| 47 -
 2 files changed, 33 insertions(+), 60 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvi.inc.c 
b/target/riscv/insn_trans/trans_rvi.inc.c
index 631a88906bce..ae4b0a2bcb78 100644
--- a/target/riscv/insn_trans/trans_rvi.inc.c
+++ b/target/riscv/insn_trans/trans_rvi.inc.c
@@ -72,41 +72,61 @@ static bool trans_jalr(DisasContext *ctx, arg_jalr *a)
 return true;
 }
 
-static bool trans_beq(DisasContext *ctx, arg_beq *a)
+static bool gen_branch(DisasContext *ctx, arg_b *a, TCGCond cond)
 {
-gen_branch(ctx, OPC_RISC_BEQ, a->rs1, a->rs2, a->imm);
+TCGLabel *l = gen_new_label();
+TCGv source1, source2;
+source1 = tcg_temp_new();
+source2 = tcg_temp_new();
+gen_get_gpr(source1, a->rs1);
+gen_get_gpr(source2, a->rs2);
+
+tcg_gen_brcond_tl(cond, source1, source2, l);
+gen_goto_tb(ctx, 1, ctx->pc_succ_insn);
+gen_set_label(l); /* branch taken */
+
+if (!has_ext(ctx, RVC) && ((ctx->base.pc_next + a->imm) & 0x3)) {
+/* misaligned */
+gen_exception_inst_addr_mis(ctx);
+} else {
+gen_goto_tb(ctx, 0, ctx->base.pc_next + a->imm);
+}
+ctx->base.is_jmp = DISAS_NORETURN;
+
+tcg_temp_free(source1);
+tcg_temp_free(source2);
+
 return true;
 }
 
+static bool trans_beq(DisasContext *ctx, arg_beq *a)
+{
+return gen_branch(ctx, a, TCG_COND_EQ);
+}
+
 static bool trans_bne(DisasContext *ctx, arg_bne *a)
 {
-gen_branch(ctx, OPC_RISC_BNE, a->rs1, a->rs2, a->imm);
-return true;
+return gen_branch(ctx, a, TCG_COND_NE);
 }
 
 static bool trans_blt(DisasContext *ctx, arg_blt *a)
 {
-gen_branch(ctx, OPC_RISC_BLT, a->rs1, a->rs2, a->imm);
-return true;
+return gen_branch(ctx, a, TCG_COND_LT);
 }
 
 static bool trans_bge(DisasContext *ctx, arg_bge *a)
 {
-gen_branch(ctx, OPC_RISC_BGE, a->rs1, a->rs2, a->imm);
-return true;
+return gen_branch(ctx, a, TCG_COND_GE);
 }
 
 static bool trans_bltu(DisasContext *ctx, arg_bltu *a)
 {
-gen_branch(ctx, OPC_RISC_BLTU, a->rs1, a->rs2, a->imm);
-return true;
+return gen_branch(ctx, a, TCG_COND_LTU);
 }
 
 static bool trans_bgeu(DisasContext *ctx, arg_bgeu *a)
 {
-
-gen_branch(ctx, OPC_RISC_BGEU, a->rs1, a->rs2, a->imm);
-return true;
+return gen_branch(ctx, a, TCG_COND_GEU);
 }
 
 static bool trans_lb(DisasContext *ctx, arg_lb *a)
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 9dee2ec24287..a3d5cdbad82d 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -531,53 +531,6 @@ static void gen_jal(DisasContext *ctx, int rd, 
target_ulong imm)
 ctx->base.is_jmp = DISAS_NORETURN;
 }
 
-static void gen_branch(DisasContext *ctx, uint32_t opc, int rs1, int rs2,
-   target_long bimm)
-{
-TCGLabel *l = gen_new_label();
-TCGv source1, source2;
-source1 = tcg_temp_new();
-source2 = tcg_temp_new();
-gen_get_gpr(source1, rs1);
-gen_get_gpr(source2, rs2);
-
-switch (opc) {
-case OPC_RISC_BEQ:
-tcg_gen_brcond_tl(TCG_COND_EQ, source1, source2, l);
-break;
-case OPC_RISC_BNE:
-tcg_gen_brcond_tl(TCG_COND_NE, source1, source2, l);
-break;
-case OPC_RISC_BLT:
-tcg_gen_brcond_tl(TCG_COND_LT, source1, source2, l);
-break;
-case OPC_RISC_BGE:
-tcg_gen_brcond_tl(TCG_COND_GE, source1, source2, l);
-break;
-case OPC_RISC_BLTU:
-tcg_gen_brcond_tl(TCG_COND_LTU, source1, source2, l);
-break;
-case OPC_RISC_BGEU:
-tcg_gen_brcond_tl(TCG_COND_GEU, source1, source2, l);
-break;
-default:
-gen_exception_illegal(ctx);
-return;
-}
-tcg_temp_free(source1);
-tcg_temp_free(source2);
-
-gen_goto_tb(ctx, 1, ctx->pc_succ_insn);
-gen_set_label(l); /* branch taken */
-if (!has_ext(ctx, RVC) && ((ctx->base.pc_next + bimm) & 0x3)) {
-/* misaligned */
-gen_exception_inst_addr_mis(ctx);
-} else {
-gen_goto_tb(ctx, 0, ctx->base.pc_next + bimm);
-}
-ctx->base.is_jmp = DISAS_NORETURN;
-}
-
 static void gen_load(DisasContext *ctx, uint32_t opc, int rd, int rs1,
 target_long imm)
 {
-- 
2.19.2




[Qemu-devel] [PULL 06/29] target/riscv: Convert RVXI fence insns to decodetree

2019-03-12 Thread Palmer Dabbelt
From: Bastian Koppelmann 

Acked-by: Alistair Francis 
Reviewed-by: Richard Henderson 
Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 
Signed-off-by: Palmer Dabbelt 
---
 target/riscv/insn32.decode  |  2 ++
 target/riscv/insn_trans/trans_rvi.inc.c | 19 +++
 target/riscv/translate.c| 12 
 3 files changed, 21 insertions(+), 12 deletions(-)

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 1f5bf1f6f97d..804b721ca51e 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -82,3 +82,5 @@ srl  000 .. 101 . 0110011 @r
 sra  010 .. 101 . 0110011 @r
 or   000 .. 110 . 0110011 @r
 and  000 .. 111 . 0110011 @r
+fence pred:4 succ:4 - 000 - 000
+fence_i         - 001 - 000
diff --git a/target/riscv/insn_trans/trans_rvi.inc.c 
b/target/riscv/insn_trans/trans_rvi.inc.c
index 136fa54d0655..973d6371df85 100644
--- a/target/riscv/insn_trans/trans_rvi.inc.c
+++ b/target/riscv/insn_trans/trans_rvi.inc.c
@@ -318,3 +318,22 @@ static bool trans_sraw(DisasContext *ctx, arg_sraw *a)
 return true;
 }
 #endif
+
+static bool trans_fence(DisasContext *ctx, arg_fence *a)
+{
+/* FENCE is a full memory barrier. */
+tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
+return true;
+}
+
+static bool trans_fence_i(DisasContext *ctx, arg_fence_i *a)
+{
+/*
+ * FENCE_I is a no-op in QEMU,
+ * however we need to end the translation block
+ */
+tcg_gen_movi_tl(cpu_pc, ctx->pc_succ_insn);
+tcg_gen_exit_tb(NULL, 0);
+ctx->base.is_jmp = DISAS_NORETURN;
+return true;
+}
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 1ae84dcd5992..f720746cb791 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -1950,18 +1950,6 @@ static void decode_RV32_64G(DisasContext *ctx)
 gen_fp_arith(ctx, MASK_OP_FP_ARITH(ctx->opcode), rd, rs1, rs2,
  GET_RM(ctx->opcode));
 break;
-case OPC_RISC_FENCE:
-if (ctx->opcode & 0x1000) {
-/* FENCE_I is a no-op in QEMU,
- * however we need to end the translation block */
-tcg_gen_movi_tl(cpu_pc, ctx->pc_succ_insn);
-tcg_gen_exit_tb(NULL, 0);
-ctx->base.is_jmp = DISAS_NORETURN;
-} else {
-/* FENCE is a full memory barrier. */
-tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
-}
-break;
 case OPC_RISC_SYSTEM:
 gen_system(ctx, MASK_OP_SYSTEM(ctx->opcode), rd, rs1,
(ctx->opcode & 0xFFF0) >> 20);
-- 
2.19.2




[Qemu-devel] [PULL 13/29] target/riscv: Convert RV32D insns to decodetree

2019-03-12 Thread Palmer Dabbelt
From: Bastian Koppelmann 

Acked-by: Alistair Francis 
Reviewed-by: Richard Henderson 
Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 
Signed-off-by: Palmer Dabbelt 
---
 target/riscv/insn32.decode  |  28 ++
 target/riscv/insn_trans/trans_rvd.inc.c | 360 
 target/riscv/translate.c|   1 +
 3 files changed, 389 insertions(+)
 create mode 100644 target/riscv/insn_trans/trans_rvd.inc.c

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index e40836bf032f..e64b2b5e3458 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -154,3 +154,31 @@ fclass_s   111  0 . 001 . 1010011 @r2
 fcvt_s_w   1101000  0 . ... . 1010011 @r2_rm
 fcvt_s_wu  1101000  1 . ... . 1010011 @r2_rm
 fmv_w_x000  0 . 000 . 1010011 @r2
+
+# *** RV32D Standard Extension ***
+fld   . 011 . 111 @i
+fsd... .  . 011 . 0100111 @s
+fmadd_d. 01 . . ... . 111 @r4_rm
+fmsub_d. 01 . . ... . 1000111 @r4_rm
+fnmsub_d   . 01 . . ... . 1001011 @r4_rm
+fnmadd_d   . 01 . . ... . 100 @r4_rm
+fadd_d 001  . . ... . 1010011 @r_rm
+fsub_d 101  . . ... . 1010011 @r_rm
+fmul_d 0001001  . . ... . 1010011 @r_rm
+fdiv_d 0001101  . . ... . 1010011 @r_rm
+fsqrt_d0101101  0 . ... . 1010011 @r2_rm
+fsgnj_d0010001  . . 000 . 1010011 @r
+fsgnjn_d   0010001  . . 001 . 1010011 @r
+fsgnjx_d   0010001  . . 010 . 1010011 @r
+fmin_d 0010101  . . 000 . 1010011 @r
+fmax_d 0010101  . . 001 . 1010011 @r
+fcvt_s_d   010  1 . ... . 1010011 @r2_rm
+fcvt_d_s   011  0 . ... . 1010011 @r2_rm
+feq_d  1010001  . . 010 . 1010011 @r
+flt_d  1010001  . . 001 . 1010011 @r
+fle_d  1010001  . . 000 . 1010011 @r
+fclass_d   1110001  0 . 001 . 1010011 @r2
+fcvt_w_d   111  0 . ... . 1010011 @r2_rm
+fcvt_wu_d  111  1 . ... . 1010011 @r2_rm
+fcvt_d_w   1101001  0 . ... . 1010011 @r2_rm
+fcvt_d_wu  1101001  1 . ... . 1010011 @r2_rm
diff --git a/target/riscv/insn_trans/trans_rvd.inc.c 
b/target/riscv/insn_trans/trans_rvd.inc.c
new file mode 100644
index ..98fc1cdc5a20
--- /dev/null
+++ b/target/riscv/insn_trans/trans_rvd.inc.c
@@ -0,0 +1,360 @@
+/*
+ * RISC-V translation routines for the RV64D Standard Extension.
+ *
+ * Copyright (c) 2016-2017 Sagar Karandikar, sag...@eecs.berkeley.edu
+ * Copyright (c) 2018 Peer Adelt, peer.ad...@hni.uni-paderborn.de
+ *Bastian Koppelmann, kbast...@mail.uni-paderborn.de
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+static bool trans_fld(DisasContext *ctx, arg_fld *a)
+{
+TCGv t0 = tcg_temp_new();
+gen_get_gpr(t0, a->rs1);
+REQUIRE_FPU;
+REQUIRE_EXT(ctx, RVD);
+tcg_gen_addi_tl(t0, t0, a->imm);
+
+tcg_gen_qemu_ld_i64(cpu_fpr[a->rd], t0, ctx->mem_idx, MO_TEQ);
+
+mark_fs_dirty(ctx);
+tcg_temp_free(t0);
+return true;
+}
+
+static bool trans_fsd(DisasContext *ctx, arg_fsd *a)
+{
+TCGv t0 = tcg_temp_new();
+gen_get_gpr(t0, a->rs1);
+REQUIRE_FPU;
+REQUIRE_EXT(ctx, RVD);
+tcg_gen_addi_tl(t0, t0, a->imm);
+
+tcg_gen_qemu_st_i64(cpu_fpr[a->rs2], t0, ctx->mem_idx, MO_TEQ);
+
+mark_fs_dirty(ctx);
+tcg_temp_free(t0);
+return true;
+}
+
+static bool trans_fmadd_d(DisasContext *ctx, arg_fmadd_d *a)
+{
+REQUIRE_FPU;
+REQUIRE_EXT(ctx, RVD);
+gen_set_rm(ctx, a->rm);
+gen_helper_fmadd_d(cpu_fpr[a->rd], cpu_env, cpu_fpr[a->rs1],
+   cpu_fpr[a->rs2], cpu_fpr[a->rs3]);
+mark_fs_dirty(ctx);
+return true;
+}
+
+static bool trans_fmsub_d(DisasContext *ctx, arg_fmsub_d *a)
+{
+REQUIRE_FPU;
+REQUIRE_EXT(ctx, RVD);
+gen_set_rm(ctx, a->rm);
+gen_helper_fmsub_d(cpu_fpr[a->rd], cpu_env, cpu_fpr[a->rs1],
+   cpu_fpr[a->rs2], cpu_fpr[a->rs3]);
+mark_fs_dirty(ctx);
+return true;
+}
+
+static bool trans_fnmsub_d(DisasContext *ctx, arg_fnmsub_d *a)
+{
+REQUIRE_FPU;
+REQUIRE_EXT(ctx,

[Qemu-devel] [PULL 16/29] target/riscv: Convert quadrant 0 of RVXC insns to decodetree

2019-03-12 Thread Palmer Dabbelt
From: Bastian Koppelmann 

Reviewed-by: Richard Henderson 
Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 
Signed-off-by: Palmer Dabbelt 
---
 target/riscv/Makefile.objs  |  9 ++-
 target/riscv/insn16.decode  | 55 ++
 target/riscv/insn_trans/trans_rvc.inc.c | 75 +
 target/riscv/translate.c| 53 ++---
 4 files changed, 154 insertions(+), 38 deletions(-)
 create mode 100644 target/riscv/insn16.decode
 create mode 100644 target/riscv/insn_trans/trans_rvc.inc.c

diff --git a/target/riscv/Makefile.objs b/target/riscv/Makefile.objs
index 05087a91bb85..9c6c1093271e 100644
--- a/target/riscv/Makefile.objs
+++ b/target/riscv/Makefile.objs
@@ -10,4 +10,11 @@ target/riscv/decode_insn32.inc.c: $(decode32-y) $(DECODETREE)
  $(PYTHON) $(DECODETREE) -o $@ --decode decode_insn32 $(decode32-y), \
  "GEN", $(TARGET_DIR)$@)
 
-target/riscv/translate.o: target/riscv/decode_insn32.inc.c
+target/riscv/decode_insn16.inc.c: \
+  $(SRC_PATH)/target/riscv/insn16.decode $(DECODETREE)
+   $(call quiet-command, \
+ $(PYTHON) $(DECODETREE) -o $@ --decode decode_insn16 --insnwidth 16 
$<, \
+ "GEN", $(TARGET_DIR)$@)
+
+target/riscv/translate.o: target/riscv/decode_insn32.inc.c \
+   target/riscv/decode_insn16.inc.c
diff --git a/target/riscv/insn16.decode b/target/riscv/insn16.decode
new file mode 100644
index ..558c0c41f0b5
--- /dev/null
+++ b/target/riscv/insn16.decode
@@ -0,0 +1,55 @@
+#
+# RISC-V translation routines for the RVXI Base Integer Instruction Set.
+#
+# Copyright (c) 2018 Peer Adelt, peer.ad...@hni.uni-paderborn.de
+#Bastian Koppelmann, kbast...@mail.uni-paderborn.de
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms and conditions of the GNU General Public License,
+# version 2 or later, as published by the Free Software Foundation.
+#
+# This program is distributed in the hope it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+# more details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# Fields:
+%rd7:5
+%rs1_3 7:3!function=ex_rvc_register
+%rs2_3 2:3!function=ex_rvc_register
+
+# Immediates:
+%nzuimm_ciw7:4 11:2 5:1 6:1   !function=ex_shift_2
+%uimm_cl_d 5:2 10:3   !function=ex_shift_3
+%uimm_cl_w 5:1 10:3 6:1   !function=ex_shift_2
+
+
+# Argument sets:
+&cl   rs1 rd
+&cl_dw uimm   rs1 rd
+&ciw   nzuimm rd
+&cs   rs1 rs2
+&cs_dw uimm   rs1 rs2
+
+
+# Formats 16:
+@ciw   ...    ... .. &ciwnzuimm=%nzuimm_ciw   rd=%rs2_3
+@cl_d  ... ... ... .. ... .. &cl_dw  uimm=%uimm_cl_d  rs1=%rs1_3  rd=%rs2_3
+@cl_w  ... ... ... .. ... .. &cl_dw  uimm=%uimm_cl_w  rs1=%rs1_3  rd=%rs2_3
+@cl... ... ... .. ... .. &cl  rs1=%rs1_3  rd=%rs2_3
+@cs... ... ... .. ... .. &cs  rs1=%rs1_3  
rs2=%rs2_3
+@cs_d  ... ... ... .. ... .. &cs_dw  uimm=%uimm_cl_d  rs1=%rs1_3  
rs2=%rs2_3
+@cs_w  ... ... ... .. ... .. &cs_dw  uimm=%uimm_cl_w  rs1=%rs1_3  
rs2=%rs2_3
+
+
+# *** RV64C Standard Extension (Quadrant 0) ***
+c_addi4spn000 ... 00 @ciw
+c_fld 001  ... ... .. ... 00 @cl_d
+c_lw  010  ... ... .. ... 00 @cl_w
+c_flw_ld  011  --- ... -- ... 00 @cl#Note: Must parse uimm manually
+c_fsd 101  ... ... .. ... 00 @cs_d
+c_sw  110  ... ... .. ... 00 @cs_w
+c_fsw_sd  111  --- ... -- ... 00 @cs#Note: Must parse uimm manually
diff --git a/target/riscv/insn_trans/trans_rvc.inc.c 
b/target/riscv/insn_trans/trans_rvc.inc.c
new file mode 100644
index ..93ec8aa30b95
--- /dev/null
+++ b/target/riscv/insn_trans/trans_rvc.inc.c
@@ -0,0 +1,75 @@
+/*
+ * RISC-V translation routines for the RVC Compressed Instruction Set.
+ *
+ * Copyright (c) 2016-2017 Sagar Karandikar, sag...@eecs.berkeley.edu
+ * Copyright (c) 2018 Peer Adelt, peer.ad...@hni.uni-paderborn.de
+ *Bastian Koppelmann, kbast...@mail.uni-paderborn.de
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of t

[Qemu-devel] [PULL 11/29] target/riscv: Convert RV32F insns to decodetree

2019-03-12 Thread Palmer Dabbelt
From: Bastian Koppelmann 

Acked-by: Alistair Francis 
Reviewed-by: Richard Henderson 
Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 
Signed-off-by: Palmer Dabbelt 
---
 target/riscv/insn32.decode  |  35 +++
 target/riscv/insn_trans/trans_rvf.inc.c | 379 
 target/riscv/translate.c|   1 +
 3 files changed, 415 insertions(+)
 create mode 100644 target/riscv/insn_trans/trans_rvf.inc.c

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 00b9e2d9a508..e40836bf032f 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -17,12 +17,14 @@
 # this program.  If not, see <http://www.gnu.org/licenses/>.
 
 # Fields:
+%rs3   27:5
 %rs2   20:5
 %rs1   15:5
 %rd7:5
 
 %sh1020:10
 %csr20:12
+%rm 12:3
 
 # immediates:
 %imm_i20:s12
@@ -50,6 +52,11 @@
 @atom_ld . aq:1 rl:1 .  . ... &atomic rs2=0 %rs1 
%rd
 @atom_st . aq:1 rl:1 .  . ... &atomic %rs2  %rs1 
%rd
 
+@r4_rm   . ..  . . ... . ... %rs3 %rs2 %rs1 %rm %rd
+@r_rm...   . . ... . ... %rs2 %rs1 %rm %rd
+@r2_rm   ...   . . ... . ... %rs1 %rm %rd
+@r2  ...   . . ... . ... %rs1 %rd
+
 # *** RV32I Base Instruction Set ***
 lui     . 0110111 @u
 auipc   . 0010111 @u
@@ -119,3 +126,31 @@ amomin_w   1 . . . . 010 . 010 @atom_st
 amomax_w   10100 . . . . 010 . 010 @atom_st
 amominu_w  11000 . . . . 010 . 010 @atom_st
 amomaxu_w  11100 . . . . 010 . 010 @atom_st
+
+# *** RV32F Standard Extension ***
+flw   . 010 . 111 @i
+fsw...  . . 010 . 0100111 @s
+fmadd_s. 00 . . ... . 111 @r4_rm
+fmsub_s. 00 . . ... . 1000111 @r4_rm
+fnmsub_s   . 00 . . ... . 1001011 @r4_rm
+fnmadd_s   . 00 . . ... . 100 @r4_rm
+fadd_s 000  . . ... . 1010011 @r_rm
+fsub_s 100  . . ... . 1010011 @r_rm
+fmul_s 0001000  . . ... . 1010011 @r_rm
+fdiv_s 0001100  . . ... . 1010011 @r_rm
+fsqrt_s0101100  0 . ... . 1010011 @r2_rm
+fsgnj_s001  . . 000 . 1010011 @r
+fsgnjn_s   001  . . 001 . 1010011 @r
+fsgnjx_s   001  . . 010 . 1010011 @r
+fmin_s 0010100  . . 000 . 1010011 @r
+fmax_s 0010100  . . 001 . 1010011 @r
+fcvt_w_s   110  0 . ... . 1010011 @r2_rm
+fcvt_wu_s  110  1 . ... . 1010011 @r2_rm
+fmv_x_w111  0 . 000 . 1010011 @r2
+feq_s  101  . . 010 . 1010011 @r
+flt_s  101  . . 001 . 1010011 @r
+fle_s  101  . . 000 . 1010011 @r
+fclass_s   111  0 . 001 . 1010011 @r2
+fcvt_s_w   1101000  0 . ... . 1010011 @r2_rm
+fcvt_s_wu  1101000  1 . ... . 1010011 @r2_rm
+fmv_w_x000  0 . 000 . 1010011 @r2
diff --git a/target/riscv/insn_trans/trans_rvf.inc.c 
b/target/riscv/insn_trans/trans_rvf.inc.c
new file mode 100644
index ..0f837903491b
--- /dev/null
+++ b/target/riscv/insn_trans/trans_rvf.inc.c
@@ -0,0 +1,379 @@
+/*
+ * RISC-V translation routines for the RV64F Standard Extension.
+ *
+ * Copyright (c) 2016-2017 Sagar Karandikar, sag...@eecs.berkeley.edu
+ * Copyright (c) 2018 Peer Adelt, peer.ad...@hni.uni-paderborn.de
+ *Bastian Koppelmann, kbast...@mail.uni-paderborn.de
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define REQUIRE_FPU do {\
+if (ctx->mstatus_fs == 0) \
+return false;   \
+} while (0)
+
+static bool trans_flw(DisasContext *ctx, arg_flw *a)
+{
+TCGv t0 = tcg_temp_new();
+gen_get_gpr(t0, a->rs1);
+REQUIRE_FPU;
+REQUIRE_EXT(ctx, RVF);
+tcg_gen_addi_tl(t0, t0, a->imm);
+
+tcg_gen_qemu_ld_i64(cpu_fpr[a->rd], t0, ctx->mem_idx, MO_TEUL);
+/* RISC-V requires NaN-boxing of narrower width floating point values */
+tcg_gen_ori_i64(cpu_fpr[a->rd], cpu_fpr[a->rd], 0xULL);
+
+tcg_temp_free(t0);
+mark_fs_d

[Qemu-devel] [PULL 04/29] target/riscv: Convert RV64I load/store insns to decodetree

2019-03-12 Thread Palmer Dabbelt
From: Bastian Koppelmann 

this splits the 64-bit only instructions into its own decode file such
that we generate the decoder for these instructions only for the RISC-V
64 bit target.

Acked-by: Alistair Francis 
Reviewed-by: Richard Henderson 
Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 
Signed-off-by: Palmer Dabbelt 
---
 target/riscv/Makefile.objs  |  8 +---
 target/riscv/insn32-64.decode   | 25 +
 target/riscv/insn_trans/trans_rvi.inc.c | 20 
 target/riscv/translate.c|  7 ---
 4 files changed, 50 insertions(+), 10 deletions(-)
 create mode 100644 target/riscv/insn32-64.decode

diff --git a/target/riscv/Makefile.objs b/target/riscv/Makefile.objs
index bf0a268033a0..05087a91bb85 100644
--- a/target/riscv/Makefile.objs
+++ b/target/riscv/Makefile.objs
@@ -2,10 +2,12 @@ obj-y += translate.o op_helper.o cpu_helper.o cpu.o csr.o 
fpu_helper.o gdbstub.o
 
 DECODETREE = $(SRC_PATH)/scripts/decodetree.py
 
-target/riscv/decode_insn32.inc.c: \
-  $(SRC_PATH)/target/riscv/insn32.decode $(DECODETREE)
+decode32-y = $(SRC_PATH)/target/riscv/insn32.decode
+decode32-$(TARGET_RISCV64) += $(SRC_PATH)/target/riscv/insn32-64.decode
+
+target/riscv/decode_insn32.inc.c: $(decode32-y) $(DECODETREE)
$(call quiet-command, \
- $(PYTHON) $(DECODETREE) -o $@ --decode decode_insn32 $<, \
+ $(PYTHON) $(DECODETREE) -o $@ --decode decode_insn32 $(decode32-y), \
  "GEN", $(TARGET_DIR)$@)
 
 target/riscv/translate.o: target/riscv/decode_insn32.inc.c
diff --git a/target/riscv/insn32-64.decode b/target/riscv/insn32-64.decode
new file mode 100644
index ..439d4e2c587b
--- /dev/null
+++ b/target/riscv/insn32-64.decode
@@ -0,0 +1,25 @@
+#
+# RISC-V translation routines for the RV Instruction Set.
+#
+# Copyright (c) 2018 Peer Adelt, peer.ad...@hni.uni-paderborn.de
+#Bastian Koppelmann, kbast...@mail.uni-paderborn.de
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms and conditions of the GNU General Public License,
+# version 2 or later, as published by the Free Software Foundation.
+#
+# This program is distributed in the hope it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+# more details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# This is concatenated with insn32.decode for risc64 targets.
+# Most of the fields and formats are there.
+
+# *** RV64I Base Instruction Set (in addition to RV32I) ***
+lwu     . 110 . 011 @i
+ld      . 011 . 011 @i
+sd   ... .  . 011 . 0100011 @s
diff --git a/target/riscv/insn_trans/trans_rvi.inc.c 
b/target/riscv/insn_trans/trans_rvi.inc.c
index d13b7b2b6d8f..61f708dba144 100644
--- a/target/riscv/insn_trans/trans_rvi.inc.c
+++ b/target/riscv/insn_trans/trans_rvi.inc.c
@@ -130,3 +130,23 @@ static bool trans_sw(DisasContext *ctx, arg_sw *a)
 gen_store(ctx, OPC_RISC_SW, a->rs1, a->rs2, a->imm);
 return true;
 }
+
+#ifdef TARGET_RISCV64
+static bool trans_lwu(DisasContext *ctx, arg_lwu *a)
+{
+gen_load(ctx, OPC_RISC_LWU, a->rd, a->rs1, a->imm);
+return true;
+}
+
+static bool trans_ld(DisasContext *ctx, arg_ld *a)
+{
+gen_load(ctx, OPC_RISC_LD, a->rd, a->rs1, a->imm);
+return true;
+}
+
+static bool trans_sd(DisasContext *ctx, arg_sd *a)
+{
+gen_store(ctx, OPC_RISC_SD, a->rs1, a->rs2, a->imm);
+return true;
+}
+#endif
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index fb284a5e08d6..2e35142ca2a4 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -1908,13 +1908,6 @@ static void decode_RV32_64G(DisasContext *ctx)
 imm = GET_IMM(ctx->opcode);
 
 switch (op) {
-case OPC_RISC_LOAD:
-gen_load(ctx, MASK_OP_LOAD(ctx->opcode), rd, rs1, imm);
-break;
-case OPC_RISC_STORE:
-gen_store(ctx, MASK_OP_STORE(ctx->opcode), rs1, rs2,
-  GET_STORE_IMM(ctx->opcode));
-break;
 case OPC_RISC_ARITH_IMM:
 #if defined(TARGET_RISCV64)
 case OPC_RISC_ARITH_IMM_W:
-- 
2.19.2




[Qemu-devel] [PULL 08/29] target/riscv: Convert RVXM insns to decodetree

2019-03-12 Thread Palmer Dabbelt
From: Bastian Koppelmann 

Acked-by: Alistair Francis 
Reviewed-by: Richard Henderson 
Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 
Signed-off-by: Palmer Dabbelt 
---
 target/riscv/insn32-64.decode   |   7 ++
 target/riscv/insn32.decode  |  10 +++
 target/riscv/insn_trans/trans_rvm.inc.c | 113 
 target/riscv/translate.c|  16 ++--
 4 files changed, 137 insertions(+), 9 deletions(-)
 create mode 100644 target/riscv/insn_trans/trans_rvm.inc.c

diff --git a/target/riscv/insn32-64.decode b/target/riscv/insn32-64.decode
index 9a35f2aa1920..008f1005469e 100644
--- a/target/riscv/insn32-64.decode
+++ b/target/riscv/insn32-64.decode
@@ -36,3 +36,10 @@ subw 010 .  . 000 . 0111011 @r
 sllw 000 .  . 001 . 0111011 @r
 srlw 000 .  . 101 . 0111011 @r
 sraw 010 .  . 101 . 0111011 @r
+
+# *** RV64M Standard Extension (in addition to RV32M) ***
+mulw 001 .  . 000 . 0111011 @r
+divw 001 .  . 100 . 0111011 @r
+divuw001 .  . 101 . 0111011 @r
+remw 001 .  . 110 . 0111011 @r
+remuw001 .  . 111 . 0111011 @r
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 977b1b10a330..e53944bf0e40 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -92,3 +92,13 @@ csrrc . 011 . 1110011 @csr
 csrrwi    . 101 . 1110011 @csr
 csrrsi    . 110 . 1110011 @csr
 csrrci    . 111 . 1110011 @csr
+
+# *** RV32M Standard Extension ***
+mul  001 .  . 000 . 0110011 @r
+mulh 001 .  . 001 . 0110011 @r
+mulhsu   001 .  . 010 . 0110011 @r
+mulhu001 .  . 011 . 0110011 @r
+div  001 .  . 100 . 0110011 @r
+divu 001 .  . 101 . 0110011 @r
+rem  001 .  . 110 . 0110011 @r
+remu 001 .  . 111 . 0110011 @r
diff --git a/target/riscv/insn_trans/trans_rvm.inc.c 
b/target/riscv/insn_trans/trans_rvm.inc.c
new file mode 100644
index ..69631c9e3783
--- /dev/null
+++ b/target/riscv/insn_trans/trans_rvm.inc.c
@@ -0,0 +1,113 @@
+/*
+ * RISC-V translation routines for the RV64M Standard Extension.
+ *
+ * Copyright (c) 2016-2017 Sagar Karandikar, sag...@eecs.berkeley.edu
+ * Copyright (c) 2018 Peer Adelt, peer.ad...@hni.uni-paderborn.de
+ *Bastian Koppelmann, kbast...@mail.uni-paderborn.de
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+static bool trans_mul(DisasContext *ctx, arg_mul *a)
+{
+REQUIRE_EXT(ctx, RVM);
+gen_arith(ctx, OPC_RISC_MUL, a->rd, a->rs1, a->rs2);
+return true;
+}
+
+static bool trans_mulh(DisasContext *ctx, arg_mulh *a)
+{
+REQUIRE_EXT(ctx, RVM);
+gen_arith(ctx, OPC_RISC_MULH, a->rd, a->rs1, a->rs2);
+return true;
+}
+
+static bool trans_mulhsu(DisasContext *ctx, arg_mulhsu *a)
+{
+REQUIRE_EXT(ctx, RVM);
+gen_arith(ctx, OPC_RISC_MULHSU, a->rd, a->rs1, a->rs2);
+return true;
+}
+
+static bool trans_mulhu(DisasContext *ctx, arg_mulhu *a)
+{
+REQUIRE_EXT(ctx, RVM);
+gen_arith(ctx, OPC_RISC_MULHU, a->rd, a->rs1, a->rs2);
+return true;
+}
+
+static bool trans_div(DisasContext *ctx, arg_div *a)
+{
+REQUIRE_EXT(ctx, RVM);
+gen_arith(ctx, OPC_RISC_DIV, a->rd, a->rs1, a->rs2);
+return true;
+}
+
+static bool trans_divu(DisasContext *ctx, arg_divu *a)
+{
+REQUIRE_EXT(ctx, RVM);
+gen_arith(ctx, OPC_RISC_DIVU, a->rd, a->rs1, a->rs2);
+return true;
+}
+
+static bool trans_rem(DisasContext *ctx, arg_rem *a)
+{
+REQUIRE_EXT(ctx, RVM);
+gen_arith(ctx, OPC_RISC_REM, a->rd, a->rs1, a->rs2);
+return true;
+}
+
+static bool trans_remu(DisasContext *ctx, arg_remu *a)
+{
+REQUIRE_EXT(ctx, RVM);
+gen_arith(ctx, OPC_RISC_REMU, a->rd, a->rs1, a->rs2);
+return true;
+}
+
+#ifdef TARGET_RISCV64
+static bool trans_mulw(DisasContext *ctx, arg_mulw *a)
+{
+REQUIRE_EXT(ctx, RVM);
+gen_arith(ctx, OPC_RISC_MULW, a->rd, a->rs1, a->rs2);
+return true;
+}
+
+static bool trans_divw(DisasContext *ctx, arg_divw *a)
+{
+REQUIRE_EXT(ctx, RVM);
+ge

[Qemu-devel] [PULL 10/29] target/riscv: Convert RV64A insns to decodetree

2019-03-12 Thread Palmer Dabbelt
From: Bastian Koppelmann 

Acked-by: Alistair Francis 
Reviewed-by: Richard Henderson 
Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 
Signed-off-by: Palmer Dabbelt 
---
 target/riscv/insn32-64.decode   |  13 +++
 target/riscv/insn_trans/trans_rva.inc.c |  58 ++
 target/riscv/translate.c| 144 
 3 files changed, 71 insertions(+), 144 deletions(-)

diff --git a/target/riscv/insn32-64.decode b/target/riscv/insn32-64.decode
index 008f1005469e..0bee95c9840d 100644
--- a/target/riscv/insn32-64.decode
+++ b/target/riscv/insn32-64.decode
@@ -43,3 +43,16 @@ divw 001 .  . 100 . 0111011 @r
 divuw001 .  . 101 . 0111011 @r
 remw 001 .  . 110 . 0111011 @r
 remuw001 .  . 111 . 0111011 @r
+
+# *** RV64A Standard Extension (in addition to RV32A) ***
+lr_d   00010 . . 0 . 011 . 010 @atom_ld
+sc_d   00011 . . . . 011 . 010 @atom_st
+amoswap_d  1 . . . . 011 . 010 @atom_st
+amoadd_d   0 . . . . 011 . 010 @atom_st
+amoxor_d   00100 . . . . 011 . 010 @atom_st
+amoand_d   01100 . . . . 011 . 010 @atom_st
+amoor_d01000 . . . . 011 . 010 @atom_st
+amomin_d   1 . . . . 011 . 010 @atom_st
+amomax_d   10100 . . . . 011 . 010 @atom_st
+amominu_d  11000 . . . . 011 . 010 @atom_st
+amomaxu_d  11100 . . . . 011 . 010 @atom_st
diff --git a/target/riscv/insn_trans/trans_rva.inc.c 
b/target/riscv/insn_trans/trans_rva.inc.c
index 5d3c853ca504..f6dbbc065e15 100644
--- a/target/riscv/insn_trans/trans_rva.inc.c
+++ b/target/riscv/insn_trans/trans_rva.inc.c
@@ -158,3 +158,61 @@ static bool trans_amomaxu_w(DisasContext *ctx, 
arg_amomaxu_w *a)
 REQUIRE_EXT(ctx, RVA);
 return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umax_tl, (MO_ALIGN | 
MO_TESL));
 }
+
+#ifdef TARGET_RISCV64
+
+static bool trans_lr_d(DisasContext *ctx, arg_lr_d *a)
+{
+return gen_lr(ctx, a, MO_ALIGN | MO_TEQ);
+}
+
+static bool trans_sc_d(DisasContext *ctx, arg_sc_d *a)
+{
+return gen_sc(ctx, a, (MO_ALIGN | MO_TEQ));
+}
+
+static bool trans_amoswap_d(DisasContext *ctx, arg_amoswap_d *a)
+{
+return gen_amo(ctx, a, &tcg_gen_atomic_xchg_tl, (MO_ALIGN | MO_TEQ));
+}
+
+static bool trans_amoadd_d(DisasContext *ctx, arg_amoadd_d *a)
+{
+return gen_amo(ctx, a, &tcg_gen_atomic_fetch_add_tl, (MO_ALIGN | MO_TEQ));
+}
+
+static bool trans_amoxor_d(DisasContext *ctx, arg_amoxor_d *a)
+{
+return gen_amo(ctx, a, &tcg_gen_atomic_fetch_xor_tl, (MO_ALIGN | MO_TEQ));
+}
+
+static bool trans_amoand_d(DisasContext *ctx, arg_amoand_d *a)
+{
+return gen_amo(ctx, a, &tcg_gen_atomic_fetch_and_tl, (MO_ALIGN | MO_TEQ));
+}
+
+static bool trans_amoor_d(DisasContext *ctx, arg_amoor_d *a)
+{
+return gen_amo(ctx, a, &tcg_gen_atomic_fetch_or_tl, (MO_ALIGN | MO_TEQ));
+}
+
+static bool trans_amomin_d(DisasContext *ctx, arg_amomin_d *a)
+{
+return gen_amo(ctx, a, &tcg_gen_atomic_fetch_smin_tl, (MO_ALIGN | MO_TEQ));
+}
+
+static bool trans_amomax_d(DisasContext *ctx, arg_amomax_d *a)
+{
+return gen_amo(ctx, a, &tcg_gen_atomic_fetch_smax_tl, (MO_ALIGN | MO_TEQ));
+}
+
+static bool trans_amominu_d(DisasContext *ctx, arg_amominu_d *a)
+{
+return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umin_tl, (MO_ALIGN | MO_TEQ));
+}
+
+static bool trans_amomaxu_d(DisasContext *ctx, arg_amomaxu_d *a)
+{
+return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umax_tl, (MO_ALIGN | MO_TEQ));
+}
+#endif
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index b0de062a4fd1..c2791459993e 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -794,143 +794,6 @@ static void gen_fp_store(DisasContext *ctx, uint32_t opc, 
int rs1,
 tcg_temp_free(t0);
 }
 
-static void gen_atomic(DisasContext *ctx, uint32_t opc,
-  int rd, int rs1, int rs2)
-{
-TCGv src1, src2, dat;
-TCGLabel *l1, *l2;
-TCGMemOp mop;
-bool aq, rl;
-
-/* Extract the size of the atomic operation.  */
-switch (extract32(opc, 12, 3)) {
-case 2: /* 32-bit */
-mop = MO_ALIGN | MO_TESL;
-break;
-#if defined(TARGET_RISCV64)
-case 3: /* 64-bit */
-mop = MO_ALIGN | MO_TEQ;
-break;
-#endif
-default:
-gen_exception_illegal(ctx);
-return;
-}
-rl = extract32(opc, 25, 1);
-aq = extract32(opc, 26, 1);
-
-src1 = tcg_temp_new();
-src2 = tcg_temp_new();
-
-switch (MASK_OP_ATOMIC_NO_AQ_RL_SZ(opc)) {
-case OPC_RISC_LR:
-/* Put addr in load_res, data in load_val.  */
-gen_get_gpr(src1, rs1);
-if (rl) {
-tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
-}
-tcg_gen_qemu_ld_tl(load_val, src1, ctx->mem_idx, mop);
-if (aq) {
- 

[Qemu-devel] [PULL 15/29] target/riscv: Convert RV priv insns to decodetree

2019-03-12 Thread Palmer Dabbelt
From: Bastian Koppelmann 

Acked-by: Alistair Francis 
Reviewed-by: Richard Henderson 
Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 
Signed-off-by: Palmer Dabbelt 
---
 target/riscv/insn32.decode|  15 +++
 .../riscv/insn_trans/trans_privileged.inc.c   | 110 ++
 target/riscv/translate.c  |  57 +
 3 files changed, 126 insertions(+), 56 deletions(-)
 create mode 100644 target/riscv/insn_trans/trans_privileged.inc.c

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index e64b2b5e3458..ecc46a50cc27 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -57,6 +57,21 @@
 @r2_rm   ...   . . ... . ... %rs1 %rm %rd
 @r2  ...   . . ... . ... %rs1 %rd
 
+@sfence_vma ... . .   ... . ... %rs2 %rs1
+@sfence_vm  ... . .   ... . ... %rs1
+
+
+# *** Privileged Instructions ***
+ecall   0 000 0 1110011
+ebreak 0001 0 000 0 1110011
+uret   00000010 0 000 0 1110011
+sret   000100000010 0 000 0 1110011
+hret   00100010 0 000 0 1110011
+mret   001100000010 0 000 0 1110011
+wfi000100000101 0 000 0 1110011
+sfence_vma 0001001. . 000 0 1110011 @sfence_vma
+sfence_vm  000100000100 . 000 0 1110011 @sfence_vm
+
 # *** RV32I Base Instruction Set ***
 lui     . 0110111 @u
 auipc   . 0010111 @u
diff --git a/target/riscv/insn_trans/trans_privileged.inc.c 
b/target/riscv/insn_trans/trans_privileged.inc.c
new file mode 100644
index ..acb605923e68
--- /dev/null
+++ b/target/riscv/insn_trans/trans_privileged.inc.c
@@ -0,0 +1,110 @@
+/*
+ * RISC-V translation routines for the RISC-V privileged instructions.
+ *
+ * Copyright (c) 2016-2017 Sagar Karandikar, sag...@eecs.berkeley.edu
+ * Copyright (c) 2018 Peer Adelt, peer.ad...@hni.uni-paderborn.de
+ *Bastian Koppelmann, kbast...@mail.uni-paderborn.de
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+static bool trans_ecall(DisasContext *ctx, arg_ecall *a)
+{
+/* always generates U-level ECALL, fixed in do_interrupt handler */
+generate_exception(ctx, RISCV_EXCP_U_ECALL);
+tcg_gen_exit_tb(NULL, 0); /* no chaining */
+ctx->base.is_jmp = DISAS_NORETURN;
+return true;
+}
+
+static bool trans_ebreak(DisasContext *ctx, arg_ebreak *a)
+{
+generate_exception(ctx, RISCV_EXCP_BREAKPOINT);
+tcg_gen_exit_tb(NULL, 0); /* no chaining */
+ctx->base.is_jmp = DISAS_NORETURN;
+return true;
+}
+
+static bool trans_uret(DisasContext *ctx, arg_uret *a)
+{
+return false;
+}
+
+static bool trans_sret(DisasContext *ctx, arg_sret *a)
+{
+#ifndef CONFIG_USER_ONLY
+tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next);
+
+if (has_ext(ctx, RVS)) {
+gen_helper_sret(cpu_pc, cpu_env, cpu_pc);
+tcg_gen_exit_tb(NULL, 0); /* no chaining */
+ctx->base.is_jmp = DISAS_NORETURN;
+} else {
+return false;
+}
+return true;
+#else
+return false;
+#endif
+}
+
+static bool trans_hret(DisasContext *ctx, arg_hret *a)
+{
+return false;
+}
+
+static bool trans_mret(DisasContext *ctx, arg_mret *a)
+{
+#ifndef CONFIG_USER_ONLY
+tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next);
+gen_helper_mret(cpu_pc, cpu_env, cpu_pc);
+tcg_gen_exit_tb(NULL, 0); /* no chaining */
+ctx->base.is_jmp = DISAS_NORETURN;
+return true;
+#else
+return false;
+#endif
+}
+
+static bool trans_wfi(DisasContext *ctx, arg_wfi *a)
+{
+#ifndef CONFIG_USER_ONLY
+tcg_gen_movi_tl(cpu_pc, ctx->pc_succ_insn);
+gen_helper_wfi(cpu_env);
+return true;
+#else
+return false;
+#endif
+}
+
+static bool trans_sfence_vma(DisasContext *ctx, arg_sfence_vma *a)
+{
+#ifndef CONFIG_USER_ONLY
+if (ctx->priv_ver == PRIV_VERSION_1_10_0) {
+gen_helper_tlb_flush(cpu_env);
+return true;
+}
+#endif
+return false;
+}
+
+static bool trans_sfence_vm(DisasContext *ctx, arg_sfence_vm *a)
+{
+#ifndef CONFIG_USER_ONLY
+if (ctx->priv_ver <= PRIV_VERSION_1_09_1) {
+gen_helper_tlb_flush(cpu_env);
+return true;
+}
+#endif
+return false;
+}
diff --git a/target/riscv/tr

[Qemu-devel] [PULL] target/riscv: Convert to decodetree

2019-03-12 Thread Palmer Dabbelt
The following changes since commit 377b155bde451d5ac545fbdcdfbf6ca17a4228f5:

  Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging 
(2019-03-11 18:26:37 +)

are available in the Git repository at:

  git://github.com/palmer-dabbelt/qemu.git tags/riscv-for-master-4.0-sf3

for you to fetch changes up to a971f8ae0e8ab6fab1eee199961b1ea2f4d876f7:

  target/riscv: Remove decode_RV32_64G() (2019-03-12 03:08:34 -0700)


target/riscv: Convert to decodetree

Bastian: this patchset converts the RISC-V decoder to decodetree in four major 
steps:

1) Convert 32-bit instructions to decodetree [Patch 1-15]:
Many of the gen_* functions are called by the decode functions for 16-bit
and 32-bit functions. If we move translation code from the gen_*
functions to the generated trans_* functions of decode-tree, we get a lot of
duplication. Therefore, we mostly generate calls to the old gen_* function
which are properly replaced after step 2).

Each of the trans_ functions are grouped into files corresponding to their
ISA extension, e.g. addi which is in RV32I is translated in the file
'trans_rvi.inc.c'.

2) Convert 16-bit instructions to decodetree [Patch 16-18]:
All 16 bit instructions have a direct mapping to a 32 bit instruction. Thus,
we convert the arguments in the 16 bit trans_ function to the arguments of
the corresponding 32 bit instruction and call the 32 bit trans_ function.

3) Remove old manual decoding in gen_* function [Patch 19-29]:
this move all manual translation code into the trans_* instructions of
decode tree, such that we can remove the old decode_* functions.

Palmer: This, with some additional cleanup patches, passed Alistar's
testing on rv32 and rv64 as well as my testing on rv64, so I think it's
good to go.  I've run my standard test against this exact tag.  I
haven't tested the OSX build because I didn't find an OSX machine (I'm
traveling), but I removed the offending commits so hopefully we're safe.


Bastian Koppelmann (29):
  target/riscv: Activate decodetree and implemnt LUI & AUIPC
  target/riscv: Convert RVXI branch insns to decodetree
  target/riscv: Convert RV32I load/store insns to decodetree
  target/riscv: Convert RV64I load/store insns to decodetree
  target/riscv: Convert RVXI arithmetic insns to decodetree
  target/riscv: Convert RVXI fence insns to decodetree
  target/riscv: Convert RVXI csr insns to decodetree
  target/riscv: Convert RVXM insns to decodetree
  target/riscv: Convert RV32A insns to decodetree
  target/riscv: Convert RV64A insns to decodetree
  target/riscv: Convert RV32F insns to decodetree
  target/riscv: Convert RV64F insns to decodetree
  target/riscv: Convert RV32D insns to decodetree
  target/riscv: Convert RV64D insns to decodetree
  target/riscv: Convert RV priv insns to decodetree
  target/riscv: Convert quadrant 0 of RVXC insns to decodetree
  target/riscv: Convert quadrant 1 of RVXC insns to decodetree
  target/riscv: Convert quadrant 2 of RVXC insns to decodetree
  target/riscv: Remove gen_jalr()
  target/riscv: Remove manual decoding from gen_branch()
  target/riscv: Remove manual decoding from gen_load()
  target/riscv: Remove manual decoding from gen_store()
  target/riscv: Move gen_arith_imm() decoding into trans_* functions
  target/riscv: make ADD/SUB/OR/XOR/AND insn use arg lists
  target/riscv: Remove shift and slt insn manual decoding
  target/riscv: Remove manual decoding of RV32/64M insn
  target/riscv: Rename trans_arith to gen_arith
  target/riscv: Remove gen_system()
  target/riscv: Remove decode_RV32_64G()

 target/riscv/Makefile.objs |   19 +
 target/riscv/insn16.decode |  129 ++
 target/riscv/insn32-64.decode  |   72 +
 target/riscv/insn32.decode |  201 +++
 target/riscv/insn_trans/trans_privileged.inc.c |  110 ++
 target/riscv/insn_trans/trans_rva.inc.c|  218 +++
 target/riscv/insn_trans/trans_rvc.inc.c|  327 +
 target/riscv/insn_trans/trans_rvd.inc.c|  442 ++
 target/riscv/insn_trans/trans_rvf.inc.c|  439 ++
 target/riscv/insn_trans/trans_rvi.inc.c|  568 
 target/riscv/insn_trans/trans_rvm.inc.c|  120 ++
 target/riscv/translate.c   | 1847 
 12 files changed, 2897 insertions(+), 1595 deletions(-)
 create mode 100644 target/riscv/insn16.decode
 create mode 100644 target/riscv/insn32-64.decode
 create mode 100644 target/riscv/insn32.decode
 create mode 100644 target/riscv/insn_trans/trans_privileged.inc.c
 create mode 100644 target/riscv/insn_trans/trans_rva.inc.c
 create mode 

[Qemu-devel] [PULL 07/29] target/riscv: Convert RVXI csr insns to decodetree

2019-03-12 Thread Palmer Dabbelt
From: Bastian Koppelmann 

Acked-by: Alistair Francis 
Reviewed-by: Richard Henderson 
Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 
Signed-off-by: Palmer Dabbelt 
---
 target/riscv/insn32.decode  |  8 +++
 target/riscv/insn_trans/trans_rvi.inc.c | 79 +
 target/riscv/translate.c| 43 +-
 3 files changed, 88 insertions(+), 42 deletions(-)

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 804b721ca51e..977b1b10a330 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -22,6 +22,7 @@
 %rd7:5
 
 %sh1020:10
+%csr20:12
 
 # immediates:
 %imm_i20:s12
@@ -43,6 +44,7 @@
 @j     . ... imm=%imm_j  
%rd
 
 @sh  ..  .. .  ... . ... &shift  shamt=%sh10  %rs1 
%rd
+@csr    .  ... . ...   %csr %rs1 
%rd
 
 # *** RV32I Base Instruction Set ***
 lui     . 0110111 @u
@@ -84,3 +86,9 @@ or   000 .. 110 . 0110011 @r
 and  000 .. 111 . 0110011 @r
 fence pred:4 succ:4 - 000 - 000
 fence_i         - 001 - 000
+csrrw . 001 . 1110011 @csr
+csrrs . 010 . 1110011 @csr
+csrrc . 011 . 1110011 @csr
+csrrwi    . 101 . 1110011 @csr
+csrrsi    . 110 . 1110011 @csr
+csrrci    . 111 . 1110011 @csr
diff --git a/target/riscv/insn_trans/trans_rvi.inc.c 
b/target/riscv/insn_trans/trans_rvi.inc.c
index 973d6371df85..4a23372cb823 100644
--- a/target/riscv/insn_trans/trans_rvi.inc.c
+++ b/target/riscv/insn_trans/trans_rvi.inc.c
@@ -337,3 +337,82 @@ static bool trans_fence_i(DisasContext *ctx, arg_fence_i 
*a)
 ctx->base.is_jmp = DISAS_NORETURN;
 return true;
 }
+
+#define RISCV_OP_CSR_PRE do {\
+source1 = tcg_temp_new(); \
+csr_store = tcg_temp_new(); \
+dest = tcg_temp_new(); \
+rs1_pass = tcg_temp_new(); \
+gen_get_gpr(source1, a->rs1); \
+tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next); \
+tcg_gen_movi_tl(rs1_pass, a->rs1); \
+tcg_gen_movi_tl(csr_store, a->csr); \
+gen_io_start();\
+} while (0)
+
+#define RISCV_OP_CSR_POST do {\
+gen_io_end(); \
+gen_set_gpr(a->rd, dest); \
+tcg_gen_movi_tl(cpu_pc, ctx->pc_succ_insn); \
+tcg_gen_exit_tb(NULL, 0); \
+ctx->base.is_jmp = DISAS_NORETURN; \
+tcg_temp_free(source1); \
+tcg_temp_free(csr_store); \
+tcg_temp_free(dest); \
+tcg_temp_free(rs1_pass); \
+} while (0)
+
+
+static bool trans_csrrw(DisasContext *ctx, arg_csrrw *a)
+{
+TCGv source1, csr_store, dest, rs1_pass;
+RISCV_OP_CSR_PRE;
+gen_helper_csrrw(dest, cpu_env, source1, csr_store);
+RISCV_OP_CSR_POST;
+return true;
+}
+
+static bool trans_csrrs(DisasContext *ctx, arg_csrrs *a)
+{
+TCGv source1, csr_store, dest, rs1_pass;
+RISCV_OP_CSR_PRE;
+gen_helper_csrrs(dest, cpu_env, source1, csr_store, rs1_pass);
+RISCV_OP_CSR_POST;
+return true;
+}
+
+static bool trans_csrrc(DisasContext *ctx, arg_csrrc *a)
+{
+TCGv source1, csr_store, dest, rs1_pass;
+RISCV_OP_CSR_PRE;
+gen_helper_csrrc(dest, cpu_env, source1, csr_store, rs1_pass);
+RISCV_OP_CSR_POST;
+return true;
+}
+
+static bool trans_csrrwi(DisasContext *ctx, arg_csrrwi *a)
+{
+TCGv source1, csr_store, dest, rs1_pass;
+RISCV_OP_CSR_PRE;
+gen_helper_csrrw(dest, cpu_env, rs1_pass, csr_store);
+RISCV_OP_CSR_POST;
+return true;
+}
+
+static bool trans_csrrsi(DisasContext *ctx, arg_csrrsi *a)
+{
+TCGv source1, csr_store, dest, rs1_pass;
+RISCV_OP_CSR_PRE;
+gen_helper_csrrs(dest, cpu_env, rs1_pass, csr_store, rs1_pass);
+RISCV_OP_CSR_POST;
+return true;
+}
+
+static bool trans_csrrci(DisasContext *ctx, arg_csrrci *a)
+{
+TCGv source1, csr_store, dest, rs1_pass;
+RISCV_OP_CSR_PRE;
+gen_helper_csrrc(dest, cpu_env, rs1_pass, csr_store, rs1_pass);
+RISCV_OP_CSR_POST;
+return true;
+}
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index f720746cb791..18555000af35 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -1476,16 +1476,11 @@ static void gen_fp_arith(DisasContext *ctx, uint32_t 
opc, int rd,
 static void gen_system(DisasContext *ctx, uint32_t opc, int rd, int rs1,
int csr)
 {
-TCGv source1, csr_store, dest, rs1_pass, imm_rs1;
+TCGv source1, dest;
 source1 = tcg_temp_new();
-csr_store = tcg_temp_new();
 dest = tcg_temp_new();
-rs1_pass = tcg_temp_new();
-imm_rs1 = tcg_temp_new();
 gen_get_gpr(source1, rs1);
 tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next);
-tcg_gen_movi_tl(rs1_pass, rs1);
-tcg_gen_movi_tl(csr_store, csr); /* copy 

[Qemu-devel] [PULL 05/29] target/riscv: Convert RVXI arithmetic insns to decodetree

2019-03-12 Thread Palmer Dabbelt
From: Bastian Koppelmann 

we cannot remove the call to gen_arith() in decode_RV32_64G() since it
is used to translate multiply instructions.

Acked-by: Alistair Francis 
Reviewed-by: Richard Henderson 
Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 
Signed-off-by: Palmer Dabbelt 
---
 target/riscv/insn32-64.decode   |  13 ++
 target/riscv/insn32.decode  |  25 
 target/riscv/insn_trans/trans_rvi.inc.c | 168 
 target/riscv/translate.c|   9 --
 4 files changed, 206 insertions(+), 9 deletions(-)

diff --git a/target/riscv/insn32-64.decode b/target/riscv/insn32-64.decode
index 439d4e2c587b..9a35f2aa1920 100644
--- a/target/riscv/insn32-64.decode
+++ b/target/riscv/insn32-64.decode
@@ -19,7 +19,20 @@
 # This is concatenated with insn32.decode for risc64 targets.
 # Most of the fields and formats are there.
 
+%sh520:5
+
+@sh5 ...  . .  ... . ... &shift  shamt=%sh5  %rs1 
%rd
+
 # *** RV64I Base Instruction Set (in addition to RV32I) ***
 lwu     . 110 . 011 @i
 ld      . 011 . 011 @i
 sd   ... .  . 011 . 0100011 @s
+addiw   . 000 . 0011011 @i
+slliw000 .  . 001 . 0011011 @sh5
+srliw000 .  . 101 . 0011011 @sh5
+sraiw010 .  . 101 . 0011011 @sh5
+addw 000 .  . 000 . 0111011 @r
+subw 010 .  . 000 . 0111011 @r
+sllw 000 .  . 001 . 0111011 @r
+srlw 000 .  . 101 . 0111011 @r
+sraw 010 .  . 101 . 0111011 @r
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 076de873c4f1..1f5bf1f6f97d 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -21,6 +21,8 @@
 %rs1   15:5
 %rd7:5
 
+%sh1020:10
+
 # immediates:
 %imm_i20:s12
 %imm_s25:s7 7:5
@@ -30,14 +32,18 @@
 
 # Argument sets:
 &bimm rs2 rs1
+&shift shamt rs1 rd
 
 # Formats 32:
+@r   ...   . . ... . ...   %rs2 %rs1 
%rd
 @i   . ... . ... imm=%imm_i %rs1 
%rd
 @b   ...   . . ... . ... &b  imm=%imm_b %rs2 %rs1
 @s   ...   . . ... . ... imm=%imm_s %rs2 %rs1
 @u     . ... imm=%imm_u  
%rd
 @j     . ... imm=%imm_j  
%rd
 
+@sh  ..  .. .  ... . ... &shift  shamt=%sh10  %rs1 
%rd
+
 # *** RV32I Base Instruction Set ***
 lui     . 0110111 @u
 auipc   . 0010111 @u
@@ -57,3 +63,22 @@ lhu   . 101 . 011 @i
 sb   ...  .   . 000 . 0100011 @s
 sh   ...  .   . 001 . 0100011 @s
 sw   ...  .   . 010 . 0100011 @s
+addi  . 000 . 0010011 @i
+slti  . 010 . 0010011 @i
+sltiu . 011 . 0010011 @i
+xori  . 100 . 0010011 @i
+ori   . 110 . 0010011 @i
+andi  . 111 . 0010011 @i
+slli 00 ... 001 . 0010011 @sh
+srli 00 ... 101 . 0010011 @sh
+srai 01 ... 101 . 0010011 @sh
+add  000 .. 000 . 0110011 @r
+sub  010 .. 000 . 0110011 @r
+sll  000 .. 001 . 0110011 @r
+slt  000 .. 010 . 0110011 @r
+sltu 000 .. 011 . 0110011 @r
+xor  000 .. 100 . 0110011 @r
+srl  000 .. 101 . 0110011 @r
+sra  010 .. 101 . 0110011 @r
+or   000 .. 110 . 0110011 @r
+and  000 .. 111 . 0110011 @r
diff --git a/target/riscv/insn_trans/trans_rvi.inc.c 
b/target/riscv/insn_trans/trans_rvi.inc.c
index 61f708dba144..136fa54d0655 100644
--- a/target/riscv/insn_trans/trans_rvi.inc.c
+++ b/target/riscv/insn_trans/trans_rvi.inc.c
@@ -150,3 +150,171 @@ static bool trans_sd(DisasContext *ctx, arg_sd *a)
 return true;
 }
 #endif
+
+static bool trans_addi(DisasContext *ctx, arg_addi *a)
+{
+gen_arith_imm(ctx, OPC_RISC_ADDI, a->rd, a->rs1, a->imm);
+return true;
+}
+
+static bool trans_slti(DisasContext *ctx, arg_slti *a)
+{
+gen_arith_imm(ctx, OPC_RISC_SLTI, a->rd, a->rs1, a->imm);
+return true;
+}
+
+static bool trans_sltiu(DisasContext *ctx, arg_sltiu *a)
+{
+gen_arith_imm(ctx, OPC_RISC_SLTIU, a->rd, a->rs1, a->imm);
+return true;
+}
+
+static bool trans_xori(DisasContext *ctx, arg_xori *a)
+{
+gen_arith_imm(ctx, OPC_RISC_XORI, a->

[Qemu-devel] [PULL 01/29] target/riscv: Activate decodetree and implemnt LUI & AUIPC

2019-03-12 Thread Palmer Dabbelt
From: Bastian Koppelmann 

for now only LUI & AUIPC are decoded and translated. If decodetree fails, we
fall back to the old decoder.

Reviewed-by: Richard Henderson 
Acked-by: Alistair Francis 
Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 
Signed-off-by: Palmer Dabbelt 
---
 target/riscv/Makefile.objs  | 10 +++
 target/riscv/insn32.decode  | 30 +
 target/riscv/insn_trans/trans_rvi.inc.c | 35 +
 target/riscv/translate.c| 31 --
 4 files changed, 92 insertions(+), 14 deletions(-)
 create mode 100644 target/riscv/insn32.decode
 create mode 100644 target/riscv/insn_trans/trans_rvi.inc.c

diff --git a/target/riscv/Makefile.objs b/target/riscv/Makefile.objs
index 4072abe3e45c..bf0a268033a0 100644
--- a/target/riscv/Makefile.objs
+++ b/target/riscv/Makefile.objs
@@ -1 +1,11 @@
 obj-y += translate.o op_helper.o cpu_helper.o cpu.o csr.o fpu_helper.o 
gdbstub.o pmp.o
+
+DECODETREE = $(SRC_PATH)/scripts/decodetree.py
+
+target/riscv/decode_insn32.inc.c: \
+  $(SRC_PATH)/target/riscv/insn32.decode $(DECODETREE)
+   $(call quiet-command, \
+ $(PYTHON) $(DECODETREE) -o $@ --decode decode_insn32 $<, \
+ "GEN", $(TARGET_DIR)$@)
+
+target/riscv/translate.o: target/riscv/decode_insn32.inc.c
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
new file mode 100644
index ..44d4e922b6fa
--- /dev/null
+++ b/target/riscv/insn32.decode
@@ -0,0 +1,30 @@
+#
+# RISC-V translation routines for the RVXI Base Integer Instruction Set.
+#
+# Copyright (c) 2018 Peer Adelt, peer.ad...@hni.uni-paderborn.de
+#Bastian Koppelmann, kbast...@mail.uni-paderborn.de
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms and conditions of the GNU General Public License,
+# version 2 or later, as published by the Free Software Foundation.
+#
+# This program is distributed in the hope it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+# more details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# Fields:
+%rd7:5
+
+# immediates:
+%imm_u12:s20 !function=ex_shift_12
+
+# Formats 32:
+@u     . ... imm=%imm_u  
%rd
+
+# *** RV32I Base Instruction Set ***
+lui     . 0110111 @u
+auipc   . 0010111 @u
diff --git a/target/riscv/insn_trans/trans_rvi.inc.c 
b/target/riscv/insn_trans/trans_rvi.inc.c
new file mode 100644
index ..9885a8d27551
--- /dev/null
+++ b/target/riscv/insn_trans/trans_rvi.inc.c
@@ -0,0 +1,35 @@
+/*
+ * RISC-V translation routines for the RVXI Base Integer Instruction Set.
+ *
+ * Copyright (c) 2016-2017 Sagar Karandikar, sag...@eecs.berkeley.edu
+ * Copyright (c) 2018 Peer Adelt, peer.ad...@hni.uni-paderborn.de
+ *Bastian Koppelmann, kbast...@mail.uni-paderborn.de
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+static bool trans_lui(DisasContext *ctx, arg_lui *a)
+{
+if (a->rd != 0) {
+tcg_gen_movi_tl(cpu_gpr[a->rd], a->imm);
+}
+return true;
+}
+
+static bool trans_auipc(DisasContext *ctx, arg_auipc *a)
+{
+if (a->rd != 0) {
+tcg_gen_movi_tl(cpu_gpr[a->rd], a->imm + ctx->base.pc_next);
+}
+return true;
+}
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index b7176cbf98e1..a273ac827448 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -1874,6 +1874,19 @@ static void decode_RV32_64C(DisasContext *ctx)
 }
 }
 
+#define EX_SH(amount) \
+static int ex_shift_##amount(int imm) \
+{ \
+return imm << amount; \
+}
+EX_SH(12)
+
+bool decode_insn32(DisasContext *ctx, uint32_t insn);
+/* Include the auto-generated decoder for 32 bit insn */
+#include "decode_insn32.inc.c"
+/* Include insn module translation function */
+#include "insn_trans/trans_rvi.inc.c"
+
 static void decode_RV32_64G(DisasContext *ctx)
 {
 i

[Qemu-devel] [PULL 09/29] target/riscv: Convert RV32A insns to decodetree

2019-03-12 Thread Palmer Dabbelt
From: Bastian Koppelmann 

Acked-by: Alistair Francis 
Reviewed-by: Richard Henderson 
Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 
Signed-off-by: Palmer Dabbelt 
---
 target/riscv/insn32.decode  |  17 +++
 target/riscv/insn_trans/trans_rva.inc.c | 160 
 target/riscv/translate.c|   1 +
 3 files changed, 178 insertions(+)
 create mode 100644 target/riscv/insn_trans/trans_rva.inc.c

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index e53944bf0e40..00b9e2d9a508 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -34,6 +34,7 @@
 # Argument sets:
 &bimm rs2 rs1
 &shift shamt rs1 rd
+&atomicaq rl rs2 rs1 rd
 
 # Formats 32:
 @r   ...   . . ... . ...   %rs2 %rs1 
%rd
@@ -46,6 +47,9 @@
 @sh  ..  .. .  ... . ... &shift  shamt=%sh10  %rs1 
%rd
 @csr    .  ... . ...   %csr %rs1 
%rd
 
+@atom_ld . aq:1 rl:1 .  . ... &atomic rs2=0 %rs1 
%rd
+@atom_st . aq:1 rl:1 .  . ... &atomic %rs2  %rs1 
%rd
+
 # *** RV32I Base Instruction Set ***
 lui     . 0110111 @u
 auipc   . 0010111 @u
@@ -102,3 +106,16 @@ div  001 .  . 100 . 0110011 @r
 divu 001 .  . 101 . 0110011 @r
 rem  001 .  . 110 . 0110011 @r
 remu 001 .  . 111 . 0110011 @r
+
+# *** RV32A Standard Extension ***
+lr_w   00010 . . 0 . 010 . 010 @atom_ld
+sc_w   00011 . . . . 010 . 010 @atom_st
+amoswap_w  1 . . . . 010 . 010 @atom_st
+amoadd_w   0 . . . . 010 . 010 @atom_st
+amoxor_w   00100 . . . . 010 . 010 @atom_st
+amoand_w   01100 . . . . 010 . 010 @atom_st
+amoor_w01000 . . . . 010 . 010 @atom_st
+amomin_w   1 . . . . 010 . 010 @atom_st
+amomax_w   10100 . . . . 010 . 010 @atom_st
+amominu_w  11000 . . . . 010 . 010 @atom_st
+amomaxu_w  11100 . . . . 010 . 010 @atom_st
diff --git a/target/riscv/insn_trans/trans_rva.inc.c 
b/target/riscv/insn_trans/trans_rva.inc.c
new file mode 100644
index ..5d3c853ca504
--- /dev/null
+++ b/target/riscv/insn_trans/trans_rva.inc.c
@@ -0,0 +1,160 @@
+/*
+ * RISC-V translation routines for the RV64A Standard Extension.
+ *
+ * Copyright (c) 2016-2017 Sagar Karandikar, sag...@eecs.berkeley.edu
+ * Copyright (c) 2018 Peer Adelt, peer.ad...@hni.uni-paderborn.de
+ *Bastian Koppelmann, kbast...@mail.uni-paderborn.de
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+static inline bool gen_lr(DisasContext *ctx, arg_atomic *a, TCGMemOp mop)
+{
+TCGv src1 = tcg_temp_new();
+/* Put addr in load_res, data in load_val.  */
+gen_get_gpr(src1, a->rs1);
+if (a->rl) {
+tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
+}
+tcg_gen_qemu_ld_tl(load_val, src1, ctx->mem_idx, mop);
+if (a->aq) {
+tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
+}
+tcg_gen_mov_tl(load_res, src1);
+gen_set_gpr(a->rd, load_val);
+
+tcg_temp_free(src1);
+return true;
+}
+
+static inline bool gen_sc(DisasContext *ctx, arg_atomic *a, TCGMemOp mop)
+{
+TCGv src1 = tcg_temp_new();
+TCGv src2 = tcg_temp_new();
+TCGv dat = tcg_temp_new();
+TCGLabel *l1 = gen_new_label();
+TCGLabel *l2 = gen_new_label();
+
+gen_get_gpr(src1, a->rs1);
+tcg_gen_brcond_tl(TCG_COND_NE, load_res, src1, l1);
+
+gen_get_gpr(src2, a->rs2);
+/*
+ * Note that the TCG atomic primitives are SC,
+ * so we can ignore AQ/RL along this path.
+ */
+tcg_gen_atomic_cmpxchg_tl(src1, load_res, load_val, src2,
+  ctx->mem_idx, mop);
+tcg_gen_setcond_tl(TCG_COND_NE, dat, src1, load_val);
+gen_set_gpr(a->rd, dat);
+tcg_gen_br(l2);
+
+gen_set_label(l1);
+/*
+ * Address comparion failure.  However, we still need to
+ * provide the memory barrier implied by AQ/RL.
+ */
+tcg_gen_mb(TCG_MO_ALL + a->aq * TCG_BAR_LDAQ + a->rl * TCG_BAR_STRL);
+tcg_gen_movi_tl(dat, 1);
+gen_set_gp

[Qemu-devel] [PULL 03/29] target/riscv: Convert RV32I load/store insns to decodetree

2019-03-12 Thread Palmer Dabbelt
From: Bastian Koppelmann 

Acked-by: Alistair Francis 
Reviewed-by: Richard Henderson 
Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 
Signed-off-by: Palmer Dabbelt 
---
 target/riscv/insn32.decode  | 10 ++
 target/riscv/insn_trans/trans_rvi.inc.c | 48 +
 2 files changed, 58 insertions(+)

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 81f56c16b45f..076de873c4f1 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -23,6 +23,7 @@
 
 # immediates:
 %imm_i20:s12
+%imm_s25:s7 7:5
 %imm_b31:s1 7:1 25:6 8:4 !function=ex_shift_1
 %imm_j31:s1 12:8 20:1 21:10  !function=ex_shift_1
 %imm_u12:s20 !function=ex_shift_12
@@ -33,6 +34,7 @@
 # Formats 32:
 @i   . ... . ... imm=%imm_i %rs1 
%rd
 @b   ...   . . ... . ... &b  imm=%imm_b %rs2 %rs1
+@s   ...   . . ... . ... imm=%imm_s %rs2 %rs1
 @u     . ... imm=%imm_u  
%rd
 @j     . ... imm=%imm_j  
%rd
 
@@ -47,3 +49,11 @@ blt  ... .. 100 . 1100011 @b
 bge  ... .. 101 . 1100011 @b
 bltu ... .. 110 . 1100011 @b
 bgeu ... .. 111 . 1100011 @b
+lb    . 000 . 011 @i
+lh    . 001 . 011 @i
+lw    . 010 . 011 @i
+lbu   . 100 . 011 @i
+lhu   . 101 . 011 @i
+sb   ...  .   . 000 . 0100011 @s
+sh   ...  .   . 001 . 0100011 @s
+sw   ...  .   . 010 . 0100011 @s
diff --git a/target/riscv/insn_trans/trans_rvi.inc.c 
b/target/riscv/insn_trans/trans_rvi.inc.c
index bcf20def50eb..d13b7b2b6d8f 100644
--- a/target/riscv/insn_trans/trans_rvi.inc.c
+++ b/target/riscv/insn_trans/trans_rvi.inc.c
@@ -82,3 +82,51 @@ static bool trans_bgeu(DisasContext *ctx, arg_bgeu *a)
 gen_branch(ctx, OPC_RISC_BGEU, a->rs1, a->rs2, a->imm);
 return true;
 }
+
+static bool trans_lb(DisasContext *ctx, arg_lb *a)
+{
+gen_load(ctx, OPC_RISC_LB, a->rd, a->rs1, a->imm);
+return true;
+}
+
+static bool trans_lh(DisasContext *ctx, arg_lh *a)
+{
+gen_load(ctx, OPC_RISC_LH, a->rd, a->rs1, a->imm);
+return true;
+}
+
+static bool trans_lw(DisasContext *ctx, arg_lw *a)
+{
+gen_load(ctx, OPC_RISC_LW, a->rd, a->rs1, a->imm);
+return true;
+}
+
+static bool trans_lbu(DisasContext *ctx, arg_lbu *a)
+{
+gen_load(ctx, OPC_RISC_LBU, a->rd, a->rs1, a->imm);
+return true;
+}
+
+static bool trans_lhu(DisasContext *ctx, arg_lhu *a)
+{
+gen_load(ctx, OPC_RISC_LHU, a->rd, a->rs1, a->imm);
+return true;
+}
+
+static bool trans_sb(DisasContext *ctx, arg_sb *a)
+{
+gen_store(ctx, OPC_RISC_SB, a->rs1, a->rs2, a->imm);
+return true;
+}
+
+static bool trans_sh(DisasContext *ctx, arg_sh *a)
+{
+gen_store(ctx, OPC_RISC_SH, a->rs1, a->rs2, a->imm);
+return true;
+}
+
+static bool trans_sw(DisasContext *ctx, arg_sw *a)
+{
+gen_store(ctx, OPC_RISC_SW, a->rs1, a->rs2, a->imm);
+return true;
+}
-- 
2.19.2




[Qemu-devel] [PULL 02/29] target/riscv: Convert RVXI branch insns to decodetree

2019-03-12 Thread Palmer Dabbelt
From: Bastian Koppelmann 

Acked-by: Alistair Francis 
Reviewed-by: Palmer Dabbelt 
Reviewed-by: Richard Henderson 
Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 
Signed-off-by: Palmer Dabbelt 
---
 target/riscv/insn32.decode  | 19 ++
 target/riscv/insn_trans/trans_rvi.inc.c | 49 +
 target/riscv/translate.c| 12 +-
 3 files changed, 69 insertions(+), 11 deletions(-)

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 44d4e922b6fa..81f56c16b45f 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -17,14 +17,33 @@
 # this program.  If not, see <http://www.gnu.org/licenses/>.
 
 # Fields:
+%rs2   20:5
+%rs1   15:5
 %rd7:5
 
 # immediates:
+%imm_i20:s12
+%imm_b31:s1 7:1 25:6 8:4 !function=ex_shift_1
+%imm_j31:s1 12:8 20:1 21:10  !function=ex_shift_1
 %imm_u12:s20 !function=ex_shift_12
 
+# Argument sets:
+&bimm rs2 rs1
+
 # Formats 32:
+@i   . ... . ... imm=%imm_i %rs1 
%rd
+@b   ...   . . ... . ... &b  imm=%imm_b %rs2 %rs1
 @u     . ... imm=%imm_u  
%rd
+@j     . ... imm=%imm_j  
%rd
 
 # *** RV32I Base Instruction Set ***
 lui     . 0110111 @u
 auipc   . 0010111 @u
+jal     . 110 @j
+jalr  . 000 . 1100111 @i
+beq  ... .. 000 . 1100011 @b
+bne  ... .. 001 . 1100011 @b
+blt  ... .. 100 . 1100011 @b
+bge  ... .. 101 . 1100011 @b
+bltu ... .. 110 . 1100011 @b
+bgeu ... .. 111 . 1100011 @b
diff --git a/target/riscv/insn_trans/trans_rvi.inc.c 
b/target/riscv/insn_trans/trans_rvi.inc.c
index 9885a8d27551..bcf20def50eb 100644
--- a/target/riscv/insn_trans/trans_rvi.inc.c
+++ b/target/riscv/insn_trans/trans_rvi.inc.c
@@ -33,3 +33,52 @@ static bool trans_auipc(DisasContext *ctx, arg_auipc *a)
 }
 return true;
 }
+
+static bool trans_jal(DisasContext *ctx, arg_jal *a)
+{
+gen_jal(ctx, a->rd, a->imm);
+return true;
+}
+
+static bool trans_jalr(DisasContext *ctx, arg_jalr *a)
+{
+gen_jalr(ctx, OPC_RISC_JALR, a->rd, a->rs1, a->imm);
+return true;
+}
+
+static bool trans_beq(DisasContext *ctx, arg_beq *a)
+{
+gen_branch(ctx, OPC_RISC_BEQ, a->rs1, a->rs2, a->imm);
+return true;
+}
+
+static bool trans_bne(DisasContext *ctx, arg_bne *a)
+{
+gen_branch(ctx, OPC_RISC_BNE, a->rs1, a->rs2, a->imm);
+return true;
+}
+
+static bool trans_blt(DisasContext *ctx, arg_blt *a)
+{
+gen_branch(ctx, OPC_RISC_BLT, a->rs1, a->rs2, a->imm);
+return true;
+}
+
+static bool trans_bge(DisasContext *ctx, arg_bge *a)
+{
+gen_branch(ctx, OPC_RISC_BGE, a->rs1, a->rs2, a->imm);
+return true;
+}
+
+static bool trans_bltu(DisasContext *ctx, arg_bltu *a)
+{
+gen_branch(ctx, OPC_RISC_BLTU, a->rs1, a->rs2, a->imm);
+return true;
+}
+
+static bool trans_bgeu(DisasContext *ctx, arg_bgeu *a)
+{
+
+gen_branch(ctx, OPC_RISC_BGEU, a->rs1, a->rs2, a->imm);
+return true;
+}
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index a273ac827448..fb284a5e08d6 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -1879,6 +1879,7 @@ static void decode_RV32_64C(DisasContext *ctx)
 { \
 return imm << amount; \
 }
+EX_SH(1)
 EX_SH(12)
 
 bool decode_insn32(DisasContext *ctx, uint32_t insn);
@@ -1907,17 +1908,6 @@ static void decode_RV32_64G(DisasContext *ctx)
 imm = GET_IMM(ctx->opcode);
 
 switch (op) {
-case OPC_RISC_JAL:
-imm = GET_JAL_IMM(ctx->opcode);
-gen_jal(ctx, rd, imm);
-break;
-case OPC_RISC_JALR:
-gen_jalr(ctx, MASK_OP_JALR(ctx->opcode), rd, rs1, imm);
-break;
-case OPC_RISC_BRANCH:
-gen_branch(ctx, MASK_OP_BRANCH(ctx->opcode), rs1, rs2,
-   GET_B_IMM(ctx->opcode));
-break;
 case OPC_RISC_LOAD:
 gen_load(ctx, MASK_OP_LOAD(ctx->opcode), rd, rs1, imm);
 break;
-- 
2.19.2




Re: [Qemu-devel] Maintainers, please tell us how to boot your machines!

2019-03-13 Thread Palmer Dabbelt

On Tue, 12 Mar 2019 10:36:05 PDT (-0700), arm...@redhat.com wrote:

Machines with no maintainer, but at least one supporter:
[...]
= hw/riscv/sifive_e.c =
Palmer Dabbelt  (supporter:RISC-V)
Alistair Francis  (supporter:RISC-V)
Sagar Karandikar  (supporter:RISC-V)
Bastian Koppelmann  (supporter:RISC-V)
qemu-ri...@nongnu.org (open list:RISC-V)

= hw/riscv/sifive_u.c =
Palmer Dabbelt  (supporter:RISC-V)
Alistair Francis  (supporter:RISC-V)
Sagar Karandikar  (supporter:RISC-V)
Bastian Koppelmann  (supporter:RISC-V)
qemu-ri...@nongnu.org (open list:RISC-V)

= hw/riscv/spike.c =
Palmer Dabbelt  (supporter:RISC-V)
Alistair Francis  (supporter:RISC-V)
Sagar Karandikar  (supporter:RISC-V)
Bastian Koppelmann  (supporter:RISC-V)
qemu-ri...@nongnu.org (open list:RISC-V)

= hw/riscv/virt.c =
Palmer Dabbelt  (supporter:RISC-V)
Alistair Francis  (supporter:RISC-V)
Sagar Karandikar  (supporter:RISC-V)
Bastian Koppelmann  (supporter:RISC-V)
qemu-ri...@nongnu.org (open list:RISC-V)


Is "maintainer" a higher level of support than "supporter"?  If that's the case 
then I'm happy signing up to be a maintainer of these, as part of by job at 
SiFive is to make sure these work.  Sorry, I'm not entirely sure how this all 
works -- from reading the top of the MAINTAINERS file it appears that 
"supported" is a higher level of support than "maintained".




[Qemu-devel] [PULL 23/29] target/riscv: Move gen_arith_imm() decoding into trans_* functions

2019-03-13 Thread Palmer Dabbelt
From: Bastian Koppelmann 

gen_arith_imm() does a lot of decoding manually, which was hard to read
in case of the shift instructions and is not necessary anymore with
decodetree.

Reviewed-by: Richard Henderson 
Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 
---
 target/riscv/insn32.decode  |   3 +-
 target/riscv/insn_trans/trans_rvi.inc.c |  98 +-
 target/riscv/translate.c| 107 ++--
 3 files changed, 108 insertions(+), 100 deletions(-)

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index ecc46a50cc27..d6b4197841f5 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -35,12 +35,13 @@
 
 # Argument sets:
 &bimm rs2 rs1
+&iimm rs1 rd
 &shift shamt rs1 rd
 &atomicaq rl rs2 rs1 rd
 
 # Formats 32:
 @r   ...   . . ... . ...   %rs2 %rs1 
%rd
-@i   . ... . ... imm=%imm_i %rs1 
%rd
+@i   . ... . ... &i  imm=%imm_i %rs1 
%rd
 @b   ...   . . ... . ... &b  imm=%imm_b %rs2 %rs1
 @s   ...   . . ... . ... imm=%imm_s %rs2 %rs1
 @u     . ... imm=%imm_u  
%rd
diff --git a/target/riscv/insn_trans/trans_rvi.inc.c 
b/target/riscv/insn_trans/trans_rvi.inc.c
index 5a09c6335ae0..0265740bdb69 100644
--- a/target/riscv/insn_trans/trans_rvi.inc.c
+++ b/target/riscv/insn_trans/trans_rvi.inc.c
@@ -217,52 +217,96 @@ static bool trans_sd(DisasContext *ctx, arg_sd *a)
 
 static bool trans_addi(DisasContext *ctx, arg_addi *a)
 {
-gen_arith_imm(ctx, OPC_RISC_ADDI, a->rd, a->rs1, a->imm);
-return true;
+return gen_arith_imm(ctx, a, &tcg_gen_add_tl);
 }
 
 static bool trans_slti(DisasContext *ctx, arg_slti *a)
 {
-gen_arith_imm(ctx, OPC_RISC_SLTI, a->rd, a->rs1, a->imm);
+TCGv source1;
+source1 = tcg_temp_new();
+gen_get_gpr(source1, a->rs1);
+
+tcg_gen_setcondi_tl(TCG_COND_LT, source1, source1, a->imm);
+
+gen_set_gpr(a->rd, source1);
+tcg_temp_free(source1);
 return true;
 }
 
 static bool trans_sltiu(DisasContext *ctx, arg_sltiu *a)
 {
-gen_arith_imm(ctx, OPC_RISC_SLTIU, a->rd, a->rs1, a->imm);
+TCGv source1;
+source1 = tcg_temp_new();
+gen_get_gpr(source1, a->rs1);
+
+tcg_gen_setcondi_tl(TCG_COND_LTU, source1, source1, a->imm);
+
+gen_set_gpr(a->rd, source1);
+tcg_temp_free(source1);
 return true;
 }
 
 static bool trans_xori(DisasContext *ctx, arg_xori *a)
 {
-gen_arith_imm(ctx, OPC_RISC_XORI, a->rd, a->rs1, a->imm);
-return true;
+return gen_arith_imm(ctx, a, &tcg_gen_xor_tl);
 }
 static bool trans_ori(DisasContext *ctx, arg_ori *a)
 {
-gen_arith_imm(ctx, OPC_RISC_ORI, a->rd, a->rs1, a->imm);
-return true;
+return gen_arith_imm(ctx, a, &tcg_gen_or_tl);
 }
 static bool trans_andi(DisasContext *ctx, arg_andi *a)
 {
-gen_arith_imm(ctx, OPC_RISC_ANDI, a->rd, a->rs1, a->imm);
-return true;
+return gen_arith_imm(ctx, a, &tcg_gen_and_tl);
 }
 static bool trans_slli(DisasContext *ctx, arg_slli *a)
 {
-gen_arith_imm(ctx, OPC_RISC_SLLI, a->rd, a->rs1, a->shamt);
+if (a->shamt >= TARGET_LONG_BITS) {
+return false;
+}
+
+if (a->rd != 0) {
+TCGv t = tcg_temp_new();
+gen_get_gpr(t, a->rs1);
+
+tcg_gen_shli_tl(t, t, a->shamt);
+
+gen_set_gpr(a->rd, t);
+tcg_temp_free(t);
+} /* NOP otherwise */
 return true;
 }
 
 static bool trans_srli(DisasContext *ctx, arg_srli *a)
 {
-gen_arith_imm(ctx, OPC_RISC_SHIFT_RIGHT_I, a->rd, a->rs1, a->shamt);
+if (a->shamt >= TARGET_LONG_BITS) {
+return false;
+}
+
+if (a->rd != 0) {
+TCGv t = tcg_temp_new();
+gen_get_gpr(t, a->rs1);
+
+tcg_gen_shri_tl(t, t, a->shamt);
+gen_set_gpr(a->rd, t);
+tcg_temp_free(t);
+} /* NOP otherwise */
 return true;
 }
 
 static bool trans_srai(DisasContext *ctx, arg_srai *a)
 {
-gen_arith_imm(ctx, OPC_RISC_SHIFT_RIGHT_I, a->rd, a->rs1, a->shamt | 
0x400);
+if (a->shamt >= TARGET_LONG_BITS) {
+return false;
+}
+
+if (a->rd != 0) {
+TCGv t = tcg_temp_new();
+gen_get_gpr(t, a->rs1);
+
+tcg_gen_sari_tl(t, t, a->shamt);
+gen_set_gpr(a->rd, t);
+tcg_temp_free(t);
+} /* NOP otherwise */
 return true;
 }
 
@@ -329,26 +373,42 @@ static bool trans_and(DisasContext *ctx, arg_and *a)
 #ifdef TARGET_RISCV64
 static bool trans_addiw(DisasContext *ctx, arg_addiw *a)
 {
-gen_arith_imm(ctx, OPC_RISC_ADDIW, a->rd, a->rs1, a->imm);
-return true;
+return gen_arith_imm(ctx, a, &gen_addw);
 }
 
 static bool trans_slliw(DisasContext *ctx, arg_slliw *a)
 {
-gen_arith_imm(ctx, OPC_RISC_SLLIW, a->rd, a->rs1, a->shamt);
+TCGv source1;
+source1 = tcg_temp_new();
+gen_get_gpr(source1, a->rs1);

[Qemu-devel] [PULL 29/29] target/riscv: Remove decode_RV32_64G()

2019-03-13 Thread Palmer Dabbelt
From: Bastian Koppelmann 

decodetree handles all instructions now so the fallback is not necessary
anymore.

Reviewed-by: Richard Henderson 
Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 
---
 target/riscv/translate.c | 21 +
 1 file changed, 1 insertion(+), 20 deletions(-)

diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 92be090bc7bb..049fa65c6611 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -651,24 +651,6 @@ bool decode_insn16(DisasContext *ctx, uint16_t insn);
 #include "decode_insn16.inc.c"
 #include "insn_trans/trans_rvc.inc.c"
 
-static void decode_RV32_64G(DisasContext *ctx)
-{
-uint32_t op;
-
-/* We do not do misaligned address check here: the address should never be
- * misaligned at this point. Instructions that set PC must do the check,
- * since epc must be the address of the instruction that caused us to
- * perform the misaligned instruction fetch */
-
-op = MASK_OP_MAJOR(ctx->opcode);
-
-switch (op) {
-default:
-gen_exception_illegal(ctx);
-break;
-}
-}
-
 static void decode_opc(DisasContext *ctx)
 {
 /* check for compressed insn */
@@ -685,8 +667,7 @@ static void decode_opc(DisasContext *ctx)
 } else {
 ctx->pc_succ_insn = ctx->base.pc_next + 4;
 if (!decode_insn32(ctx, ctx->opcode)) {
-/* fallback to old decoder */
-decode_RV32_64G(ctx);
+gen_exception_illegal(ctx);
 }
 }
 }
-- 
2.19.2




[Qemu-devel] [PULL 24/29] target/riscv: make ADD/SUB/OR/XOR/AND insn use arg lists

2019-03-13 Thread Palmer Dabbelt
From: Bastian Koppelmann 

manual decoding in gen_arith() is not necessary with decodetree. For now
the function is called trans_arith as the original gen_arith still
exists. The former will be renamed to gen_arith as soon as the old
gen_arith can be removed.

Reviewed-by: Richard Henderson 
Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 
---
 target/riscv/insn32.decode  |  3 +-
 target/riscv/insn_trans/trans_rvi.inc.c | 21 +
 target/riscv/translate.c| 40 +++--
 3 files changed, 34 insertions(+), 30 deletions(-)

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index d6b4197841f5..6f3ab7aa52d3 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -36,11 +36,12 @@
 # Argument sets:
 &bimm rs2 rs1
 &iimm rs1 rd
+&rrd rs1 rs2
 &shift shamt rs1 rd
 &atomicaq rl rs2 rs1 rd
 
 # Formats 32:
-@r   ...   . . ... . ...   %rs2 %rs1 
%rd
+@r   ...   . . ... . ... &r%rs2 %rs1 
%rd
 @i   . ... . ... &i  imm=%imm_i %rs1 
%rd
 @b   ...   . . ... . ... &b  imm=%imm_b %rs2 %rs1
 @s   ...   . . ... . ... imm=%imm_s %rs2 %rs1
diff --git a/target/riscv/insn_trans/trans_rvi.inc.c 
b/target/riscv/insn_trans/trans_rvi.inc.c
index 0265740bdb69..8879f2da35c7 100644
--- a/target/riscv/insn_trans/trans_rvi.inc.c
+++ b/target/riscv/insn_trans/trans_rvi.inc.c
@@ -312,14 +312,12 @@ static bool trans_srai(DisasContext *ctx, arg_srai *a)
 
 static bool trans_add(DisasContext *ctx, arg_add *a)
 {
-gen_arith(ctx, OPC_RISC_ADD, a->rd, a->rs1, a->rs2);
-return true;
+return trans_arith(ctx, a, &tcg_gen_add_tl);
 }
 
 static bool trans_sub(DisasContext *ctx, arg_sub *a)
 {
-gen_arith(ctx, OPC_RISC_SUB, a->rd, a->rs1, a->rs2);
-return true;
+return trans_arith(ctx, a, &tcg_gen_sub_tl);
 }
 
 static bool trans_sll(DisasContext *ctx, arg_sll *a)
@@ -342,8 +340,7 @@ static bool trans_sltu(DisasContext *ctx, arg_sltu *a)
 
 static bool trans_xor(DisasContext *ctx, arg_xor *a)
 {
-gen_arith(ctx, OPC_RISC_XOR, a->rd, a->rs1, a->rs2);
-return true;
+return trans_arith(ctx, a, &tcg_gen_xor_tl);
 }
 
 static bool trans_srl(DisasContext *ctx, arg_srl *a)
@@ -360,14 +357,12 @@ static bool trans_sra(DisasContext *ctx, arg_sra *a)
 
 static bool trans_or(DisasContext *ctx, arg_or *a)
 {
-gen_arith(ctx, OPC_RISC_OR, a->rd, a->rs1, a->rs2);
-return true;
+return trans_arith(ctx, a, &tcg_gen_or_tl);
 }
 
 static bool trans_and(DisasContext *ctx, arg_and *a)
 {
-gen_arith(ctx, OPC_RISC_AND, a->rd, a->rs1, a->rs2);
-return true;
+return trans_arith(ctx, a, &tcg_gen_and_tl);
 }
 
 #ifdef TARGET_RISCV64
@@ -414,14 +409,12 @@ static bool trans_sraiw(DisasContext *ctx, arg_sraiw *a)
 
 static bool trans_addw(DisasContext *ctx, arg_addw *a)
 {
-gen_arith(ctx, OPC_RISC_ADDW, a->rd, a->rs1, a->rs2);
-return true;
+return trans_arith(ctx, a, &gen_addw);
 }
 
 static bool trans_subw(DisasContext *ctx, arg_subw *a)
 {
-gen_arith(ctx, OPC_RISC_SUBW, a->rd, a->rs1, a->rs2);
-return true;
+return trans_arith(ctx, a, &gen_subw);
 }
 
 static bool trans_sllw(DisasContext *ctx, arg_sllw *a)
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 0157758a160a..8eb883463322 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -198,12 +198,6 @@ static void gen_arith(DisasContext *ctx, uint32_t opc, int 
rd, int rs1,
 gen_get_gpr(source2, rs2);
 
 switch (opc) {
-CASE_OP_32_64(OPC_RISC_ADD):
-tcg_gen_add_tl(source1, source1, source2);
-break;
-CASE_OP_32_64(OPC_RISC_SUB):
-tcg_gen_sub_tl(source1, source1, source2);
-break;
 #if defined(TARGET_RISCV64)
 case OPC_RISC_SLLW:
 tcg_gen_andi_tl(source2, source2, 0x1F);
@@ -220,9 +214,6 @@ static void gen_arith(DisasContext *ctx, uint32_t opc, int 
rd, int rs1,
 case OPC_RISC_SLTU:
 tcg_gen_setcond_tl(TCG_COND_LTU, source1, source1, source2);
 break;
-case OPC_RISC_XOR:
-tcg_gen_xor_tl(source1, source1, source2);
-break;
 #if defined(TARGET_RISCV64)
 case OPC_RISC_SRLW:
 /* clear upper 32 */
@@ -248,12 +239,6 @@ static void gen_arith(DisasContext *ctx, uint32_t opc, int 
rd, int rs1,
 tcg_gen_andi_tl(source2, source2, TARGET_LONG_BITS - 1);
 tcg_gen_sar_tl(source1, source1, source2);
 break;
-case OPC_RISC_OR:
-tcg_gen_or_tl(source1, source1, source2);
-break;
-case OPC_RISC_AND:
-tcg_gen_and_tl(source1, source1, source2);
-break;
 CASE_OP_32_64(OPC_RISC_MUL):
 if (!has_ext(ctx, RVM)) {
 goto do_illegal;
@@ -730,8 +715,33 @@ static void gen_addw(TCGv ret, TCGv arg1, TCGv arg2)
 tcg_gen_add_tl(ret, arg1, arg2);
 

[Qemu-devel] [PULL 22/29] target/riscv: Remove manual decoding from gen_store()

2019-03-13 Thread Palmer Dabbelt
From: Bastian Koppelmann 

With decodetree we don't need to convert RISC-V opcodes into to MemOps
as the old gen_store() did.

Reviewed-by: Richard Henderson 
Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 
---
 target/riscv/insn_trans/trans_rvi.inc.c | 27 +
 target/riscv/translate.c|  8 +---
 2 files changed, 24 insertions(+), 11 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvi.inc.c 
b/target/riscv/insn_trans/trans_rvi.inc.c
index cc361ed4d151..5a09c6335ae0 100644
--- a/target/riscv/insn_trans/trans_rvi.inc.c
+++ b/target/riscv/insn_trans/trans_rvi.inc.c
@@ -168,22 +168,34 @@ static bool trans_lhu(DisasContext *ctx, arg_lhu *a)
 return gen_load(ctx, a, MO_TEUW);
 }
 
-static bool trans_sb(DisasContext *ctx, arg_sb *a)
+static bool gen_store(DisasContext *ctx, arg_sb *a, TCGMemOp memop)
 {
-gen_store(ctx, OPC_RISC_SB, a->rs1, a->rs2, a->imm);
+TCGv t0 = tcg_temp_new();
+TCGv dat = tcg_temp_new();
+gen_get_gpr(t0, a->rs1);
+tcg_gen_addi_tl(t0, t0, a->imm);
+gen_get_gpr(dat, a->rs2);
+
+tcg_gen_qemu_st_tl(dat, t0, ctx->mem_idx, memop);
+tcg_temp_free(t0);
+tcg_temp_free(dat);
 return true;
 }
 
+
+static bool trans_sb(DisasContext *ctx, arg_sb *a)
+{
+return gen_store(ctx, a, MO_SB);
+}
+
 static bool trans_sh(DisasContext *ctx, arg_sh *a)
 {
-gen_store(ctx, OPC_RISC_SH, a->rs1, a->rs2, a->imm);
-return true;
+return gen_store(ctx, a, MO_TESW);
 }
 
 static bool trans_sw(DisasContext *ctx, arg_sw *a)
 {
-gen_store(ctx, OPC_RISC_SW, a->rs1, a->rs2, a->imm);
-return true;
+return gen_store(ctx, a, MO_TESL);
 }
 
 #ifdef TARGET_RISCV64
@@ -199,8 +211,7 @@ static bool trans_ld(DisasContext *ctx, arg_ld *a)
 
 static bool trans_sd(DisasContext *ctx, arg_sd *a)
 {
-gen_store(ctx, OPC_RISC_SD, a->rs1, a->rs2, a->imm);
-return true;
+return gen_store(ctx, a, MO_TEQ);
 }
 #endif
 
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 99d6d3b4ae91..cdc08b1bff20 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -56,6 +56,7 @@ typedef struct DisasContext {
 int frm;
 } DisasContext;
 
+#ifdef TARGET_RISCV64
 /* convert riscv funct3 to qemu memop for load/store */
 static const int tcg_memop_lookup[8] = {
 [0 ... 7] = -1,
@@ -69,6 +70,7 @@ static const int tcg_memop_lookup[8] = {
 [6] = MO_TEUL,
 #endif
 };
+#endif
 
 #ifdef TARGET_RISCV64
 #define CASE_OP_32_64(X) case X: case glue(X, W)
@@ -551,9 +553,8 @@ static void gen_load_c(DisasContext *ctx, uint32_t opc, int 
rd, int rs1,
 tcg_temp_free(t0);
 tcg_temp_free(t1);
 }
-#endif
 
-static void gen_store(DisasContext *ctx, uint32_t opc, int rs1, int rs2,
+static void gen_store_c(DisasContext *ctx, uint32_t opc, int rs1, int rs2,
 target_long imm)
 {
 TCGv t0 = tcg_temp_new();
@@ -572,6 +573,7 @@ static void gen_store(DisasContext *ctx, uint32_t opc, int 
rs1, int rs2,
 tcg_temp_free(t0);
 tcg_temp_free(dat);
 }
+#endif
 
 #ifndef CONFIG_USER_ONLY
 /* The states of mstatus_fs are:
@@ -736,7 +738,7 @@ static void decode_RV32_64C0(DisasContext *ctx)
 case 7:
 #if defined(TARGET_RISCV64)
 /* C.SD (RV64/128) -> sd rs2', offset[7:3](rs1')*/
-gen_store(ctx, OPC_RISC_SD, rs1s, rd_rs2,
+gen_store_c(ctx, OPC_RISC_SD, rs1s, rd_rs2,
   GET_C_LD_IMM(ctx->opcode));
 #else
 /* C.FSW (RV32) -> fsw rs2', offset[6:2](rs1')*/
-- 
2.19.2




[Qemu-devel] [PULL 20/29] target/riscv: Remove manual decoding from gen_branch()

2019-03-13 Thread Palmer Dabbelt
From: Bastian Koppelmann 

We now utilizes argument-sets of decodetree such that no manual
decoding is necessary.

Reviewed-by: Richard Henderson 
Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 
---
 target/riscv/insn_trans/trans_rvi.inc.c | 46 +---
 target/riscv/translate.c| 47 -
 2 files changed, 33 insertions(+), 60 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvi.inc.c 
b/target/riscv/insn_trans/trans_rvi.inc.c
index 631a88906bce..ae4b0a2bcb78 100644
--- a/target/riscv/insn_trans/trans_rvi.inc.c
+++ b/target/riscv/insn_trans/trans_rvi.inc.c
@@ -72,41 +72,61 @@ static bool trans_jalr(DisasContext *ctx, arg_jalr *a)
 return true;
 }
 
-static bool trans_beq(DisasContext *ctx, arg_beq *a)
+static bool gen_branch(DisasContext *ctx, arg_b *a, TCGCond cond)
 {
-gen_branch(ctx, OPC_RISC_BEQ, a->rs1, a->rs2, a->imm);
+TCGLabel *l = gen_new_label();
+TCGv source1, source2;
+source1 = tcg_temp_new();
+source2 = tcg_temp_new();
+gen_get_gpr(source1, a->rs1);
+gen_get_gpr(source2, a->rs2);
+
+tcg_gen_brcond_tl(cond, source1, source2, l);
+gen_goto_tb(ctx, 1, ctx->pc_succ_insn);
+gen_set_label(l); /* branch taken */
+
+if (!has_ext(ctx, RVC) && ((ctx->base.pc_next + a->imm) & 0x3)) {
+/* misaligned */
+gen_exception_inst_addr_mis(ctx);
+} else {
+gen_goto_tb(ctx, 0, ctx->base.pc_next + a->imm);
+}
+ctx->base.is_jmp = DISAS_NORETURN;
+
+tcg_temp_free(source1);
+tcg_temp_free(source2);
+
 return true;
 }
 
+static bool trans_beq(DisasContext *ctx, arg_beq *a)
+{
+return gen_branch(ctx, a, TCG_COND_EQ);
+}
+
 static bool trans_bne(DisasContext *ctx, arg_bne *a)
 {
-gen_branch(ctx, OPC_RISC_BNE, a->rs1, a->rs2, a->imm);
-return true;
+return gen_branch(ctx, a, TCG_COND_NE);
 }
 
 static bool trans_blt(DisasContext *ctx, arg_blt *a)
 {
-gen_branch(ctx, OPC_RISC_BLT, a->rs1, a->rs2, a->imm);
-return true;
+return gen_branch(ctx, a, TCG_COND_LT);
 }
 
 static bool trans_bge(DisasContext *ctx, arg_bge *a)
 {
-gen_branch(ctx, OPC_RISC_BGE, a->rs1, a->rs2, a->imm);
-return true;
+return gen_branch(ctx, a, TCG_COND_GE);
 }
 
 static bool trans_bltu(DisasContext *ctx, arg_bltu *a)
 {
-gen_branch(ctx, OPC_RISC_BLTU, a->rs1, a->rs2, a->imm);
-return true;
+return gen_branch(ctx, a, TCG_COND_LTU);
 }
 
 static bool trans_bgeu(DisasContext *ctx, arg_bgeu *a)
 {
-
-gen_branch(ctx, OPC_RISC_BGEU, a->rs1, a->rs2, a->imm);
-return true;
+return gen_branch(ctx, a, TCG_COND_GEU);
 }
 
 static bool trans_lb(DisasContext *ctx, arg_lb *a)
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 9dee2ec24287..a3d5cdbad82d 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -531,53 +531,6 @@ static void gen_jal(DisasContext *ctx, int rd, 
target_ulong imm)
 ctx->base.is_jmp = DISAS_NORETURN;
 }
 
-static void gen_branch(DisasContext *ctx, uint32_t opc, int rs1, int rs2,
-   target_long bimm)
-{
-TCGLabel *l = gen_new_label();
-TCGv source1, source2;
-source1 = tcg_temp_new();
-source2 = tcg_temp_new();
-gen_get_gpr(source1, rs1);
-gen_get_gpr(source2, rs2);
-
-switch (opc) {
-case OPC_RISC_BEQ:
-tcg_gen_brcond_tl(TCG_COND_EQ, source1, source2, l);
-break;
-case OPC_RISC_BNE:
-tcg_gen_brcond_tl(TCG_COND_NE, source1, source2, l);
-break;
-case OPC_RISC_BLT:
-tcg_gen_brcond_tl(TCG_COND_LT, source1, source2, l);
-break;
-case OPC_RISC_BGE:
-tcg_gen_brcond_tl(TCG_COND_GE, source1, source2, l);
-break;
-case OPC_RISC_BLTU:
-tcg_gen_brcond_tl(TCG_COND_LTU, source1, source2, l);
-break;
-case OPC_RISC_BGEU:
-tcg_gen_brcond_tl(TCG_COND_GEU, source1, source2, l);
-break;
-default:
-gen_exception_illegal(ctx);
-return;
-}
-tcg_temp_free(source1);
-tcg_temp_free(source2);
-
-gen_goto_tb(ctx, 1, ctx->pc_succ_insn);
-gen_set_label(l); /* branch taken */
-if (!has_ext(ctx, RVC) && ((ctx->base.pc_next + bimm) & 0x3)) {
-/* misaligned */
-gen_exception_inst_addr_mis(ctx);
-} else {
-gen_goto_tb(ctx, 0, ctx->base.pc_next + bimm);
-}
-ctx->base.is_jmp = DISAS_NORETURN;
-}
-
 static void gen_load(DisasContext *ctx, uint32_t opc, int rd, int rs1,
 target_long imm)
 {
-- 
2.19.2




[Qemu-devel] [PULL 26/29] target/riscv: Remove manual decoding of RV32/64M insn

2019-03-13 Thread Palmer Dabbelt
From: Bastian Koppelmann 

Reviewed-by: Richard Henderson 
Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 
---
 target/riscv/insn_trans/trans_rvm.inc.c |  55 ++--
 target/riscv/translate.c| 320 ++--
 2 files changed, 164 insertions(+), 211 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvm.inc.c 
b/target/riscv/insn_trans/trans_rvm.inc.c
index 69631c9e3783..d2bf2f171904 100644
--- a/target/riscv/insn_trans/trans_rvm.inc.c
+++ b/target/riscv/insn_trans/trans_rvm.inc.c
@@ -22,92 +22,99 @@
 static bool trans_mul(DisasContext *ctx, arg_mul *a)
 {
 REQUIRE_EXT(ctx, RVM);
-gen_arith(ctx, OPC_RISC_MUL, a->rd, a->rs1, a->rs2);
-return true;
+return trans_arith(ctx, a, &tcg_gen_mul_tl);
 }
 
 static bool trans_mulh(DisasContext *ctx, arg_mulh *a)
 {
 REQUIRE_EXT(ctx, RVM);
-gen_arith(ctx, OPC_RISC_MULH, a->rd, a->rs1, a->rs2);
+TCGv source1 = tcg_temp_new();
+TCGv source2 = tcg_temp_new();
+gen_get_gpr(source1, a->rs1);
+gen_get_gpr(source2, a->rs2);
+
+tcg_gen_muls2_tl(source2, source1, source1, source2);
+
+gen_set_gpr(a->rd, source1);
+tcg_temp_free(source1);
+tcg_temp_free(source2);
 return true;
 }
 
 static bool trans_mulhsu(DisasContext *ctx, arg_mulhsu *a)
 {
 REQUIRE_EXT(ctx, RVM);
-gen_arith(ctx, OPC_RISC_MULHSU, a->rd, a->rs1, a->rs2);
-return true;
+return trans_arith(ctx, a, &gen_mulhsu);
 }
 
 static bool trans_mulhu(DisasContext *ctx, arg_mulhu *a)
 {
 REQUIRE_EXT(ctx, RVM);
-gen_arith(ctx, OPC_RISC_MULHU, a->rd, a->rs1, a->rs2);
+TCGv source1 = tcg_temp_new();
+TCGv source2 = tcg_temp_new();
+gen_get_gpr(source1, a->rs1);
+gen_get_gpr(source2, a->rs2);
+
+tcg_gen_mulu2_tl(source2, source1, source1, source2);
+
+gen_set_gpr(a->rd, source1);
+tcg_temp_free(source1);
+tcg_temp_free(source2);
 return true;
 }
 
 static bool trans_div(DisasContext *ctx, arg_div *a)
 {
 REQUIRE_EXT(ctx, RVM);
-gen_arith(ctx, OPC_RISC_DIV, a->rd, a->rs1, a->rs2);
-return true;
+return trans_arith(ctx, a, &gen_div);
 }
 
 static bool trans_divu(DisasContext *ctx, arg_divu *a)
 {
 REQUIRE_EXT(ctx, RVM);
-gen_arith(ctx, OPC_RISC_DIVU, a->rd, a->rs1, a->rs2);
-return true;
+return trans_arith(ctx, a, &gen_divu);
 }
 
 static bool trans_rem(DisasContext *ctx, arg_rem *a)
 {
 REQUIRE_EXT(ctx, RVM);
-gen_arith(ctx, OPC_RISC_REM, a->rd, a->rs1, a->rs2);
-return true;
+return trans_arith(ctx, a, &gen_rem);
 }
 
 static bool trans_remu(DisasContext *ctx, arg_remu *a)
 {
 REQUIRE_EXT(ctx, RVM);
-gen_arith(ctx, OPC_RISC_REMU, a->rd, a->rs1, a->rs2);
-return true;
+return trans_arith(ctx, a, &gen_remu);
 }
 
 #ifdef TARGET_RISCV64
 static bool trans_mulw(DisasContext *ctx, arg_mulw *a)
 {
 REQUIRE_EXT(ctx, RVM);
-gen_arith(ctx, OPC_RISC_MULW, a->rd, a->rs1, a->rs2);
-return true;
+return trans_arith(ctx, a, &gen_mulw);
 }
 
 static bool trans_divw(DisasContext *ctx, arg_divw *a)
 {
 REQUIRE_EXT(ctx, RVM);
-gen_arith(ctx, OPC_RISC_DIVW, a->rd, a->rs1, a->rs2);
-return true;
+return gen_arith_div_w(ctx, a, &gen_div);
 }
 
 static bool trans_divuw(DisasContext *ctx, arg_divuw *a)
 {
 REQUIRE_EXT(ctx, RVM);
-gen_arith(ctx, OPC_RISC_DIVUW, a->rd, a->rs1, a->rs2);
-return true;
+return gen_arith_div_w(ctx, a, &gen_divu);
 }
 
 static bool trans_remw(DisasContext *ctx, arg_remw *a)
 {
 REQUIRE_EXT(ctx, RVM);
-gen_arith(ctx, OPC_RISC_REMW, a->rd, a->rs1, a->rs2);
-return true;
+return gen_arith_div_w(ctx, a, &gen_rem);
 }
 
 static bool trans_remuw(DisasContext *ctx, arg_remuw *a)
 {
 REQUIRE_EXT(ctx, RVM);
-gen_arith(ctx, OPC_RISC_REMUW, a->rd, a->rs1, a->rs2);
-return true;
+return gen_arith_div_w(ctx, a, &gen_remu);
 }
 #endif
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 9ae40f65096f..3cd7e16c63cf 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -188,193 +188,112 @@ static void gen_mulhsu(TCGv ret, TCGv arg1, TCGv arg2)
 tcg_temp_free(rh);
 }
 
-static void gen_arith(DisasContext *ctx, uint32_t opc, int rd, int rs1,
-int rs2)
-{
-TCGv source1, source2, cond1, cond2, zeroreg, resultopt1;
-source1 = tcg_temp_new();
-source2 = tcg_temp_new();
-gen_get_gpr(source1, rs1);
-gen_get_gpr(source2, rs2);
-
-switch (opc) {
-CASE_OP_32_64(OPC_RISC_MUL):
-if (!has_ext(ctx, RVM)) {
-goto do_illegal;
-}
-tcg_gen_mul_tl(source1, source1, source2);
-break;
-case OPC_RISC_MULH:
-if (!has_ext(ctx, RVM)) {
-goto do_illegal;
-}
-tcg_gen_muls2_tl(source2, source1, source1, source2);
-break;
-case OPC_RISC_MULHSU:
-if (!has_ext(ctx, RVM)) {
-goto do_illegal;
-}
-gen_mulhsu(source1, source1, source2);
-break;
-case OP

[Qemu-devel] [PULL 18/29] target/riscv: Convert quadrant 2 of RVXC insns to decodetree

2019-03-13 Thread Palmer Dabbelt
From: Bastian Koppelmann 

Reviewed-by: Richard Henderson 
Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 
---
 target/riscv/insn16.decode  |  31 
 target/riscv/insn_trans/trans_rvc.inc.c | 101 
 target/riscv/translate.c|  83 +--
 3 files changed, 134 insertions(+), 81 deletions(-)

diff --git a/target/riscv/insn16.decode b/target/riscv/insn16.decode
index 45109301c6d4..17cc52cf2ac2 100644
--- a/target/riscv/insn16.decode
+++ b/target/riscv/insn16.decode
@@ -20,6 +20,7 @@
 %rd7:5
 %rs1_3 7:3!function=ex_rvc_register
 %rs2_3 2:3!function=ex_rvc_register
+%rs2_5 2:5
 
 # Immediates:
 %imm_ci12:s1 2:5
@@ -30,6 +31,10 @@
 %imm_cj12:s1 8:1 9:2 6:1 7:1 2:1 11:1 3:3 !function=ex_shift_1
 
 %nzuimm_6bit   12:1 2:5
+%uimm_6bit_ld 2:3 12:1 5:2   !function=ex_shift_3
+%uimm_6bit_lw 2:2 12:1 4:3   !function=ex_shift_2
+%uimm_6bit_sd 7:3 10:3   !function=ex_shift_3
+%uimm_6bit_sw 7:2 9:4!function=ex_shift_2
 
 %imm_addi16sp  12:s1 3:2 5:1 2:1 6:1 !function=ex_shift_4
 %imm_lui   12:s1 2:5 !function=ex_shift_12
@@ -48,10 +53,15 @@
 &cj   imm
 &c_shift   shamt  rd
 
+&c_ld  uimm  rd
+&c_sd  uimm  rs2
 
 &caddi16sp_lui  imm_lui imm_addi16sp rd
+&cflwsp_ldspuimm_flwsp uimm_ldsp rd
+&cfswsp_sdspuimm_fswsp uimm_sdsp rs2
 
 # Formats 16:
+@cr  . .  .. &cr  rs2=%rs2_5  %rd
 @ci... . . .  .. &ci imm=%imm_ci  %rd
 @ciw   ...    ... .. &ciwnzuimm=%nzuimm_ciw   rd=%rs2_3
 @cl_d  ... ... ... .. ... .. &cl_dw  uimm=%uimm_cl_d  rs1=%rs1_3  rd=%rs2_3
@@ -64,9 +74,19 @@
 @cb... ... ... .. ... .. &cb imm=%imm_cb  rs1=%rs1_3
 @cj...... .. &cj imm=%imm_cj
 
+@c_ld  ... . .  . .. &c_ld uimm=%uimm_6bit_ld  %rd
+@c_lw  ... . .  . .. &c_ld uimm=%uimm_6bit_lw  %rd
+@c_sd  ... . .  . .. &c_sd uimm=%uimm_6bit_sd  rs2=%rs2_5
+@c_sw  ... . .  . .. &c_sd uimm=%uimm_6bit_sw  rs2=%rs2_5
+
 @c_addi16sp_lui ... .  . . .. &caddi16sp_lui %imm_lui %imm_addi16sp %rd
+@c_flwsp_ldsp   ... .  . . .. &cflwsp_ldsp uimm_flwsp=%uimm_6bit_lw \
+uimm_ldsp=%uimm_6bit_ld %rd
+@c_fswsp_sdsp   ... .  . . .. &cfswsp_sdsp uimm_fswsp=%uimm_6bit_sw \
+uimm_sdsp=%uimm_6bit_sd rs2=%rs2_5
 
 @c_shift... . .. ... . .. &c_shift rd=%rs1_3 shamt=%nzuimm_6bit
+@c_shift2   ... . .. ... . .. &c_shift rd=%rdshamt=%nzuimm_6bit
 
 @c_andi ... . .. ... . .. &ci imm=%imm_ci rd=%rs1_3
 
@@ -96,3 +116,14 @@ c_addw100 1 11 ... 01 ... 01 @cs_2
 c_j   101 ... 01 @cj
 c_beqz110  ... ...  . 01 @cb
 c_bnez111  ... ...  . 01 @cb
+
+# *** RV64C Standard Extension (Quadrant 2) ***
+c_slli000 .  .  . 10 @c_shift2
+c_fldsp   001 .  .  . 10 @c_ld
+c_lwsp010 .  .  . 10 @c_lw
+c_flwsp_ldsp  011 .  .  . 10 @c_flwsp_ldsp 
#C.LDSP:RV64;C.FLWSP:RV32
+c_jr_mv   100 0  .  . 10 @cr
+c_ebreak_jalr_add 100 1  .  . 10 @cr
+c_fsdsp   101   ..  . 10 @c_sd
+c_swsp110 .  .  . 10 @c_sw
+c_fswsp_sdsp  111 .  .  . 10 @c_fswsp_sdsp 
#C.SDSP:RV64;C.FSWSP:RV32
diff --git a/target/riscv/insn_trans/trans_rvc.inc.c 
b/target/riscv/insn_trans/trans_rvc.inc.c
index b06c435c9800..bcdf64d3b705 100644
--- a/target/riscv/insn_trans/trans_rvc.inc.c
+++ b/target/riscv/insn_trans/trans_rvc.inc.c
@@ -224,3 +224,104 @@ static bool trans_c_bnez(DisasContext *ctx, arg_c_bnez *a)
 arg_bne arg = { .rs1 = a->rs1, .rs2 = 0, .imm = a->imm };
 return trans_bne(ctx, &arg);
 }
+
+static bool trans_c_slli(DisasContext *ctx, arg_c_slli *a)
+{
+int shamt = a->shamt;
+if (shamt == 0) {
+/* For RV128 a shamt of 0 means a shift by 64 */
+shamt = 64;
+}
+/* Ensure, that shamt[5] is zero for RV32 */
+if (shamt >= TARGET_LONG_BITS) {
+return false;
+}
+
+arg_slli arg = { .rd = a->rd, .rs1 = a->rd, .shamt = a->shamt };
+return trans_slli(ctx, &arg);
+}
+
+static bool trans_c_fldsp(DisasContext *ctx, arg_c_fldsp *a)
+{
+arg_fld arg = { .rd = a->rd, .rs1 = 2, .imm = a->uimm };
+return trans_fld(ctx, &arg);
+}
+
+static bool trans_c_lwsp(DisasContext *ctx, arg_c_lwsp *a)
+{
+arg_lw arg = { .rd = a->rd, .rs1 = 2, .imm = a->uimm };
+return trans_lw(ctx, &arg);
+}
+
+static bool trans_c_flwsp_ldsp(DisasContext *ctx, arg_c_flwsp_ldsp *a)
+{
+#ifdef TARGET_RISCV32
+/* C.FLWSP */
+arg_flw arg_flw = { .rd = a->rd, .rs1 = 2, .imm = a->uimm_flwsp };
+return trans_flw(ctx, &arg_flw);
+#else
+/* C.LDSP */
+arg_ld arg_ld = { .rd = a->rd, .rs1 = 2, .imm = a->uim

[Qemu-devel] [PULL 28/29] target/riscv: Remove gen_system()

2019-03-13 Thread Palmer Dabbelt
From: Bastian Koppelmann 

with all 16 bit insns moved to decodetree no path is falling back to
gen_system(), so we can remove it.

Reviewed-by: Richard Henderson 
Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 
---
 target/riscv/translate.c | 34 --
 1 file changed, 34 deletions(-)

diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index dedf4189d5b7..92be090bc7bb 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -473,33 +473,6 @@ static void gen_set_rm(DisasContext *ctx, int rm)
 tcg_temp_free_i32(t0);
 }
 
-static void gen_system(DisasContext *ctx, uint32_t opc, int rd, int rs1,
-   int csr)
-{
-tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next);
-
-switch (opc) {
-case OPC_RISC_ECALL:
-switch (csr) {
-case 0x0: /* ECALL */
-/* always generates U-level ECALL, fixed in do_interrupt handler */
-generate_exception(ctx, RISCV_EXCP_U_ECALL);
-tcg_gen_exit_tb(NULL, 0); /* no chaining */
-ctx->base.is_jmp = DISAS_NORETURN;
-break;
-case 0x1: /* EBREAK */
-generate_exception(ctx, RISCV_EXCP_BREAKPOINT);
-tcg_gen_exit_tb(NULL, 0); /* no chaining */
-ctx->base.is_jmp = DISAS_NORETURN;
-break;
-default:
-gen_exception_illegal(ctx);
-break;
-}
-break;
-}
-}
-
 static void decode_RV32_64C0(DisasContext *ctx)
 {
 uint8_t funct3 = extract32(ctx->opcode, 13, 3);
@@ -680,7 +653,6 @@ bool decode_insn16(DisasContext *ctx, uint16_t insn);
 
 static void decode_RV32_64G(DisasContext *ctx)
 {
-int rs1, rd;
 uint32_t op;
 
 /* We do not do misaligned address check here: the address should never be
@@ -689,14 +661,8 @@ static void decode_RV32_64G(DisasContext *ctx)
  * perform the misaligned instruction fetch */
 
 op = MASK_OP_MAJOR(ctx->opcode);
-rs1 = GET_RS1(ctx->opcode);
-rd = GET_RD(ctx->opcode);
 
 switch (op) {
-case OPC_RISC_SYSTEM:
-gen_system(ctx, MASK_OP_SYSTEM(ctx->opcode), rd, rs1,
-   (ctx->opcode & 0xFFF0) >> 20);
-break;
 default:
 gen_exception_illegal(ctx);
 break;
-- 
2.19.2




[Qemu-devel] [PULL 13/29] target/riscv: Convert RV32D insns to decodetree

2019-03-13 Thread Palmer Dabbelt
From: Bastian Koppelmann 

Acked-by: Alistair Francis 
Reviewed-by: Richard Henderson 
Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 
---
 target/riscv/insn32.decode  |  28 ++
 target/riscv/insn_trans/trans_rvd.inc.c | 360 
 target/riscv/translate.c|   1 +
 3 files changed, 389 insertions(+)
 create mode 100644 target/riscv/insn_trans/trans_rvd.inc.c

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index e40836bf032f..e64b2b5e3458 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -154,3 +154,31 @@ fclass_s   111  0 . 001 . 1010011 @r2
 fcvt_s_w   1101000  0 . ... . 1010011 @r2_rm
 fcvt_s_wu  1101000  1 . ... . 1010011 @r2_rm
 fmv_w_x000  0 . 000 . 1010011 @r2
+
+# *** RV32D Standard Extension ***
+fld   . 011 . 111 @i
+fsd... .  . 011 . 0100111 @s
+fmadd_d. 01 . . ... . 111 @r4_rm
+fmsub_d. 01 . . ... . 1000111 @r4_rm
+fnmsub_d   . 01 . . ... . 1001011 @r4_rm
+fnmadd_d   . 01 . . ... . 100 @r4_rm
+fadd_d 001  . . ... . 1010011 @r_rm
+fsub_d 101  . . ... . 1010011 @r_rm
+fmul_d 0001001  . . ... . 1010011 @r_rm
+fdiv_d 0001101  . . ... . 1010011 @r_rm
+fsqrt_d0101101  0 . ... . 1010011 @r2_rm
+fsgnj_d0010001  . . 000 . 1010011 @r
+fsgnjn_d   0010001  . . 001 . 1010011 @r
+fsgnjx_d   0010001  . . 010 . 1010011 @r
+fmin_d 0010101  . . 000 . 1010011 @r
+fmax_d 0010101  . . 001 . 1010011 @r
+fcvt_s_d   010  1 . ... . 1010011 @r2_rm
+fcvt_d_s   011  0 . ... . 1010011 @r2_rm
+feq_d  1010001  . . 010 . 1010011 @r
+flt_d  1010001  . . 001 . 1010011 @r
+fle_d  1010001  . . 000 . 1010011 @r
+fclass_d   1110001  0 . 001 . 1010011 @r2
+fcvt_w_d   111  0 . ... . 1010011 @r2_rm
+fcvt_wu_d  111  1 . ... . 1010011 @r2_rm
+fcvt_d_w   1101001  0 . ... . 1010011 @r2_rm
+fcvt_d_wu  1101001  1 . ... . 1010011 @r2_rm
diff --git a/target/riscv/insn_trans/trans_rvd.inc.c 
b/target/riscv/insn_trans/trans_rvd.inc.c
new file mode 100644
index ..98fc1cdc5a20
--- /dev/null
+++ b/target/riscv/insn_trans/trans_rvd.inc.c
@@ -0,0 +1,360 @@
+/*
+ * RISC-V translation routines for the RV64D Standard Extension.
+ *
+ * Copyright (c) 2016-2017 Sagar Karandikar, sag...@eecs.berkeley.edu
+ * Copyright (c) 2018 Peer Adelt, peer.ad...@hni.uni-paderborn.de
+ *Bastian Koppelmann, kbast...@mail.uni-paderborn.de
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see .
+ */
+
+static bool trans_fld(DisasContext *ctx, arg_fld *a)
+{
+TCGv t0 = tcg_temp_new();
+gen_get_gpr(t0, a->rs1);
+REQUIRE_FPU;
+REQUIRE_EXT(ctx, RVD);
+tcg_gen_addi_tl(t0, t0, a->imm);
+
+tcg_gen_qemu_ld_i64(cpu_fpr[a->rd], t0, ctx->mem_idx, MO_TEQ);
+
+mark_fs_dirty(ctx);
+tcg_temp_free(t0);
+return true;
+}
+
+static bool trans_fsd(DisasContext *ctx, arg_fsd *a)
+{
+TCGv t0 = tcg_temp_new();
+gen_get_gpr(t0, a->rs1);
+REQUIRE_FPU;
+REQUIRE_EXT(ctx, RVD);
+tcg_gen_addi_tl(t0, t0, a->imm);
+
+tcg_gen_qemu_st_i64(cpu_fpr[a->rs2], t0, ctx->mem_idx, MO_TEQ);
+
+mark_fs_dirty(ctx);
+tcg_temp_free(t0);
+return true;
+}
+
+static bool trans_fmadd_d(DisasContext *ctx, arg_fmadd_d *a)
+{
+REQUIRE_FPU;
+REQUIRE_EXT(ctx, RVD);
+gen_set_rm(ctx, a->rm);
+gen_helper_fmadd_d(cpu_fpr[a->rd], cpu_env, cpu_fpr[a->rs1],
+   cpu_fpr[a->rs2], cpu_fpr[a->rs3]);
+mark_fs_dirty(ctx);
+return true;
+}
+
+static bool trans_fmsub_d(DisasContext *ctx, arg_fmsub_d *a)
+{
+REQUIRE_FPU;
+REQUIRE_EXT(ctx, RVD);
+gen_set_rm(ctx, a->rm);
+gen_helper_fmsub_d(cpu_fpr[a->rd], cpu_env, cpu_fpr[a->rs1],
+   cpu_fpr[a->rs2], cpu_fpr[a->rs3]);
+mark_fs_dirty(ctx);
+return true;
+}
+
+static bool trans_fnmsub_d(DisasContext *ctx, arg_fnmsub_d *a)
+{
+REQUIRE_FPU;
+REQUIRE_EXT(ctx, RVD);
+gen_set_rm(ctx, a->rm);
+gen_helper_fnmsub_d(cpu_fpr[a->rd], cpu_env, cpu_fpr[a

[Qemu-devel] [PULL 25/29] target/riscv: Remove shift and slt insn manual decoding

2019-03-13 Thread Palmer Dabbelt
From: Bastian Koppelmann 

Reviewed-by: Richard Henderson 
Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 
---
 target/riscv/insn_trans/trans_rvi.inc.c | 93 +
 target/riscv/translate.c| 59 +---
 2 files changed, 81 insertions(+), 71 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvi.inc.c 
b/target/riscv/insn_trans/trans_rvi.inc.c
index 8879f2da35c7..88ef0003ec17 100644
--- a/target/riscv/insn_trans/trans_rvi.inc.c
+++ b/target/riscv/insn_trans/trans_rvi.inc.c
@@ -220,30 +220,25 @@ static bool trans_addi(DisasContext *ctx, arg_addi *a)
 return gen_arith_imm(ctx, a, &tcg_gen_add_tl);
 }
 
-static bool trans_slti(DisasContext *ctx, arg_slti *a)
+static void gen_slt(TCGv ret, TCGv s1, TCGv s2)
 {
-TCGv source1;
-source1 = tcg_temp_new();
-gen_get_gpr(source1, a->rs1);
+tcg_gen_setcond_tl(TCG_COND_LT, ret, s1, s2);
+}
+
+static void gen_sltu(TCGv ret, TCGv s1, TCGv s2)
+{
+tcg_gen_setcond_tl(TCG_COND_LTU, ret, s1, s2);
+}
 
-tcg_gen_setcondi_tl(TCG_COND_LT, source1, source1, a->imm);
 
-gen_set_gpr(a->rd, source1);
-tcg_temp_free(source1);
-return true;
+static bool trans_slti(DisasContext *ctx, arg_slti *a)
+{
+return gen_arith_imm(ctx, a, &gen_slt);
 }
 
 static bool trans_sltiu(DisasContext *ctx, arg_sltiu *a)
 {
-TCGv source1;
-source1 = tcg_temp_new();
-gen_get_gpr(source1, a->rs1);
-
-tcg_gen_setcondi_tl(TCG_COND_LTU, source1, source1, a->imm);
-
-gen_set_gpr(a->rd, source1);
-tcg_temp_free(source1);
-return true;
+return gen_arith_imm(ctx, a, &gen_sltu);
 }
 
 static bool trans_xori(DisasContext *ctx, arg_xori *a)
@@ -322,20 +317,17 @@ static bool trans_sub(DisasContext *ctx, arg_sub *a)
 
 static bool trans_sll(DisasContext *ctx, arg_sll *a)
 {
-gen_arith(ctx, OPC_RISC_SLL, a->rd, a->rs1, a->rs2);
-return true;
+return gen_shift(ctx, a, &tcg_gen_shl_tl);
 }
 
 static bool trans_slt(DisasContext *ctx, arg_slt *a)
 {
-gen_arith(ctx, OPC_RISC_SLT, a->rd, a->rs1, a->rs2);
-return true;
+return trans_arith(ctx, a, &gen_slt);
 }
 
 static bool trans_sltu(DisasContext *ctx, arg_sltu *a)
 {
-gen_arith(ctx, OPC_RISC_SLTU, a->rd, a->rs1, a->rs2);
-return true;
+return trans_arith(ctx, a, &gen_sltu);
 }
 
 static bool trans_xor(DisasContext *ctx, arg_xor *a)
@@ -345,14 +337,12 @@ static bool trans_xor(DisasContext *ctx, arg_xor *a)
 
 static bool trans_srl(DisasContext *ctx, arg_srl *a)
 {
-gen_arith(ctx, OPC_RISC_SRL, a->rd, a->rs1, a->rs2);
-return true;
+return gen_shift(ctx, a, &tcg_gen_shr_tl);
 }
 
 static bool trans_sra(DisasContext *ctx, arg_sra *a)
 {
-gen_arith(ctx, OPC_RISC_SRA, a->rd, a->rs1, a->rs2);
-return true;
+return gen_shift(ctx, a, &tcg_gen_sar_tl);
 }
 
 static bool trans_or(DisasContext *ctx, arg_or *a)
@@ -419,19 +409,62 @@ static bool trans_subw(DisasContext *ctx, arg_subw *a)
 
 static bool trans_sllw(DisasContext *ctx, arg_sllw *a)
 {
-gen_arith(ctx, OPC_RISC_SLLW, a->rd, a->rs1, a->rs2);
+TCGv source1 = tcg_temp_new();
+TCGv source2 = tcg_temp_new();
+
+gen_get_gpr(source1, a->rs1);
+gen_get_gpr(source2, a->rs2);
+
+tcg_gen_andi_tl(source2, source2, 0x1F);
+tcg_gen_shl_tl(source1, source1, source2);
+
+tcg_gen_ext32s_tl(source1, source1);
+gen_set_gpr(a->rd, source1);
+tcg_temp_free(source1);
+tcg_temp_free(source2);
 return true;
 }
 
 static bool trans_srlw(DisasContext *ctx, arg_srlw *a)
 {
-gen_arith(ctx, OPC_RISC_SRLW, a->rd, a->rs1, a->rs2);
+TCGv source1 = tcg_temp_new();
+TCGv source2 = tcg_temp_new();
+
+gen_get_gpr(source1, a->rs1);
+gen_get_gpr(source2, a->rs2);
+
+/* clear upper 32 */
+tcg_gen_ext32u_tl(source1, source1);
+tcg_gen_andi_tl(source2, source2, 0x1F);
+tcg_gen_shr_tl(source1, source1, source2);
+
+tcg_gen_ext32s_tl(source1, source1);
+gen_set_gpr(a->rd, source1);
+tcg_temp_free(source1);
+tcg_temp_free(source2);
 return true;
 }
 
 static bool trans_sraw(DisasContext *ctx, arg_sraw *a)
 {
-gen_arith(ctx, OPC_RISC_SRAW, a->rd, a->rs1, a->rs2);
+TCGv source1 = tcg_temp_new();
+TCGv source2 = tcg_temp_new();
+
+gen_get_gpr(source1, a->rs1);
+gen_get_gpr(source2, a->rs2);
+
+/*
+ * first, trick to get it to act like working on 32 bits (get rid of
+ * upper 32, sign extend to fill space)
+ */
+tcg_gen_ext32s_tl(source1, source1);
+tcg_gen_andi_tl(source2, source2, 0x1F);
+tcg_gen_sar_tl(source1, source1, source2);
+
+gen_set_gpr(a->rd, source1);
+tcg_temp_free(source1);
+tcg_temp_free(source2);
+
 return true;
 }
 #endif
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 8eb883463322..9ae40f65096f 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -198,47 +198,6 @@ static void gen_arith(DisasContext *ctx, uint32_t opc, int 
rd, int rs1,
 gen_get_gpr(

[Qemu-devel] [PULL 27/29] target/riscv: Rename trans_arith to gen_arith

2019-03-13 Thread Palmer Dabbelt
From: Bastian Koppelmann 

Reviewed-by: Richard Henderson 
Signed-off-by: Bastian Koppelmann 
---
 target/riscv/insn_trans/trans_rvi.inc.c | 18 +-
 target/riscv/insn_trans/trans_rvm.inc.c | 14 +++---
 target/riscv/translate.c|  4 ++--
 3 files changed, 18 insertions(+), 18 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvi.inc.c 
b/target/riscv/insn_trans/trans_rvi.inc.c
index 88ef0003ec17..d420a4d8b2e9 100644
--- a/target/riscv/insn_trans/trans_rvi.inc.c
+++ b/target/riscv/insn_trans/trans_rvi.inc.c
@@ -307,12 +307,12 @@ static bool trans_srai(DisasContext *ctx, arg_srai *a)
 
 static bool trans_add(DisasContext *ctx, arg_add *a)
 {
-return trans_arith(ctx, a, &tcg_gen_add_tl);
+return gen_arith(ctx, a, &tcg_gen_add_tl);
 }
 
 static bool trans_sub(DisasContext *ctx, arg_sub *a)
 {
-return trans_arith(ctx, a, &tcg_gen_sub_tl);
+return gen_arith(ctx, a, &tcg_gen_sub_tl);
 }
 
 static bool trans_sll(DisasContext *ctx, arg_sll *a)
@@ -322,17 +322,17 @@ static bool trans_sll(DisasContext *ctx, arg_sll *a)
 
 static bool trans_slt(DisasContext *ctx, arg_slt *a)
 {
-return trans_arith(ctx, a, &gen_slt);
+return gen_arith(ctx, a, &gen_slt);
 }
 
 static bool trans_sltu(DisasContext *ctx, arg_sltu *a)
 {
-return trans_arith(ctx, a, &gen_sltu);
+return gen_arith(ctx, a, &gen_sltu);
 }
 
 static bool trans_xor(DisasContext *ctx, arg_xor *a)
 {
-return trans_arith(ctx, a, &tcg_gen_xor_tl);
+return gen_arith(ctx, a, &tcg_gen_xor_tl);
 }
 
 static bool trans_srl(DisasContext *ctx, arg_srl *a)
@@ -347,12 +347,12 @@ static bool trans_sra(DisasContext *ctx, arg_sra *a)
 
 static bool trans_or(DisasContext *ctx, arg_or *a)
 {
-return trans_arith(ctx, a, &tcg_gen_or_tl);
+return gen_arith(ctx, a, &tcg_gen_or_tl);
 }
 
 static bool trans_and(DisasContext *ctx, arg_and *a)
 {
-return trans_arith(ctx, a, &tcg_gen_and_tl);
+return gen_arith(ctx, a, &tcg_gen_and_tl);
 }
 
 #ifdef TARGET_RISCV64
@@ -399,12 +399,12 @@ static bool trans_sraiw(DisasContext *ctx, arg_sraiw *a)
 
 static bool trans_addw(DisasContext *ctx, arg_addw *a)
 {
-return trans_arith(ctx, a, &gen_addw);
+return gen_arith(ctx, a, &gen_addw);
 }
 
 static bool trans_subw(DisasContext *ctx, arg_subw *a)
 {
-return trans_arith(ctx, a, &gen_subw);
+return gen_arith(ctx, a, &gen_subw);
 }
 
 static bool trans_sllw(DisasContext *ctx, arg_sllw *a)
diff --git a/target/riscv/insn_trans/trans_rvm.inc.c 
b/target/riscv/insn_trans/trans_rvm.inc.c
index d2bf2f171904..204af225f8f3 100644
--- a/target/riscv/insn_trans/trans_rvm.inc.c
+++ b/target/riscv/insn_trans/trans_rvm.inc.c
@@ -22,7 +22,7 @@
 static bool trans_mul(DisasContext *ctx, arg_mul *a)
 {
 REQUIRE_EXT(ctx, RVM);
-return trans_arith(ctx, a, &tcg_gen_mul_tl);
+return gen_arith(ctx, a, &tcg_gen_mul_tl);
 }
 
 static bool trans_mulh(DisasContext *ctx, arg_mulh *a)
@@ -44,7 +44,7 @@ static bool trans_mulh(DisasContext *ctx, arg_mulh *a)
 static bool trans_mulhsu(DisasContext *ctx, arg_mulhsu *a)
 {
 REQUIRE_EXT(ctx, RVM);
-return trans_arith(ctx, a, &gen_mulhsu);
+return gen_arith(ctx, a, &gen_mulhsu);
 }
 
 static bool trans_mulhu(DisasContext *ctx, arg_mulhu *a)
@@ -66,32 +66,32 @@ static bool trans_mulhu(DisasContext *ctx, arg_mulhu *a)
 static bool trans_div(DisasContext *ctx, arg_div *a)
 {
 REQUIRE_EXT(ctx, RVM);
-return trans_arith(ctx, a, &gen_div);
+return gen_arith(ctx, a, &gen_div);
 }
 
 static bool trans_divu(DisasContext *ctx, arg_divu *a)
 {
 REQUIRE_EXT(ctx, RVM);
-return trans_arith(ctx, a, &gen_divu);
+return gen_arith(ctx, a, &gen_divu);
 }
 
 static bool trans_rem(DisasContext *ctx, arg_rem *a)
 {
 REQUIRE_EXT(ctx, RVM);
-return trans_arith(ctx, a, &gen_rem);
+return gen_arith(ctx, a, &gen_rem);
 }
 
 static bool trans_remu(DisasContext *ctx, arg_remu *a)
 {
 REQUIRE_EXT(ctx, RVM);
-return trans_arith(ctx, a, &gen_remu);
+return gen_arith(ctx, a, &gen_remu);
 }
 
 #ifdef TARGET_RISCV64
 static bool trans_mulw(DisasContext *ctx, arg_mulw *a)
 {
 REQUIRE_EXT(ctx, RVM);
-return trans_arith(ctx, a, &gen_mulw);
+return gen_arith(ctx, a, &gen_mulw);
 }
 
 static bool trans_divw(DisasContext *ctx, arg_divw *a)
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 3cd7e16c63cf..dedf4189d5b7 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -629,8 +629,8 @@ static bool gen_arith_div_w(DisasContext *ctx, arg_r *a,
 
 #endif
 
-static bool trans_arith(DisasContext *ctx, arg_r *a,
-void(*func)(TCGv, TCGv, TCGv))
+static bool gen_arith(DisasContext *ctx, arg_r *a,
+  void(*func)(TCGv, TCGv, TCGv))
 {
 TCGv source1, source2;
 source1 = tcg_temp_new();
-- 
2.19.2




[Qemu-devel] [PULL 16/29] target/riscv: Convert quadrant 0 of RVXC insns to decodetree

2019-03-13 Thread Palmer Dabbelt
From: Bastian Koppelmann 

Reviewed-by: Richard Henderson 
Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 
---
 target/riscv/Makefile.objs  |  9 ++-
 target/riscv/insn16.decode  | 55 ++
 target/riscv/insn_trans/trans_rvc.inc.c | 75 +
 target/riscv/translate.c| 53 ++---
 4 files changed, 154 insertions(+), 38 deletions(-)
 create mode 100644 target/riscv/insn16.decode
 create mode 100644 target/riscv/insn_trans/trans_rvc.inc.c

diff --git a/target/riscv/Makefile.objs b/target/riscv/Makefile.objs
index 05087a91bb85..9c6c1093271e 100644
--- a/target/riscv/Makefile.objs
+++ b/target/riscv/Makefile.objs
@@ -10,4 +10,11 @@ target/riscv/decode_insn32.inc.c: $(decode32-y) $(DECODETREE)
  $(PYTHON) $(DECODETREE) -o $@ --decode decode_insn32 $(decode32-y), \
  "GEN", $(TARGET_DIR)$@)
 
-target/riscv/translate.o: target/riscv/decode_insn32.inc.c
+target/riscv/decode_insn16.inc.c: \
+  $(SRC_PATH)/target/riscv/insn16.decode $(DECODETREE)
+   $(call quiet-command, \
+ $(PYTHON) $(DECODETREE) -o $@ --decode decode_insn16 --insnwidth 16 
$<, \
+ "GEN", $(TARGET_DIR)$@)
+
+target/riscv/translate.o: target/riscv/decode_insn32.inc.c \
+   target/riscv/decode_insn16.inc.c
diff --git a/target/riscv/insn16.decode b/target/riscv/insn16.decode
new file mode 100644
index ..558c0c41f0b5
--- /dev/null
+++ b/target/riscv/insn16.decode
@@ -0,0 +1,55 @@
+#
+# RISC-V translation routines for the RVXI Base Integer Instruction Set.
+#
+# Copyright (c) 2018 Peer Adelt, peer.ad...@hni.uni-paderborn.de
+#Bastian Koppelmann, kbast...@mail.uni-paderborn.de
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms and conditions of the GNU General Public License,
+# version 2 or later, as published by the Free Software Foundation.
+#
+# This program is distributed in the hope it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+# more details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program.  If not, see .
+
+# Fields:
+%rd7:5
+%rs1_3 7:3!function=ex_rvc_register
+%rs2_3 2:3!function=ex_rvc_register
+
+# Immediates:
+%nzuimm_ciw7:4 11:2 5:1 6:1   !function=ex_shift_2
+%uimm_cl_d 5:2 10:3   !function=ex_shift_3
+%uimm_cl_w 5:1 10:3 6:1   !function=ex_shift_2
+
+
+# Argument sets:
+&cl   rs1 rd
+&cl_dw uimm   rs1 rd
+&ciw   nzuimm rd
+&cs   rs1 rs2
+&cs_dw uimm   rs1 rs2
+
+
+# Formats 16:
+@ciw   ...    ... .. &ciwnzuimm=%nzuimm_ciw   rd=%rs2_3
+@cl_d  ... ... ... .. ... .. &cl_dw  uimm=%uimm_cl_d  rs1=%rs1_3  rd=%rs2_3
+@cl_w  ... ... ... .. ... .. &cl_dw  uimm=%uimm_cl_w  rs1=%rs1_3  rd=%rs2_3
+@cl... ... ... .. ... .. &cl  rs1=%rs1_3  rd=%rs2_3
+@cs... ... ... .. ... .. &cs  rs1=%rs1_3  
rs2=%rs2_3
+@cs_d  ... ... ... .. ... .. &cs_dw  uimm=%uimm_cl_d  rs1=%rs1_3  
rs2=%rs2_3
+@cs_w  ... ... ... .. ... .. &cs_dw  uimm=%uimm_cl_w  rs1=%rs1_3  
rs2=%rs2_3
+
+
+# *** RV64C Standard Extension (Quadrant 0) ***
+c_addi4spn000 ... 00 @ciw
+c_fld 001  ... ... .. ... 00 @cl_d
+c_lw  010  ... ... .. ... 00 @cl_w
+c_flw_ld  011  --- ... -- ... 00 @cl#Note: Must parse uimm manually
+c_fsd 101  ... ... .. ... 00 @cs_d
+c_sw  110  ... ... .. ... 00 @cs_w
+c_fsw_sd  111  --- ... -- ... 00 @cs#Note: Must parse uimm manually
diff --git a/target/riscv/insn_trans/trans_rvc.inc.c 
b/target/riscv/insn_trans/trans_rvc.inc.c
new file mode 100644
index ..93ec8aa30b95
--- /dev/null
+++ b/target/riscv/insn_trans/trans_rvc.inc.c
@@ -0,0 +1,75 @@
+/*
+ * RISC-V translation routines for the RVC Compressed Instruction Set.
+ *
+ * Copyright (c) 2016-2017 Sagar Karandikar, sag...@eecs.berkeley.edu
+ * Copyright (c) 2018 Peer Adelt, peer.ad...@hni.uni-paderborn.de
+ *Bastian Koppelmann, kbast...@mail.uni-paderborn.de
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see .
+ */
+

[Qemu-devel] [PULL 21/29] target/riscv: Remove manual decoding from gen_load()

2019-03-13 Thread Palmer Dabbelt
From: Bastian Koppelmann 

With decodetree we don't need to convert RISC-V opcodes into to MemOps
as the old gen_load() did.

Reviewed-by: Richard Henderson 
Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 
---
 target/riscv/insn_trans/trans_rvi.inc.c | 35 +++--
 target/riscv/translate.c|  6 +++--
 2 files changed, 25 insertions(+), 16 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvi.inc.c 
b/target/riscv/insn_trans/trans_rvi.inc.c
index ae4b0a2bcb78..cc361ed4d151 100644
--- a/target/riscv/insn_trans/trans_rvi.inc.c
+++ b/target/riscv/insn_trans/trans_rvi.inc.c
@@ -129,34 +129,43 @@ static bool trans_bgeu(DisasContext *ctx, arg_bgeu *a)
 return gen_branch(ctx, a, TCG_COND_GEU);
 }
 
-static bool trans_lb(DisasContext *ctx, arg_lb *a)
+static bool gen_load(DisasContext *ctx, arg_lb *a, TCGMemOp memop)
 {
-gen_load(ctx, OPC_RISC_LB, a->rd, a->rs1, a->imm);
+TCGv t0 = tcg_temp_new();
+TCGv t1 = tcg_temp_new();
+gen_get_gpr(t0, a->rs1);
+tcg_gen_addi_tl(t0, t0, a->imm);
+
+tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, memop);
+gen_set_gpr(a->rd, t1);
+tcg_temp_free(t0);
+tcg_temp_free(t1);
 return true;
 }
 
+static bool trans_lb(DisasContext *ctx, arg_lb *a)
+{
+return gen_load(ctx, a, MO_SB);
+}
+
 static bool trans_lh(DisasContext *ctx, arg_lh *a)
 {
-gen_load(ctx, OPC_RISC_LH, a->rd, a->rs1, a->imm);
-return true;
+return gen_load(ctx, a, MO_TESW);
 }
 
 static bool trans_lw(DisasContext *ctx, arg_lw *a)
 {
-gen_load(ctx, OPC_RISC_LW, a->rd, a->rs1, a->imm);
-return true;
+return gen_load(ctx, a, MO_TESL);
 }
 
 static bool trans_lbu(DisasContext *ctx, arg_lbu *a)
 {
-gen_load(ctx, OPC_RISC_LBU, a->rd, a->rs1, a->imm);
-return true;
+return gen_load(ctx, a, MO_UB);
 }
 
 static bool trans_lhu(DisasContext *ctx, arg_lhu *a)
 {
-gen_load(ctx, OPC_RISC_LHU, a->rd, a->rs1, a->imm);
-return true;
+return gen_load(ctx, a, MO_TEUW);
 }
 
 static bool trans_sb(DisasContext *ctx, arg_sb *a)
@@ -180,14 +189,12 @@ static bool trans_sw(DisasContext *ctx, arg_sw *a)
 #ifdef TARGET_RISCV64
 static bool trans_lwu(DisasContext *ctx, arg_lwu *a)
 {
-gen_load(ctx, OPC_RISC_LWU, a->rd, a->rs1, a->imm);
-return true;
+return gen_load(ctx, a, MO_TEUL);
 }
 
 static bool trans_ld(DisasContext *ctx, arg_ld *a)
 {
-gen_load(ctx, OPC_RISC_LD, a->rd, a->rs1, a->imm);
-return true;
+return gen_load(ctx, a, MO_TEQ);
 }
 
 static bool trans_sd(DisasContext *ctx, arg_sd *a)
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index a3d5cdbad82d..99d6d3b4ae91 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -531,7 +531,8 @@ static void gen_jal(DisasContext *ctx, int rd, target_ulong 
imm)
 ctx->base.is_jmp = DISAS_NORETURN;
 }
 
-static void gen_load(DisasContext *ctx, uint32_t opc, int rd, int rs1,
+#ifdef TARGET_RISCV64
+static void gen_load_c(DisasContext *ctx, uint32_t opc, int rd, int rs1,
 target_long imm)
 {
 TCGv t0 = tcg_temp_new();
@@ -550,6 +551,7 @@ static void gen_load(DisasContext *ctx, uint32_t opc, int 
rd, int rs1,
 tcg_temp_free(t0);
 tcg_temp_free(t1);
 }
+#endif
 
 static void gen_store(DisasContext *ctx, uint32_t opc, int rs1, int rs2,
 target_long imm)
@@ -723,7 +725,7 @@ static void decode_RV32_64C0(DisasContext *ctx)
 case 3:
 #if defined(TARGET_RISCV64)
 /* C.LD(RV64/128) -> ld rd', offset[7:3](rs1')*/
-gen_load(ctx, OPC_RISC_LD, rd_rs2, rs1s,
+gen_load_c(ctx, OPC_RISC_LD, rd_rs2, rs1s,
  GET_C_LD_IMM(ctx->opcode));
 #else
 /* C.FLW (RV32) -> flw rd', offset[6:2](rs1')*/
-- 
2.19.2




[Qemu-devel] [PULL 11/29] target/riscv: Convert RV32F insns to decodetree

2019-03-13 Thread Palmer Dabbelt
From: Bastian Koppelmann 

Acked-by: Alistair Francis 
Reviewed-by: Richard Henderson 
Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 
---
 target/riscv/insn32.decode  |  35 +++
 target/riscv/insn_trans/trans_rvf.inc.c | 379 
 target/riscv/translate.c|   1 +
 3 files changed, 415 insertions(+)
 create mode 100644 target/riscv/insn_trans/trans_rvf.inc.c

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 00b9e2d9a508..e40836bf032f 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -17,12 +17,14 @@
 # this program.  If not, see .
 
 # Fields:
+%rs3   27:5
 %rs2   20:5
 %rs1   15:5
 %rd7:5
 
 %sh1020:10
 %csr20:12
+%rm 12:3
 
 # immediates:
 %imm_i20:s12
@@ -50,6 +52,11 @@
 @atom_ld . aq:1 rl:1 .  . ... &atomic rs2=0 %rs1 
%rd
 @atom_st . aq:1 rl:1 .  . ... &atomic %rs2  %rs1 
%rd
 
+@r4_rm   . ..  . . ... . ... %rs3 %rs2 %rs1 %rm %rd
+@r_rm...   . . ... . ... %rs2 %rs1 %rm %rd
+@r2_rm   ...   . . ... . ... %rs1 %rm %rd
+@r2  ...   . . ... . ... %rs1 %rd
+
 # *** RV32I Base Instruction Set ***
 lui     . 0110111 @u
 auipc   . 0010111 @u
@@ -119,3 +126,31 @@ amomin_w   1 . . . . 010 . 010 @atom_st
 amomax_w   10100 . . . . 010 . 010 @atom_st
 amominu_w  11000 . . . . 010 . 010 @atom_st
 amomaxu_w  11100 . . . . 010 . 010 @atom_st
+
+# *** RV32F Standard Extension ***
+flw   . 010 . 111 @i
+fsw...  . . 010 . 0100111 @s
+fmadd_s. 00 . . ... . 111 @r4_rm
+fmsub_s. 00 . . ... . 1000111 @r4_rm
+fnmsub_s   . 00 . . ... . 1001011 @r4_rm
+fnmadd_s   . 00 . . ... . 100 @r4_rm
+fadd_s 000  . . ... . 1010011 @r_rm
+fsub_s 100  . . ... . 1010011 @r_rm
+fmul_s 0001000  . . ... . 1010011 @r_rm
+fdiv_s 0001100  . . ... . 1010011 @r_rm
+fsqrt_s0101100  0 . ... . 1010011 @r2_rm
+fsgnj_s001  . . 000 . 1010011 @r
+fsgnjn_s   001  . . 001 . 1010011 @r
+fsgnjx_s   001  . . 010 . 1010011 @r
+fmin_s 0010100  . . 000 . 1010011 @r
+fmax_s 0010100  . . 001 . 1010011 @r
+fcvt_w_s   110  0 . ... . 1010011 @r2_rm
+fcvt_wu_s  110  1 . ... . 1010011 @r2_rm
+fmv_x_w111  0 . 000 . 1010011 @r2
+feq_s  101  . . 010 . 1010011 @r
+flt_s  101  . . 001 . 1010011 @r
+fle_s  101  . . 000 . 1010011 @r
+fclass_s   111  0 . 001 . 1010011 @r2
+fcvt_s_w   1101000  0 . ... . 1010011 @r2_rm
+fcvt_s_wu  1101000  1 . ... . 1010011 @r2_rm
+fmv_w_x000  0 . 000 . 1010011 @r2
diff --git a/target/riscv/insn_trans/trans_rvf.inc.c 
b/target/riscv/insn_trans/trans_rvf.inc.c
new file mode 100644
index ..0f837903491b
--- /dev/null
+++ b/target/riscv/insn_trans/trans_rvf.inc.c
@@ -0,0 +1,379 @@
+/*
+ * RISC-V translation routines for the RV64F Standard Extension.
+ *
+ * Copyright (c) 2016-2017 Sagar Karandikar, sag...@eecs.berkeley.edu
+ * Copyright (c) 2018 Peer Adelt, peer.ad...@hni.uni-paderborn.de
+ *Bastian Koppelmann, kbast...@mail.uni-paderborn.de
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see .
+ */
+
+#define REQUIRE_FPU do {\
+if (ctx->mstatus_fs == 0) \
+return false;   \
+} while (0)
+
+static bool trans_flw(DisasContext *ctx, arg_flw *a)
+{
+TCGv t0 = tcg_temp_new();
+gen_get_gpr(t0, a->rs1);
+REQUIRE_FPU;
+REQUIRE_EXT(ctx, RVF);
+tcg_gen_addi_tl(t0, t0, a->imm);
+
+tcg_gen_qemu_ld_i64(cpu_fpr[a->rd], t0, ctx->mem_idx, MO_TEUL);
+/* RISC-V requires NaN-boxing of narrower width floating point values */
+tcg_gen_ori_i64(cpu_fpr[a->rd], cpu_fpr[a->rd], 0xULL);
+
+tcg_temp_free(t0);
+mark_fs_dirty(ctx);
+return true;
+}
+
+static bool trans_fsw(DisasContext *ctx,

[Qemu-devel] [PULL 14/29] target/riscv: Convert RV64D insns to decodetree

2019-03-13 Thread Palmer Dabbelt
From: Bastian Koppelmann 

Acked-by: Alistair Francis 
Reviewed-by: Richard Henderson 
Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 
---
 target/riscv/insn32-64.decode   |   8 +
 target/riscv/insn_trans/trans_rvd.inc.c |  82 
 target/riscv/translate.c| 601 +---
 3 files changed, 91 insertions(+), 600 deletions(-)

diff --git a/target/riscv/insn32-64.decode b/target/riscv/insn32-64.decode
index 6319f872ac1d..380bf791bcdc 100644
--- a/target/riscv/insn32-64.decode
+++ b/target/riscv/insn32-64.decode
@@ -62,3 +62,11 @@ fcvt_l_s   110  00010 . ... . 1010011 @r2_rm
 fcvt_lu_s  110  00011 . ... . 1010011 @r2_rm
 fcvt_s_l   1101000  00010 . ... . 1010011 @r2_rm
 fcvt_s_lu  1101000  00011 . ... . 1010011 @r2_rm
+
+# *** RV64D Standard Extension (in addition to RV32D) ***
+fcvt_l_d   111  00010 . ... . 1010011 @r2_rm
+fcvt_lu_d  111  00011 . ... . 1010011 @r2_rm
+fmv_x_d1110001  0 . 000 . 1010011 @r2
+fcvt_d_l   1101001  00010 . ... . 1010011 @r2_rm
+fcvt_d_lu  1101001  00011 . ... . 1010011 @r2_rm
+fmv_d_x001  0 . 000 . 1010011 @r2
diff --git a/target/riscv/insn_trans/trans_rvd.inc.c 
b/target/riscv/insn_trans/trans_rvd.inc.c
index 98fc1cdc5a20..393fa0248ce9 100644
--- a/target/riscv/insn_trans/trans_rvd.inc.c
+++ b/target/riscv/insn_trans/trans_rvd.inc.c
@@ -358,3 +358,85 @@ static bool trans_fcvt_d_wu(DisasContext *ctx, 
arg_fcvt_d_wu *a)
 mark_fs_dirty(ctx);
 return true;
 }
+
+#ifdef TARGET_RISCV64
+
+static bool trans_fcvt_l_d(DisasContext *ctx, arg_fcvt_l_d *a)
+{
+REQUIRE_FPU;
+REQUIRE_EXT(ctx, RVD);
+
+TCGv t0 = tcg_temp_new();
+gen_set_rm(ctx, a->rm);
+gen_helper_fcvt_l_d(t0, cpu_env, cpu_fpr[a->rs1]);
+gen_set_gpr(a->rd, t0);
+tcg_temp_free(t0);
+return true;
+}
+
+static bool trans_fcvt_lu_d(DisasContext *ctx, arg_fcvt_lu_d *a)
+{
+REQUIRE_FPU;
+REQUIRE_EXT(ctx, RVD);
+
+TCGv t0 = tcg_temp_new();
+gen_set_rm(ctx, a->rm);
+gen_helper_fcvt_lu_d(t0, cpu_env, cpu_fpr[a->rs1]);
+gen_set_gpr(a->rd, t0);
+tcg_temp_free(t0);
+return true;
+}
+
+static bool trans_fmv_x_d(DisasContext *ctx, arg_fmv_x_d *a)
+{
+REQUIRE_FPU;
+REQUIRE_EXT(ctx, RVD);
+
+gen_set_gpr(a->rd, cpu_fpr[a->rs1]);
+return true;
+}
+
+static bool trans_fcvt_d_l(DisasContext *ctx, arg_fcvt_d_l *a)
+{
+REQUIRE_FPU;
+REQUIRE_EXT(ctx, RVD);
+
+TCGv t0 = tcg_temp_new();
+gen_get_gpr(t0, a->rs1);
+
+gen_set_rm(ctx, a->rm);
+gen_helper_fcvt_d_l(cpu_fpr[a->rd], cpu_env, t0);
+tcg_temp_free(t0);
+mark_fs_dirty(ctx);
+return true;
+}
+
+static bool trans_fcvt_d_lu(DisasContext *ctx, arg_fcvt_d_lu *a)
+{
+REQUIRE_FPU;
+REQUIRE_EXT(ctx, RVD);
+
+TCGv t0 = tcg_temp_new();
+gen_get_gpr(t0, a->rs1);
+
+gen_set_rm(ctx, a->rm);
+gen_helper_fcvt_d_lu(cpu_fpr[a->rd], cpu_env, t0);
+tcg_temp_free(t0);
+mark_fs_dirty(ctx);
+return true;
+}
+
+static bool trans_fmv_d_x(DisasContext *ctx, arg_fmv_d_x *a)
+{
+REQUIRE_FPU;
+REQUIRE_EXT(ctx, RVD);
+
+TCGv t0 = tcg_temp_new();
+gen_get_gpr(t0, a->rs1);
+
+tcg_gen_mov_tl(cpu_fpr[a->rd], t0);
+tcg_temp_free(t0);
+mark_fs_dirty(ctx);
+return true;
+}
+#endif
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index c201985ef37b..2e36deee82f4 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -186,44 +186,6 @@ static void gen_mulhsu(TCGv ret, TCGv arg1, TCGv arg2)
 tcg_temp_free(rh);
 }
 
-static void gen_fsgnj(DisasContext *ctx, uint32_t rd, uint32_t rs1,
-uint32_t rs2, int rm, uint64_t min)
-{
-switch (rm) {
-case 0: /* fsgnj */
-if (rs1 == rs2) { /* FMOV */
-tcg_gen_mov_i64(cpu_fpr[rd], cpu_fpr[rs1]);
-} else {
-tcg_gen_deposit_i64(cpu_fpr[rd], cpu_fpr[rs2], cpu_fpr[rs1],
-0, min == INT32_MIN ? 31 : 63);
-}
-break;
-case 1: /* fsgnjn */
-if (rs1 == rs2) { /* FNEG */
-tcg_gen_xori_i64(cpu_fpr[rd], cpu_fpr[rs1], min);
-} else {
-TCGv_i64 t0 = tcg_temp_new_i64();
-tcg_gen_not_i64(t0, cpu_fpr[rs2]);
-tcg_gen_deposit_i64(cpu_fpr[rd], t0, cpu_fpr[rs1],
-0, min == INT32_MIN ? 31 : 63);
-tcg_temp_free_i64(t0);
-}
-break;
-case 2: /* fsgnjx */
-if (rs1 == rs2) { /* FABS */
-tcg_gen_andi_i64(cpu_fpr[rd], cpu_fpr[rs1], ~min);
-} else {
-TCGv_i64 t0 = tcg_temp_new_i64();
-tcg_gen_andi_i64(t0, cpu_fpr[rs2], min);
-tcg_gen_xor_i64(cpu_fpr[rd], cpu_fpr[rs1], t0);
-tcg_temp_free_i64(t0);
-}
-break;
-default:
-gen_exception_illegal(ctx);
-}
-}
-
 static void gen_arith(DisasContext *ctx, uint32_t opc, 

[Qemu-devel] [PULL 19/29] target/riscv: Remove gen_jalr()

2019-03-13 Thread Palmer Dabbelt
From: Bastian Koppelmann 

trans_jalr() is the only caller, so move the code into trans_jalr().

Acked-by: Alistair Francis 
Reviewed-by: Richard Henderson 
Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 
---
 target/riscv/insn_trans/trans_rvi.inc.c | 28 +-
 target/riscv/translate.c| 38 -
 2 files changed, 27 insertions(+), 39 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvi.inc.c 
b/target/riscv/insn_trans/trans_rvi.inc.c
index 4a23372cb823..631a88906bce 100644
--- a/target/riscv/insn_trans/trans_rvi.inc.c
+++ b/target/riscv/insn_trans/trans_rvi.inc.c
@@ -42,7 +42,33 @@ static bool trans_jal(DisasContext *ctx, arg_jal *a)
 
 static bool trans_jalr(DisasContext *ctx, arg_jalr *a)
 {
-gen_jalr(ctx, OPC_RISC_JALR, a->rd, a->rs1, a->imm);
+/* no chaining with JALR */
+TCGLabel *misaligned = NULL;
+TCGv t0 = tcg_temp_new();
+
+
+gen_get_gpr(cpu_pc, a->rs1);
+tcg_gen_addi_tl(cpu_pc, cpu_pc, a->imm);
+tcg_gen_andi_tl(cpu_pc, cpu_pc, (target_ulong)-2);
+
+if (!has_ext(ctx, RVC)) {
+misaligned = gen_new_label();
+tcg_gen_andi_tl(t0, cpu_pc, 0x2);
+tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0x0, misaligned);
+}
+
+if (a->rd != 0) {
+tcg_gen_movi_tl(cpu_gpr[a->rd], ctx->pc_succ_insn);
+}
+tcg_gen_lookup_and_goto_ptr();
+
+if (misaligned) {
+gen_set_label(misaligned);
+gen_exception_inst_addr_mis(ctx);
+}
+ctx->base.is_jmp = DISAS_NORETURN;
+
+tcg_temp_free(t0);
 return true;
 }
 
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 80afa2c1e62b..9dee2ec24287 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -531,44 +531,6 @@ static void gen_jal(DisasContext *ctx, int rd, 
target_ulong imm)
 ctx->base.is_jmp = DISAS_NORETURN;
 }
 
-static void gen_jalr(DisasContext *ctx, uint32_t opc, int rd, int rs1,
- target_long imm)
-{
-/* no chaining with JALR */
-TCGLabel *misaligned = NULL;
-TCGv t0 = tcg_temp_new();
-
-switch (opc) {
-case OPC_RISC_JALR:
-gen_get_gpr(cpu_pc, rs1);
-tcg_gen_addi_tl(cpu_pc, cpu_pc, imm);
-tcg_gen_andi_tl(cpu_pc, cpu_pc, (target_ulong)-2);
-
-if (!has_ext(ctx, RVC)) {
-misaligned = gen_new_label();
-tcg_gen_andi_tl(t0, cpu_pc, 0x2);
-tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0x0, misaligned);
-}
-
-if (rd != 0) {
-tcg_gen_movi_tl(cpu_gpr[rd], ctx->pc_succ_insn);
-}
-tcg_gen_lookup_and_goto_ptr();
-
-if (misaligned) {
-gen_set_label(misaligned);
-gen_exception_inst_addr_mis(ctx);
-}
-ctx->base.is_jmp = DISAS_NORETURN;
-break;
-
-default:
-gen_exception_illegal(ctx);
-break;
-}
-tcg_temp_free(t0);
-}
-
 static void gen_branch(DisasContext *ctx, uint32_t opc, int rs1, int rs2,
target_long bimm)
 {
-- 
2.19.2




[Qemu-devel] [PULL 12/29] target/riscv: Convert RV64F insns to decodetree

2019-03-13 Thread Palmer Dabbelt
From: Bastian Koppelmann 

Acked-by: Alistair Francis 
Reviewed-by: Richard Henderson 
Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 
---
 target/riscv/insn32-64.decode   |  6 +++
 target/riscv/insn_trans/trans_rvf.inc.c | 60 +
 2 files changed, 66 insertions(+)

diff --git a/target/riscv/insn32-64.decode b/target/riscv/insn32-64.decode
index 0bee95c9840d..6319f872ac1d 100644
--- a/target/riscv/insn32-64.decode
+++ b/target/riscv/insn32-64.decode
@@ -56,3 +56,9 @@ amomin_d   1 . . . . 011 . 010 @atom_st
 amomax_d   10100 . . . . 011 . 010 @atom_st
 amominu_d  11000 . . . . 011 . 010 @atom_st
 amomaxu_d  11100 . . . . 011 . 010 @atom_st
+
+# *** RV64F Standard Extension (in addition to RV32F) ***
+fcvt_l_s   110  00010 . ... . 1010011 @r2_rm
+fcvt_lu_s  110  00011 . ... . 1010011 @r2_rm
+fcvt_s_l   1101000  00010 . ... . 1010011 @r2_rm
+fcvt_s_lu  1101000  00011 . ... . 1010011 @r2_rm
diff --git a/target/riscv/insn_trans/trans_rvf.inc.c 
b/target/riscv/insn_trans/trans_rvf.inc.c
index 0f837903491b..172dbfa919b6 100644
--- a/target/riscv/insn_trans/trans_rvf.inc.c
+++ b/target/riscv/insn_trans/trans_rvf.inc.c
@@ -377,3 +377,63 @@ static bool trans_fmv_w_x(DisasContext *ctx, arg_fmv_w_x 
*a)
 
 return true;
 }
+
+#ifdef TARGET_RISCV64
+static bool trans_fcvt_l_s(DisasContext *ctx, arg_fcvt_l_s *a)
+{
+REQUIRE_FPU;
+REQUIRE_EXT(ctx, RVF);
+
+TCGv t0 = tcg_temp_new();
+gen_set_rm(ctx, a->rm);
+gen_helper_fcvt_l_s(t0, cpu_env, cpu_fpr[a->rs1]);
+gen_set_gpr(a->rd, t0);
+tcg_temp_free(t0);
+return true;
+}
+
+static bool trans_fcvt_lu_s(DisasContext *ctx, arg_fcvt_lu_s *a)
+{
+REQUIRE_FPU;
+REQUIRE_EXT(ctx, RVF);
+
+TCGv t0 = tcg_temp_new();
+gen_set_rm(ctx, a->rm);
+gen_helper_fcvt_lu_s(t0, cpu_env, cpu_fpr[a->rs1]);
+gen_set_gpr(a->rd, t0);
+tcg_temp_free(t0);
+return true;
+}
+
+static bool trans_fcvt_s_l(DisasContext *ctx, arg_fcvt_s_l *a)
+{
+REQUIRE_FPU;
+REQUIRE_EXT(ctx, RVF);
+
+TCGv t0 = tcg_temp_new();
+gen_get_gpr(t0, a->rs1);
+
+gen_set_rm(ctx, a->rm);
+gen_helper_fcvt_s_l(cpu_fpr[a->rd], cpu_env, t0);
+
+mark_fs_dirty(ctx);
+tcg_temp_free(t0);
+return true;
+}
+
+static bool trans_fcvt_s_lu(DisasContext *ctx, arg_fcvt_s_lu *a)
+{
+REQUIRE_FPU;
+REQUIRE_EXT(ctx, RVF);
+
+TCGv t0 = tcg_temp_new();
+gen_get_gpr(t0, a->rs1);
+
+gen_set_rm(ctx, a->rm);
+gen_helper_fcvt_s_lu(cpu_fpr[a->rd], cpu_env, t0);
+
+mark_fs_dirty(ctx);
+tcg_temp_free(t0);
+return true;
+}
+#endif
-- 
2.19.2




[Qemu-devel] [PULL 15/29] target/riscv: Convert RV priv insns to decodetree

2019-03-13 Thread Palmer Dabbelt
From: Bastian Koppelmann 

Acked-by: Alistair Francis 
Reviewed-by: Richard Henderson 
Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 
---
 target/riscv/insn32.decode|  15 +++
 .../riscv/insn_trans/trans_privileged.inc.c   | 110 ++
 target/riscv/translate.c  |  57 +
 3 files changed, 126 insertions(+), 56 deletions(-)
 create mode 100644 target/riscv/insn_trans/trans_privileged.inc.c

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index e64b2b5e3458..ecc46a50cc27 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -57,6 +57,21 @@
 @r2_rm   ...   . . ... . ... %rs1 %rm %rd
 @r2  ...   . . ... . ... %rs1 %rd
 
+@sfence_vma ... . .   ... . ... %rs2 %rs1
+@sfence_vm  ... . .   ... . ... %rs1
+
+
+# *** Privileged Instructions ***
+ecall   0 000 0 1110011
+ebreak 0001 0 000 0 1110011
+uret   00000010 0 000 0 1110011
+sret   000100000010 0 000 0 1110011
+hret   00100010 0 000 0 1110011
+mret   001100000010 0 000 0 1110011
+wfi000100000101 0 000 0 1110011
+sfence_vma 0001001. . 000 0 1110011 @sfence_vma
+sfence_vm  000100000100 . 000 0 1110011 @sfence_vm
+
 # *** RV32I Base Instruction Set ***
 lui     . 0110111 @u
 auipc   . 0010111 @u
diff --git a/target/riscv/insn_trans/trans_privileged.inc.c 
b/target/riscv/insn_trans/trans_privileged.inc.c
new file mode 100644
index ..acb605923e68
--- /dev/null
+++ b/target/riscv/insn_trans/trans_privileged.inc.c
@@ -0,0 +1,110 @@
+/*
+ * RISC-V translation routines for the RISC-V privileged instructions.
+ *
+ * Copyright (c) 2016-2017 Sagar Karandikar, sag...@eecs.berkeley.edu
+ * Copyright (c) 2018 Peer Adelt, peer.ad...@hni.uni-paderborn.de
+ *Bastian Koppelmann, kbast...@mail.uni-paderborn.de
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see .
+ */
+
+static bool trans_ecall(DisasContext *ctx, arg_ecall *a)
+{
+/* always generates U-level ECALL, fixed in do_interrupt handler */
+generate_exception(ctx, RISCV_EXCP_U_ECALL);
+tcg_gen_exit_tb(NULL, 0); /* no chaining */
+ctx->base.is_jmp = DISAS_NORETURN;
+return true;
+}
+
+static bool trans_ebreak(DisasContext *ctx, arg_ebreak *a)
+{
+generate_exception(ctx, RISCV_EXCP_BREAKPOINT);
+tcg_gen_exit_tb(NULL, 0); /* no chaining */
+ctx->base.is_jmp = DISAS_NORETURN;
+return true;
+}
+
+static bool trans_uret(DisasContext *ctx, arg_uret *a)
+{
+return false;
+}
+
+static bool trans_sret(DisasContext *ctx, arg_sret *a)
+{
+#ifndef CONFIG_USER_ONLY
+tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next);
+
+if (has_ext(ctx, RVS)) {
+gen_helper_sret(cpu_pc, cpu_env, cpu_pc);
+tcg_gen_exit_tb(NULL, 0); /* no chaining */
+ctx->base.is_jmp = DISAS_NORETURN;
+} else {
+return false;
+}
+return true;
+#else
+return false;
+#endif
+}
+
+static bool trans_hret(DisasContext *ctx, arg_hret *a)
+{
+return false;
+}
+
+static bool trans_mret(DisasContext *ctx, arg_mret *a)
+{
+#ifndef CONFIG_USER_ONLY
+tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next);
+gen_helper_mret(cpu_pc, cpu_env, cpu_pc);
+tcg_gen_exit_tb(NULL, 0); /* no chaining */
+ctx->base.is_jmp = DISAS_NORETURN;
+return true;
+#else
+return false;
+#endif
+}
+
+static bool trans_wfi(DisasContext *ctx, arg_wfi *a)
+{
+#ifndef CONFIG_USER_ONLY
+tcg_gen_movi_tl(cpu_pc, ctx->pc_succ_insn);
+gen_helper_wfi(cpu_env);
+return true;
+#else
+return false;
+#endif
+}
+
+static bool trans_sfence_vma(DisasContext *ctx, arg_sfence_vma *a)
+{
+#ifndef CONFIG_USER_ONLY
+if (ctx->priv_ver == PRIV_VERSION_1_10_0) {
+gen_helper_tlb_flush(cpu_env);
+return true;
+}
+#endif
+return false;
+}
+
+static bool trans_sfence_vm(DisasContext *ctx, arg_sfence_vm *a)
+{
+#ifndef CONFIG_USER_ONLY
+if (ctx->priv_ver <= PRIV_VERSION_1_09_1) {
+gen_helper_tlb_flush(cpu_env);
+return true;
+}
+#endif
+return false;
+}
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 2e36deee82f4..02f64ed8a734 100

[Qemu-devel] [PULL 08/29] target/riscv: Convert RVXM insns to decodetree

2019-03-13 Thread Palmer Dabbelt
From: Bastian Koppelmann 

Acked-by: Alistair Francis 
Reviewed-by: Richard Henderson 
Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 
---
 target/riscv/insn32-64.decode   |   7 ++
 target/riscv/insn32.decode  |  10 +++
 target/riscv/insn_trans/trans_rvm.inc.c | 113 
 target/riscv/translate.c|  16 ++--
 4 files changed, 137 insertions(+), 9 deletions(-)
 create mode 100644 target/riscv/insn_trans/trans_rvm.inc.c

diff --git a/target/riscv/insn32-64.decode b/target/riscv/insn32-64.decode
index 9a35f2aa1920..008f1005469e 100644
--- a/target/riscv/insn32-64.decode
+++ b/target/riscv/insn32-64.decode
@@ -36,3 +36,10 @@ subw 010 .  . 000 . 0111011 @r
 sllw 000 .  . 001 . 0111011 @r
 srlw 000 .  . 101 . 0111011 @r
 sraw 010 .  . 101 . 0111011 @r
+
+# *** RV64M Standard Extension (in addition to RV32M) ***
+mulw 001 .  . 000 . 0111011 @r
+divw 001 .  . 100 . 0111011 @r
+divuw001 .  . 101 . 0111011 @r
+remw 001 .  . 110 . 0111011 @r
+remuw001 .  . 111 . 0111011 @r
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 977b1b10a330..e53944bf0e40 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -92,3 +92,13 @@ csrrc . 011 . 1110011 @csr
 csrrwi    . 101 . 1110011 @csr
 csrrsi    . 110 . 1110011 @csr
 csrrci    . 111 . 1110011 @csr
+
+# *** RV32M Standard Extension ***
+mul  001 .  . 000 . 0110011 @r
+mulh 001 .  . 001 . 0110011 @r
+mulhsu   001 .  . 010 . 0110011 @r
+mulhu001 .  . 011 . 0110011 @r
+div  001 .  . 100 . 0110011 @r
+divu 001 .  . 101 . 0110011 @r
+rem  001 .  . 110 . 0110011 @r
+remu 001 .  . 111 . 0110011 @r
diff --git a/target/riscv/insn_trans/trans_rvm.inc.c 
b/target/riscv/insn_trans/trans_rvm.inc.c
new file mode 100644
index ..69631c9e3783
--- /dev/null
+++ b/target/riscv/insn_trans/trans_rvm.inc.c
@@ -0,0 +1,113 @@
+/*
+ * RISC-V translation routines for the RV64M Standard Extension.
+ *
+ * Copyright (c) 2016-2017 Sagar Karandikar, sag...@eecs.berkeley.edu
+ * Copyright (c) 2018 Peer Adelt, peer.ad...@hni.uni-paderborn.de
+ *Bastian Koppelmann, kbast...@mail.uni-paderborn.de
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see .
+ */
+
+
+static bool trans_mul(DisasContext *ctx, arg_mul *a)
+{
+REQUIRE_EXT(ctx, RVM);
+gen_arith(ctx, OPC_RISC_MUL, a->rd, a->rs1, a->rs2);
+return true;
+}
+
+static bool trans_mulh(DisasContext *ctx, arg_mulh *a)
+{
+REQUIRE_EXT(ctx, RVM);
+gen_arith(ctx, OPC_RISC_MULH, a->rd, a->rs1, a->rs2);
+return true;
+}
+
+static bool trans_mulhsu(DisasContext *ctx, arg_mulhsu *a)
+{
+REQUIRE_EXT(ctx, RVM);
+gen_arith(ctx, OPC_RISC_MULHSU, a->rd, a->rs1, a->rs2);
+return true;
+}
+
+static bool trans_mulhu(DisasContext *ctx, arg_mulhu *a)
+{
+REQUIRE_EXT(ctx, RVM);
+gen_arith(ctx, OPC_RISC_MULHU, a->rd, a->rs1, a->rs2);
+return true;
+}
+
+static bool trans_div(DisasContext *ctx, arg_div *a)
+{
+REQUIRE_EXT(ctx, RVM);
+gen_arith(ctx, OPC_RISC_DIV, a->rd, a->rs1, a->rs2);
+return true;
+}
+
+static bool trans_divu(DisasContext *ctx, arg_divu *a)
+{
+REQUIRE_EXT(ctx, RVM);
+gen_arith(ctx, OPC_RISC_DIVU, a->rd, a->rs1, a->rs2);
+return true;
+}
+
+static bool trans_rem(DisasContext *ctx, arg_rem *a)
+{
+REQUIRE_EXT(ctx, RVM);
+gen_arith(ctx, OPC_RISC_REM, a->rd, a->rs1, a->rs2);
+return true;
+}
+
+static bool trans_remu(DisasContext *ctx, arg_remu *a)
+{
+REQUIRE_EXT(ctx, RVM);
+gen_arith(ctx, OPC_RISC_REMU, a->rd, a->rs1, a->rs2);
+return true;
+}
+
+#ifdef TARGET_RISCV64
+static bool trans_mulw(DisasContext *ctx, arg_mulw *a)
+{
+REQUIRE_EXT(ctx, RVM);
+gen_arith(ctx, OPC_RISC_MULW, a->rd, a->rs1, a->rs2);
+return true;
+}
+
+static bool trans_divw(DisasContext *ctx, arg_divw *a)
+{
+REQUIRE_EXT(ctx, RVM);
+gen_arith(ctx, OPC_RISC_DIVW, a->rd, a->rs1, a->rs2);
+return true;
+}
+
+static bool trans_divuw(DisasContext *ctx, arg_di

[Qemu-devel] [PULL 10/29] target/riscv: Convert RV64A insns to decodetree

2019-03-13 Thread Palmer Dabbelt
From: Bastian Koppelmann 

Acked-by: Alistair Francis 
Reviewed-by: Richard Henderson 
Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 
---
 target/riscv/insn32-64.decode   |  13 +++
 target/riscv/insn_trans/trans_rva.inc.c |  58 ++
 target/riscv/translate.c| 144 
 3 files changed, 71 insertions(+), 144 deletions(-)

diff --git a/target/riscv/insn32-64.decode b/target/riscv/insn32-64.decode
index 008f1005469e..0bee95c9840d 100644
--- a/target/riscv/insn32-64.decode
+++ b/target/riscv/insn32-64.decode
@@ -43,3 +43,16 @@ divw 001 .  . 100 . 0111011 @r
 divuw001 .  . 101 . 0111011 @r
 remw 001 .  . 110 . 0111011 @r
 remuw001 .  . 111 . 0111011 @r
+
+# *** RV64A Standard Extension (in addition to RV32A) ***
+lr_d   00010 . . 0 . 011 . 010 @atom_ld
+sc_d   00011 . . . . 011 . 010 @atom_st
+amoswap_d  1 . . . . 011 . 010 @atom_st
+amoadd_d   0 . . . . 011 . 010 @atom_st
+amoxor_d   00100 . . . . 011 . 010 @atom_st
+amoand_d   01100 . . . . 011 . 010 @atom_st
+amoor_d01000 . . . . 011 . 010 @atom_st
+amomin_d   1 . . . . 011 . 010 @atom_st
+amomax_d   10100 . . . . 011 . 010 @atom_st
+amominu_d  11000 . . . . 011 . 010 @atom_st
+amomaxu_d  11100 . . . . 011 . 010 @atom_st
diff --git a/target/riscv/insn_trans/trans_rva.inc.c 
b/target/riscv/insn_trans/trans_rva.inc.c
index 5d3c853ca504..f6dbbc065e15 100644
--- a/target/riscv/insn_trans/trans_rva.inc.c
+++ b/target/riscv/insn_trans/trans_rva.inc.c
@@ -158,3 +158,61 @@ static bool trans_amomaxu_w(DisasContext *ctx, 
arg_amomaxu_w *a)
 REQUIRE_EXT(ctx, RVA);
 return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umax_tl, (MO_ALIGN | 
MO_TESL));
 }
+
+#ifdef TARGET_RISCV64
+
+static bool trans_lr_d(DisasContext *ctx, arg_lr_d *a)
+{
+return gen_lr(ctx, a, MO_ALIGN | MO_TEQ);
+}
+
+static bool trans_sc_d(DisasContext *ctx, arg_sc_d *a)
+{
+return gen_sc(ctx, a, (MO_ALIGN | MO_TEQ));
+}
+
+static bool trans_amoswap_d(DisasContext *ctx, arg_amoswap_d *a)
+{
+return gen_amo(ctx, a, &tcg_gen_atomic_xchg_tl, (MO_ALIGN | MO_TEQ));
+}
+
+static bool trans_amoadd_d(DisasContext *ctx, arg_amoadd_d *a)
+{
+return gen_amo(ctx, a, &tcg_gen_atomic_fetch_add_tl, (MO_ALIGN | MO_TEQ));
+}
+
+static bool trans_amoxor_d(DisasContext *ctx, arg_amoxor_d *a)
+{
+return gen_amo(ctx, a, &tcg_gen_atomic_fetch_xor_tl, (MO_ALIGN | MO_TEQ));
+}
+
+static bool trans_amoand_d(DisasContext *ctx, arg_amoand_d *a)
+{
+return gen_amo(ctx, a, &tcg_gen_atomic_fetch_and_tl, (MO_ALIGN | MO_TEQ));
+}
+
+static bool trans_amoor_d(DisasContext *ctx, arg_amoor_d *a)
+{
+return gen_amo(ctx, a, &tcg_gen_atomic_fetch_or_tl, (MO_ALIGN | MO_TEQ));
+}
+
+static bool trans_amomin_d(DisasContext *ctx, arg_amomin_d *a)
+{
+return gen_amo(ctx, a, &tcg_gen_atomic_fetch_smin_tl, (MO_ALIGN | MO_TEQ));
+}
+
+static bool trans_amomax_d(DisasContext *ctx, arg_amomax_d *a)
+{
+return gen_amo(ctx, a, &tcg_gen_atomic_fetch_smax_tl, (MO_ALIGN | MO_TEQ));
+}
+
+static bool trans_amominu_d(DisasContext *ctx, arg_amominu_d *a)
+{
+return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umin_tl, (MO_ALIGN | MO_TEQ));
+}
+
+static bool trans_amomaxu_d(DisasContext *ctx, arg_amomaxu_d *a)
+{
+return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umax_tl, (MO_ALIGN | MO_TEQ));
+}
+#endif
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index b0de062a4fd1..c2791459993e 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -794,143 +794,6 @@ static void gen_fp_store(DisasContext *ctx, uint32_t opc, 
int rs1,
 tcg_temp_free(t0);
 }
 
-static void gen_atomic(DisasContext *ctx, uint32_t opc,
-  int rd, int rs1, int rs2)
-{
-TCGv src1, src2, dat;
-TCGLabel *l1, *l2;
-TCGMemOp mop;
-bool aq, rl;
-
-/* Extract the size of the atomic operation.  */
-switch (extract32(opc, 12, 3)) {
-case 2: /* 32-bit */
-mop = MO_ALIGN | MO_TESL;
-break;
-#if defined(TARGET_RISCV64)
-case 3: /* 64-bit */
-mop = MO_ALIGN | MO_TEQ;
-break;
-#endif
-default:
-gen_exception_illegal(ctx);
-return;
-}
-rl = extract32(opc, 25, 1);
-aq = extract32(opc, 26, 1);
-
-src1 = tcg_temp_new();
-src2 = tcg_temp_new();
-
-switch (MASK_OP_ATOMIC_NO_AQ_RL_SZ(opc)) {
-case OPC_RISC_LR:
-/* Put addr in load_res, data in load_val.  */
-gen_get_gpr(src1, rs1);
-if (rl) {
-tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
-}
-tcg_gen_qemu_ld_tl(load_val, src1, ctx->mem_idx, mop);
-if (aq) {
-tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
-}
-tcg_gen_mov_tl(load_res, src1);
-gen_

[Qemu-devel] [PULL 07/29] target/riscv: Convert RVXI csr insns to decodetree

2019-03-13 Thread Palmer Dabbelt
From: Bastian Koppelmann 

Acked-by: Alistair Francis 
Reviewed-by: Richard Henderson 
Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 
---
 target/riscv/insn32.decode  |  8 +++
 target/riscv/insn_trans/trans_rvi.inc.c | 79 +
 target/riscv/translate.c| 43 +-
 3 files changed, 88 insertions(+), 42 deletions(-)

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 804b721ca51e..977b1b10a330 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -22,6 +22,7 @@
 %rd7:5
 
 %sh1020:10
+%csr20:12
 
 # immediates:
 %imm_i20:s12
@@ -43,6 +44,7 @@
 @j     . ... imm=%imm_j  
%rd
 
 @sh  ..  .. .  ... . ... &shift  shamt=%sh10  %rs1 
%rd
+@csr    .  ... . ...   %csr %rs1 
%rd
 
 # *** RV32I Base Instruction Set ***
 lui     . 0110111 @u
@@ -84,3 +86,9 @@ or   000 .. 110 . 0110011 @r
 and  000 .. 111 . 0110011 @r
 fence pred:4 succ:4 - 000 - 000
 fence_i         - 001 - 000
+csrrw . 001 . 1110011 @csr
+csrrs . 010 . 1110011 @csr
+csrrc . 011 . 1110011 @csr
+csrrwi    . 101 . 1110011 @csr
+csrrsi    . 110 . 1110011 @csr
+csrrci    . 111 . 1110011 @csr
diff --git a/target/riscv/insn_trans/trans_rvi.inc.c 
b/target/riscv/insn_trans/trans_rvi.inc.c
index 973d6371df85..4a23372cb823 100644
--- a/target/riscv/insn_trans/trans_rvi.inc.c
+++ b/target/riscv/insn_trans/trans_rvi.inc.c
@@ -337,3 +337,82 @@ static bool trans_fence_i(DisasContext *ctx, arg_fence_i 
*a)
 ctx->base.is_jmp = DISAS_NORETURN;
 return true;
 }
+
+#define RISCV_OP_CSR_PRE do {\
+source1 = tcg_temp_new(); \
+csr_store = tcg_temp_new(); \
+dest = tcg_temp_new(); \
+rs1_pass = tcg_temp_new(); \
+gen_get_gpr(source1, a->rs1); \
+tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next); \
+tcg_gen_movi_tl(rs1_pass, a->rs1); \
+tcg_gen_movi_tl(csr_store, a->csr); \
+gen_io_start();\
+} while (0)
+
+#define RISCV_OP_CSR_POST do {\
+gen_io_end(); \
+gen_set_gpr(a->rd, dest); \
+tcg_gen_movi_tl(cpu_pc, ctx->pc_succ_insn); \
+tcg_gen_exit_tb(NULL, 0); \
+ctx->base.is_jmp = DISAS_NORETURN; \
+tcg_temp_free(source1); \
+tcg_temp_free(csr_store); \
+tcg_temp_free(dest); \
+tcg_temp_free(rs1_pass); \
+} while (0)
+
+
+static bool trans_csrrw(DisasContext *ctx, arg_csrrw *a)
+{
+TCGv source1, csr_store, dest, rs1_pass;
+RISCV_OP_CSR_PRE;
+gen_helper_csrrw(dest, cpu_env, source1, csr_store);
+RISCV_OP_CSR_POST;
+return true;
+}
+
+static bool trans_csrrs(DisasContext *ctx, arg_csrrs *a)
+{
+TCGv source1, csr_store, dest, rs1_pass;
+RISCV_OP_CSR_PRE;
+gen_helper_csrrs(dest, cpu_env, source1, csr_store, rs1_pass);
+RISCV_OP_CSR_POST;
+return true;
+}
+
+static bool trans_csrrc(DisasContext *ctx, arg_csrrc *a)
+{
+TCGv source1, csr_store, dest, rs1_pass;
+RISCV_OP_CSR_PRE;
+gen_helper_csrrc(dest, cpu_env, source1, csr_store, rs1_pass);
+RISCV_OP_CSR_POST;
+return true;
+}
+
+static bool trans_csrrwi(DisasContext *ctx, arg_csrrwi *a)
+{
+TCGv source1, csr_store, dest, rs1_pass;
+RISCV_OP_CSR_PRE;
+gen_helper_csrrw(dest, cpu_env, rs1_pass, csr_store);
+RISCV_OP_CSR_POST;
+return true;
+}
+
+static bool trans_csrrsi(DisasContext *ctx, arg_csrrsi *a)
+{
+TCGv source1, csr_store, dest, rs1_pass;
+RISCV_OP_CSR_PRE;
+gen_helper_csrrs(dest, cpu_env, rs1_pass, csr_store, rs1_pass);
+RISCV_OP_CSR_POST;
+return true;
+}
+
+static bool trans_csrrci(DisasContext *ctx, arg_csrrci *a)
+{
+TCGv source1, csr_store, dest, rs1_pass;
+RISCV_OP_CSR_PRE;
+gen_helper_csrrc(dest, cpu_env, rs1_pass, csr_store, rs1_pass);
+RISCV_OP_CSR_POST;
+return true;
+}
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index f720746cb791..18555000af35 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -1476,16 +1476,11 @@ static void gen_fp_arith(DisasContext *ctx, uint32_t 
opc, int rd,
 static void gen_system(DisasContext *ctx, uint32_t opc, int rd, int rs1,
int csr)
 {
-TCGv source1, csr_store, dest, rs1_pass, imm_rs1;
+TCGv source1, dest;
 source1 = tcg_temp_new();
-csr_store = tcg_temp_new();
 dest = tcg_temp_new();
-rs1_pass = tcg_temp_new();
-imm_rs1 = tcg_temp_new();
 gen_get_gpr(source1, rs1);
 tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next);
-tcg_gen_movi_tl(rs1_pass, rs1);
-tcg_gen_movi_tl(csr_store, csr); /* copy into temp reg to feed to helper */
 
 #ifndef CONFIG_USER_ONLY
 /* Extr

[Qemu-devel] [PULL 09/29] target/riscv: Convert RV32A insns to decodetree

2019-03-13 Thread Palmer Dabbelt
From: Bastian Koppelmann 

Acked-by: Alistair Francis 
Reviewed-by: Richard Henderson 
Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 
---
 target/riscv/insn32.decode  |  17 +++
 target/riscv/insn_trans/trans_rva.inc.c | 160 
 target/riscv/translate.c|   1 +
 3 files changed, 178 insertions(+)
 create mode 100644 target/riscv/insn_trans/trans_rva.inc.c

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index e53944bf0e40..00b9e2d9a508 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -34,6 +34,7 @@
 # Argument sets:
 &bimm rs2 rs1
 &shift shamt rs1 rd
+&atomicaq rl rs2 rs1 rd
 
 # Formats 32:
 @r   ...   . . ... . ...   %rs2 %rs1 
%rd
@@ -46,6 +47,9 @@
 @sh  ..  .. .  ... . ... &shift  shamt=%sh10  %rs1 
%rd
 @csr    .  ... . ...   %csr %rs1 
%rd
 
+@atom_ld . aq:1 rl:1 .  . ... &atomic rs2=0 %rs1 
%rd
+@atom_st . aq:1 rl:1 .  . ... &atomic %rs2  %rs1 
%rd
+
 # *** RV32I Base Instruction Set ***
 lui     . 0110111 @u
 auipc   . 0010111 @u
@@ -102,3 +106,16 @@ div  001 .  . 100 . 0110011 @r
 divu 001 .  . 101 . 0110011 @r
 rem  001 .  . 110 . 0110011 @r
 remu 001 .  . 111 . 0110011 @r
+
+# *** RV32A Standard Extension ***
+lr_w   00010 . . 0 . 010 . 010 @atom_ld
+sc_w   00011 . . . . 010 . 010 @atom_st
+amoswap_w  1 . . . . 010 . 010 @atom_st
+amoadd_w   0 . . . . 010 . 010 @atom_st
+amoxor_w   00100 . . . . 010 . 010 @atom_st
+amoand_w   01100 . . . . 010 . 010 @atom_st
+amoor_w01000 . . . . 010 . 010 @atom_st
+amomin_w   1 . . . . 010 . 010 @atom_st
+amomax_w   10100 . . . . 010 . 010 @atom_st
+amominu_w  11000 . . . . 010 . 010 @atom_st
+amomaxu_w  11100 . . . . 010 . 010 @atom_st
diff --git a/target/riscv/insn_trans/trans_rva.inc.c 
b/target/riscv/insn_trans/trans_rva.inc.c
new file mode 100644
index ..5d3c853ca504
--- /dev/null
+++ b/target/riscv/insn_trans/trans_rva.inc.c
@@ -0,0 +1,160 @@
+/*
+ * RISC-V translation routines for the RV64A Standard Extension.
+ *
+ * Copyright (c) 2016-2017 Sagar Karandikar, sag...@eecs.berkeley.edu
+ * Copyright (c) 2018 Peer Adelt, peer.ad...@hni.uni-paderborn.de
+ *Bastian Koppelmann, kbast...@mail.uni-paderborn.de
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see .
+ */
+
+static inline bool gen_lr(DisasContext *ctx, arg_atomic *a, TCGMemOp mop)
+{
+TCGv src1 = tcg_temp_new();
+/* Put addr in load_res, data in load_val.  */
+gen_get_gpr(src1, a->rs1);
+if (a->rl) {
+tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
+}
+tcg_gen_qemu_ld_tl(load_val, src1, ctx->mem_idx, mop);
+if (a->aq) {
+tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
+}
+tcg_gen_mov_tl(load_res, src1);
+gen_set_gpr(a->rd, load_val);
+
+tcg_temp_free(src1);
+return true;
+}
+
+static inline bool gen_sc(DisasContext *ctx, arg_atomic *a, TCGMemOp mop)
+{
+TCGv src1 = tcg_temp_new();
+TCGv src2 = tcg_temp_new();
+TCGv dat = tcg_temp_new();
+TCGLabel *l1 = gen_new_label();
+TCGLabel *l2 = gen_new_label();
+
+gen_get_gpr(src1, a->rs1);
+tcg_gen_brcond_tl(TCG_COND_NE, load_res, src1, l1);
+
+gen_get_gpr(src2, a->rs2);
+/*
+ * Note that the TCG atomic primitives are SC,
+ * so we can ignore AQ/RL along this path.
+ */
+tcg_gen_atomic_cmpxchg_tl(src1, load_res, load_val, src2,
+  ctx->mem_idx, mop);
+tcg_gen_setcond_tl(TCG_COND_NE, dat, src1, load_val);
+gen_set_gpr(a->rd, dat);
+tcg_gen_br(l2);
+
+gen_set_label(l1);
+/*
+ * Address comparion failure.  However, we still need to
+ * provide the memory barrier implied by AQ/RL.
+ */
+tcg_gen_mb(TCG_MO_ALL + a->aq * TCG_BAR_LDAQ + a->rl * TCG_BAR_STRL);
+tcg_gen_movi_tl(dat, 1);
+gen_set_gpr(a->rd, dat);
+
+gen_set_label(l2);
+tcg_temp_free(dat);
+tcg_temp_free(src1);
+t

[Qemu-devel] [PULL 06/29] target/riscv: Convert RVXI fence insns to decodetree

2019-03-13 Thread Palmer Dabbelt
From: Bastian Koppelmann 

Acked-by: Alistair Francis 
Reviewed-by: Richard Henderson 
Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 
---
 target/riscv/insn32.decode  |  2 ++
 target/riscv/insn_trans/trans_rvi.inc.c | 19 +++
 target/riscv/translate.c| 12 
 3 files changed, 21 insertions(+), 12 deletions(-)

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 1f5bf1f6f97d..804b721ca51e 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -82,3 +82,5 @@ srl  000 .. 101 . 0110011 @r
 sra  010 .. 101 . 0110011 @r
 or   000 .. 110 . 0110011 @r
 and  000 .. 111 . 0110011 @r
+fence pred:4 succ:4 - 000 - 000
+fence_i         - 001 - 000
diff --git a/target/riscv/insn_trans/trans_rvi.inc.c 
b/target/riscv/insn_trans/trans_rvi.inc.c
index 136fa54d0655..973d6371df85 100644
--- a/target/riscv/insn_trans/trans_rvi.inc.c
+++ b/target/riscv/insn_trans/trans_rvi.inc.c
@@ -318,3 +318,22 @@ static bool trans_sraw(DisasContext *ctx, arg_sraw *a)
 return true;
 }
 #endif
+
+static bool trans_fence(DisasContext *ctx, arg_fence *a)
+{
+/* FENCE is a full memory barrier. */
+tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
+return true;
+}
+
+static bool trans_fence_i(DisasContext *ctx, arg_fence_i *a)
+{
+/*
+ * FENCE_I is a no-op in QEMU,
+ * however we need to end the translation block
+ */
+tcg_gen_movi_tl(cpu_pc, ctx->pc_succ_insn);
+tcg_gen_exit_tb(NULL, 0);
+ctx->base.is_jmp = DISAS_NORETURN;
+return true;
+}
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 1ae84dcd5992..f720746cb791 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -1950,18 +1950,6 @@ static void decode_RV32_64G(DisasContext *ctx)
 gen_fp_arith(ctx, MASK_OP_FP_ARITH(ctx->opcode), rd, rs1, rs2,
  GET_RM(ctx->opcode));
 break;
-case OPC_RISC_FENCE:
-if (ctx->opcode & 0x1000) {
-/* FENCE_I is a no-op in QEMU,
- * however we need to end the translation block */
-tcg_gen_movi_tl(cpu_pc, ctx->pc_succ_insn);
-tcg_gen_exit_tb(NULL, 0);
-ctx->base.is_jmp = DISAS_NORETURN;
-} else {
-/* FENCE is a full memory barrier. */
-tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
-}
-break;
 case OPC_RISC_SYSTEM:
 gen_system(ctx, MASK_OP_SYSTEM(ctx->opcode), rd, rs1,
(ctx->opcode & 0xFFF0) >> 20);
-- 
2.19.2




[Qemu-devel] [PULL 01/29] target/riscv: Activate decodetree and implemnt LUI & AUIPC

2019-03-13 Thread Palmer Dabbelt
From: Bastian Koppelmann 

for now only LUI & AUIPC are decoded and translated. If decodetree fails, we
fall back to the old decoder.

Reviewed-by: Richard Henderson 
Acked-by: Alistair Francis 
Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 
---
 target/riscv/Makefile.objs  | 10 +++
 target/riscv/insn32.decode  | 30 +
 target/riscv/insn_trans/trans_rvi.inc.c | 35 +
 target/riscv/translate.c| 31 --
 4 files changed, 92 insertions(+), 14 deletions(-)
 create mode 100644 target/riscv/insn32.decode
 create mode 100644 target/riscv/insn_trans/trans_rvi.inc.c

diff --git a/target/riscv/Makefile.objs b/target/riscv/Makefile.objs
index 4072abe3e45c..bf0a268033a0 100644
--- a/target/riscv/Makefile.objs
+++ b/target/riscv/Makefile.objs
@@ -1 +1,11 @@
 obj-y += translate.o op_helper.o cpu_helper.o cpu.o csr.o fpu_helper.o 
gdbstub.o pmp.o
+
+DECODETREE = $(SRC_PATH)/scripts/decodetree.py
+
+target/riscv/decode_insn32.inc.c: \
+  $(SRC_PATH)/target/riscv/insn32.decode $(DECODETREE)
+   $(call quiet-command, \
+ $(PYTHON) $(DECODETREE) -o $@ --decode decode_insn32 $<, \
+ "GEN", $(TARGET_DIR)$@)
+
+target/riscv/translate.o: target/riscv/decode_insn32.inc.c
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
new file mode 100644
index ..44d4e922b6fa
--- /dev/null
+++ b/target/riscv/insn32.decode
@@ -0,0 +1,30 @@
+#
+# RISC-V translation routines for the RVXI Base Integer Instruction Set.
+#
+# Copyright (c) 2018 Peer Adelt, peer.ad...@hni.uni-paderborn.de
+#Bastian Koppelmann, kbast...@mail.uni-paderborn.de
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms and conditions of the GNU General Public License,
+# version 2 or later, as published by the Free Software Foundation.
+#
+# This program is distributed in the hope it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+# more details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program.  If not, see .
+
+# Fields:
+%rd7:5
+
+# immediates:
+%imm_u12:s20 !function=ex_shift_12
+
+# Formats 32:
+@u     . ... imm=%imm_u  
%rd
+
+# *** RV32I Base Instruction Set ***
+lui     . 0110111 @u
+auipc   . 0010111 @u
diff --git a/target/riscv/insn_trans/trans_rvi.inc.c 
b/target/riscv/insn_trans/trans_rvi.inc.c
new file mode 100644
index ..9885a8d27551
--- /dev/null
+++ b/target/riscv/insn_trans/trans_rvi.inc.c
@@ -0,0 +1,35 @@
+/*
+ * RISC-V translation routines for the RVXI Base Integer Instruction Set.
+ *
+ * Copyright (c) 2016-2017 Sagar Karandikar, sag...@eecs.berkeley.edu
+ * Copyright (c) 2018 Peer Adelt, peer.ad...@hni.uni-paderborn.de
+ *Bastian Koppelmann, kbast...@mail.uni-paderborn.de
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see .
+ */
+
+static bool trans_lui(DisasContext *ctx, arg_lui *a)
+{
+if (a->rd != 0) {
+tcg_gen_movi_tl(cpu_gpr[a->rd], a->imm);
+}
+return true;
+}
+
+static bool trans_auipc(DisasContext *ctx, arg_auipc *a)
+{
+if (a->rd != 0) {
+tcg_gen_movi_tl(cpu_gpr[a->rd], a->imm + ctx->base.pc_next);
+}
+return true;
+}
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index b7176cbf98e1..a273ac827448 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -1874,6 +1874,19 @@ static void decode_RV32_64C(DisasContext *ctx)
 }
 }
 
+#define EX_SH(amount) \
+static int ex_shift_##amount(int imm) \
+{ \
+return imm << amount; \
+}
+EX_SH(12)
+
+bool decode_insn32(DisasContext *ctx, uint32_t insn);
+/* Include the auto-generated decoder for 32 bit insn */
+#include "decode_insn32.inc.c"
+/* Include insn module translation function */
+#include "insn_trans/trans_rvi.inc.c"
+
 static void decode_RV32_64G(DisasContext *ctx)
 {
 int rs1;
@@ -1894,19 +1907,6 @@ static void decode_RV32_64G(DisasContext *ctx)
 imm = GET_IMM(ctx->opcode);
 

[Qemu-devel] [PULL 05/29] target/riscv: Convert RVXI arithmetic insns to decodetree

2019-03-13 Thread Palmer Dabbelt
From: Bastian Koppelmann 

we cannot remove the call to gen_arith() in decode_RV32_64G() since it
is used to translate multiply instructions.

Acked-by: Alistair Francis 
Reviewed-by: Richard Henderson 
Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 
---
 target/riscv/insn32-64.decode   |  13 ++
 target/riscv/insn32.decode  |  25 
 target/riscv/insn_trans/trans_rvi.inc.c | 168 
 target/riscv/translate.c|   9 --
 4 files changed, 206 insertions(+), 9 deletions(-)

diff --git a/target/riscv/insn32-64.decode b/target/riscv/insn32-64.decode
index 439d4e2c587b..9a35f2aa1920 100644
--- a/target/riscv/insn32-64.decode
+++ b/target/riscv/insn32-64.decode
@@ -19,7 +19,20 @@
 # This is concatenated with insn32.decode for risc64 targets.
 # Most of the fields and formats are there.
 
+%sh520:5
+
+@sh5 ...  . .  ... . ... &shift  shamt=%sh5  %rs1 
%rd
+
 # *** RV64I Base Instruction Set (in addition to RV32I) ***
 lwu     . 110 . 011 @i
 ld      . 011 . 011 @i
 sd   ... .  . 011 . 0100011 @s
+addiw   . 000 . 0011011 @i
+slliw000 .  . 001 . 0011011 @sh5
+srliw000 .  . 101 . 0011011 @sh5
+sraiw010 .  . 101 . 0011011 @sh5
+addw 000 .  . 000 . 0111011 @r
+subw 010 .  . 000 . 0111011 @r
+sllw 000 .  . 001 . 0111011 @r
+srlw 000 .  . 101 . 0111011 @r
+sraw 010 .  . 101 . 0111011 @r
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 076de873c4f1..1f5bf1f6f97d 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -21,6 +21,8 @@
 %rs1   15:5
 %rd7:5
 
+%sh1020:10
+
 # immediates:
 %imm_i20:s12
 %imm_s25:s7 7:5
@@ -30,14 +32,18 @@
 
 # Argument sets:
 &bimm rs2 rs1
+&shift shamt rs1 rd
 
 # Formats 32:
+@r   ...   . . ... . ...   %rs2 %rs1 
%rd
 @i   . ... . ... imm=%imm_i %rs1 
%rd
 @b   ...   . . ... . ... &b  imm=%imm_b %rs2 %rs1
 @s   ...   . . ... . ... imm=%imm_s %rs2 %rs1
 @u     . ... imm=%imm_u  
%rd
 @j     . ... imm=%imm_j  
%rd
 
+@sh  ..  .. .  ... . ... &shift  shamt=%sh10  %rs1 
%rd
+
 # *** RV32I Base Instruction Set ***
 lui     . 0110111 @u
 auipc   . 0010111 @u
@@ -57,3 +63,22 @@ lhu   . 101 . 011 @i
 sb   ...  .   . 000 . 0100011 @s
 sh   ...  .   . 001 . 0100011 @s
 sw   ...  .   . 010 . 0100011 @s
+addi  . 000 . 0010011 @i
+slti  . 010 . 0010011 @i
+sltiu . 011 . 0010011 @i
+xori  . 100 . 0010011 @i
+ori   . 110 . 0010011 @i
+andi  . 111 . 0010011 @i
+slli 00 ... 001 . 0010011 @sh
+srli 00 ... 101 . 0010011 @sh
+srai 01 ... 101 . 0010011 @sh
+add  000 .. 000 . 0110011 @r
+sub  010 .. 000 . 0110011 @r
+sll  000 .. 001 . 0110011 @r
+slt  000 .. 010 . 0110011 @r
+sltu 000 .. 011 . 0110011 @r
+xor  000 .. 100 . 0110011 @r
+srl  000 .. 101 . 0110011 @r
+sra  010 .. 101 . 0110011 @r
+or   000 .. 110 . 0110011 @r
+and  000 .. 111 . 0110011 @r
diff --git a/target/riscv/insn_trans/trans_rvi.inc.c 
b/target/riscv/insn_trans/trans_rvi.inc.c
index 61f708dba144..136fa54d0655 100644
--- a/target/riscv/insn_trans/trans_rvi.inc.c
+++ b/target/riscv/insn_trans/trans_rvi.inc.c
@@ -150,3 +150,171 @@ static bool trans_sd(DisasContext *ctx, arg_sd *a)
 return true;
 }
 #endif
+
+static bool trans_addi(DisasContext *ctx, arg_addi *a)
+{
+gen_arith_imm(ctx, OPC_RISC_ADDI, a->rd, a->rs1, a->imm);
+return true;
+}
+
+static bool trans_slti(DisasContext *ctx, arg_slti *a)
+{
+gen_arith_imm(ctx, OPC_RISC_SLTI, a->rd, a->rs1, a->imm);
+return true;
+}
+
+static bool trans_sltiu(DisasContext *ctx, arg_sltiu *a)
+{
+gen_arith_imm(ctx, OPC_RISC_SLTIU, a->rd, a->rs1, a->imm);
+return true;
+}
+
+static bool trans_xori(DisasContext *ctx, arg_xori *a)
+{
+gen_arith_imm(ctx, OPC_RISC_XORI, a->rd, a->rs1, a->imm);
+return true;
+}
+static bool trans_ori(DisasContext *ctx, 

[Qemu-devel] [PULL 04/29] target/riscv: Convert RV64I load/store insns to decodetree

2019-03-13 Thread Palmer Dabbelt
From: Bastian Koppelmann 

this splits the 64-bit only instructions into its own decode file such
that we generate the decoder for these instructions only for the RISC-V
64 bit target.

Acked-by: Alistair Francis 
Reviewed-by: Richard Henderson 
Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 
---
 target/riscv/Makefile.objs  |  8 +---
 target/riscv/insn32-64.decode   | 25 +
 target/riscv/insn_trans/trans_rvi.inc.c | 20 
 target/riscv/translate.c|  7 ---
 4 files changed, 50 insertions(+), 10 deletions(-)
 create mode 100644 target/riscv/insn32-64.decode

diff --git a/target/riscv/Makefile.objs b/target/riscv/Makefile.objs
index bf0a268033a0..05087a91bb85 100644
--- a/target/riscv/Makefile.objs
+++ b/target/riscv/Makefile.objs
@@ -2,10 +2,12 @@ obj-y += translate.o op_helper.o cpu_helper.o cpu.o csr.o 
fpu_helper.o gdbstub.o
 
 DECODETREE = $(SRC_PATH)/scripts/decodetree.py
 
-target/riscv/decode_insn32.inc.c: \
-  $(SRC_PATH)/target/riscv/insn32.decode $(DECODETREE)
+decode32-y = $(SRC_PATH)/target/riscv/insn32.decode
+decode32-$(TARGET_RISCV64) += $(SRC_PATH)/target/riscv/insn32-64.decode
+
+target/riscv/decode_insn32.inc.c: $(decode32-y) $(DECODETREE)
$(call quiet-command, \
- $(PYTHON) $(DECODETREE) -o $@ --decode decode_insn32 $<, \
+ $(PYTHON) $(DECODETREE) -o $@ --decode decode_insn32 $(decode32-y), \
  "GEN", $(TARGET_DIR)$@)
 
 target/riscv/translate.o: target/riscv/decode_insn32.inc.c
diff --git a/target/riscv/insn32-64.decode b/target/riscv/insn32-64.decode
new file mode 100644
index ..439d4e2c587b
--- /dev/null
+++ b/target/riscv/insn32-64.decode
@@ -0,0 +1,25 @@
+#
+# RISC-V translation routines for the RV Instruction Set.
+#
+# Copyright (c) 2018 Peer Adelt, peer.ad...@hni.uni-paderborn.de
+#Bastian Koppelmann, kbast...@mail.uni-paderborn.de
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms and conditions of the GNU General Public License,
+# version 2 or later, as published by the Free Software Foundation.
+#
+# This program is distributed in the hope it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+# more details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program.  If not, see .
+
+# This is concatenated with insn32.decode for risc64 targets.
+# Most of the fields and formats are there.
+
+# *** RV64I Base Instruction Set (in addition to RV32I) ***
+lwu     . 110 . 011 @i
+ld      . 011 . 011 @i
+sd   ... .  . 011 . 0100011 @s
diff --git a/target/riscv/insn_trans/trans_rvi.inc.c 
b/target/riscv/insn_trans/trans_rvi.inc.c
index d13b7b2b6d8f..61f708dba144 100644
--- a/target/riscv/insn_trans/trans_rvi.inc.c
+++ b/target/riscv/insn_trans/trans_rvi.inc.c
@@ -130,3 +130,23 @@ static bool trans_sw(DisasContext *ctx, arg_sw *a)
 gen_store(ctx, OPC_RISC_SW, a->rs1, a->rs2, a->imm);
 return true;
 }
+
+#ifdef TARGET_RISCV64
+static bool trans_lwu(DisasContext *ctx, arg_lwu *a)
+{
+gen_load(ctx, OPC_RISC_LWU, a->rd, a->rs1, a->imm);
+return true;
+}
+
+static bool trans_ld(DisasContext *ctx, arg_ld *a)
+{
+gen_load(ctx, OPC_RISC_LD, a->rd, a->rs1, a->imm);
+return true;
+}
+
+static bool trans_sd(DisasContext *ctx, arg_sd *a)
+{
+gen_store(ctx, OPC_RISC_SD, a->rs1, a->rs2, a->imm);
+return true;
+}
+#endif
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index fb284a5e08d6..2e35142ca2a4 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -1908,13 +1908,6 @@ static void decode_RV32_64G(DisasContext *ctx)
 imm = GET_IMM(ctx->opcode);
 
 switch (op) {
-case OPC_RISC_LOAD:
-gen_load(ctx, MASK_OP_LOAD(ctx->opcode), rd, rs1, imm);
-break;
-case OPC_RISC_STORE:
-gen_store(ctx, MASK_OP_STORE(ctx->opcode), rs1, rs2,
-  GET_STORE_IMM(ctx->opcode));
-break;
 case OPC_RISC_ARITH_IMM:
 #if defined(TARGET_RISCV64)
 case OPC_RISC_ARITH_IMM_W:
-- 
2.19.2




[Qemu-devel] [PULL 02/29] target/riscv: Convert RVXI branch insns to decodetree

2019-03-13 Thread Palmer Dabbelt
From: Bastian Koppelmann 

Acked-by: Alistair Francis 
Reviewed-by: Palmer Dabbelt 
Reviewed-by: Richard Henderson 
Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 
---
 target/riscv/insn32.decode  | 19 ++
 target/riscv/insn_trans/trans_rvi.inc.c | 49 +
 target/riscv/translate.c| 12 +-
 3 files changed, 69 insertions(+), 11 deletions(-)

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 44d4e922b6fa..81f56c16b45f 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -17,14 +17,33 @@
 # this program.  If not, see <http://www.gnu.org/licenses/>.
 
 # Fields:
+%rs2   20:5
+%rs1   15:5
 %rd7:5
 
 # immediates:
+%imm_i20:s12
+%imm_b31:s1 7:1 25:6 8:4 !function=ex_shift_1
+%imm_j31:s1 12:8 20:1 21:10  !function=ex_shift_1
 %imm_u12:s20 !function=ex_shift_12
 
+# Argument sets:
+&bimm rs2 rs1
+
 # Formats 32:
+@i   . ... . ... imm=%imm_i %rs1 
%rd
+@b   ...   . . ... . ... &b  imm=%imm_b %rs2 %rs1
 @u     . ... imm=%imm_u  
%rd
+@j     . ... imm=%imm_j  
%rd
 
 # *** RV32I Base Instruction Set ***
 lui     . 0110111 @u
 auipc   . 0010111 @u
+jal     . 110 @j
+jalr  . 000 . 1100111 @i
+beq  ... .. 000 . 1100011 @b
+bne  ... .. 001 . 1100011 @b
+blt  ... .. 100 . 1100011 @b
+bge  ... .. 101 . 1100011 @b
+bltu ... .. 110 . 1100011 @b
+bgeu ... .. 111 . 1100011 @b
diff --git a/target/riscv/insn_trans/trans_rvi.inc.c 
b/target/riscv/insn_trans/trans_rvi.inc.c
index 9885a8d27551..bcf20def50eb 100644
--- a/target/riscv/insn_trans/trans_rvi.inc.c
+++ b/target/riscv/insn_trans/trans_rvi.inc.c
@@ -33,3 +33,52 @@ static bool trans_auipc(DisasContext *ctx, arg_auipc *a)
 }
 return true;
 }
+
+static bool trans_jal(DisasContext *ctx, arg_jal *a)
+{
+gen_jal(ctx, a->rd, a->imm);
+return true;
+}
+
+static bool trans_jalr(DisasContext *ctx, arg_jalr *a)
+{
+gen_jalr(ctx, OPC_RISC_JALR, a->rd, a->rs1, a->imm);
+return true;
+}
+
+static bool trans_beq(DisasContext *ctx, arg_beq *a)
+{
+gen_branch(ctx, OPC_RISC_BEQ, a->rs1, a->rs2, a->imm);
+return true;
+}
+
+static bool trans_bne(DisasContext *ctx, arg_bne *a)
+{
+gen_branch(ctx, OPC_RISC_BNE, a->rs1, a->rs2, a->imm);
+return true;
+}
+
+static bool trans_blt(DisasContext *ctx, arg_blt *a)
+{
+gen_branch(ctx, OPC_RISC_BLT, a->rs1, a->rs2, a->imm);
+return true;
+}
+
+static bool trans_bge(DisasContext *ctx, arg_bge *a)
+{
+gen_branch(ctx, OPC_RISC_BGE, a->rs1, a->rs2, a->imm);
+return true;
+}
+
+static bool trans_bltu(DisasContext *ctx, arg_bltu *a)
+{
+gen_branch(ctx, OPC_RISC_BLTU, a->rs1, a->rs2, a->imm);
+return true;
+}
+
+static bool trans_bgeu(DisasContext *ctx, arg_bgeu *a)
+{
+
+gen_branch(ctx, OPC_RISC_BGEU, a->rs1, a->rs2, a->imm);
+return true;
+}
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index a273ac827448..fb284a5e08d6 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -1879,6 +1879,7 @@ static void decode_RV32_64C(DisasContext *ctx)
 { \
 return imm << amount; \
 }
+EX_SH(1)
 EX_SH(12)
 
 bool decode_insn32(DisasContext *ctx, uint32_t insn);
@@ -1907,17 +1908,6 @@ static void decode_RV32_64G(DisasContext *ctx)
 imm = GET_IMM(ctx->opcode);
 
 switch (op) {
-case OPC_RISC_JAL:
-imm = GET_JAL_IMM(ctx->opcode);
-gen_jal(ctx, rd, imm);
-break;
-case OPC_RISC_JALR:
-gen_jalr(ctx, MASK_OP_JALR(ctx->opcode), rd, rs1, imm);
-break;
-case OPC_RISC_BRANCH:
-gen_branch(ctx, MASK_OP_BRANCH(ctx->opcode), rs1, rs2,
-   GET_B_IMM(ctx->opcode));
-break;
 case OPC_RISC_LOAD:
 gen_load(ctx, MASK_OP_LOAD(ctx->opcode), rd, rs1, imm);
 break;
-- 
2.19.2




[Qemu-devel] [PULL 03/29] target/riscv: Convert RV32I load/store insns to decodetree

2019-03-13 Thread Palmer Dabbelt
From: Bastian Koppelmann 

Acked-by: Alistair Francis 
Reviewed-by: Richard Henderson 
Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 
---
 target/riscv/insn32.decode  | 10 ++
 target/riscv/insn_trans/trans_rvi.inc.c | 48 +
 2 files changed, 58 insertions(+)

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 81f56c16b45f..076de873c4f1 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -23,6 +23,7 @@
 
 # immediates:
 %imm_i20:s12
+%imm_s25:s7 7:5
 %imm_b31:s1 7:1 25:6 8:4 !function=ex_shift_1
 %imm_j31:s1 12:8 20:1 21:10  !function=ex_shift_1
 %imm_u12:s20 !function=ex_shift_12
@@ -33,6 +34,7 @@
 # Formats 32:
 @i   . ... . ... imm=%imm_i %rs1 
%rd
 @b   ...   . . ... . ... &b  imm=%imm_b %rs2 %rs1
+@s   ...   . . ... . ... imm=%imm_s %rs2 %rs1
 @u     . ... imm=%imm_u  
%rd
 @j     . ... imm=%imm_j  
%rd
 
@@ -47,3 +49,11 @@ blt  ... .. 100 . 1100011 @b
 bge  ... .. 101 . 1100011 @b
 bltu ... .. 110 . 1100011 @b
 bgeu ... .. 111 . 1100011 @b
+lb    . 000 . 011 @i
+lh    . 001 . 011 @i
+lw    . 010 . 011 @i
+lbu   . 100 . 011 @i
+lhu   . 101 . 011 @i
+sb   ...  .   . 000 . 0100011 @s
+sh   ...  .   . 001 . 0100011 @s
+sw   ...  .   . 010 . 0100011 @s
diff --git a/target/riscv/insn_trans/trans_rvi.inc.c 
b/target/riscv/insn_trans/trans_rvi.inc.c
index bcf20def50eb..d13b7b2b6d8f 100644
--- a/target/riscv/insn_trans/trans_rvi.inc.c
+++ b/target/riscv/insn_trans/trans_rvi.inc.c
@@ -82,3 +82,51 @@ static bool trans_bgeu(DisasContext *ctx, arg_bgeu *a)
 gen_branch(ctx, OPC_RISC_BGEU, a->rs1, a->rs2, a->imm);
 return true;
 }
+
+static bool trans_lb(DisasContext *ctx, arg_lb *a)
+{
+gen_load(ctx, OPC_RISC_LB, a->rd, a->rs1, a->imm);
+return true;
+}
+
+static bool trans_lh(DisasContext *ctx, arg_lh *a)
+{
+gen_load(ctx, OPC_RISC_LH, a->rd, a->rs1, a->imm);
+return true;
+}
+
+static bool trans_lw(DisasContext *ctx, arg_lw *a)
+{
+gen_load(ctx, OPC_RISC_LW, a->rd, a->rs1, a->imm);
+return true;
+}
+
+static bool trans_lbu(DisasContext *ctx, arg_lbu *a)
+{
+gen_load(ctx, OPC_RISC_LBU, a->rd, a->rs1, a->imm);
+return true;
+}
+
+static bool trans_lhu(DisasContext *ctx, arg_lhu *a)
+{
+gen_load(ctx, OPC_RISC_LHU, a->rd, a->rs1, a->imm);
+return true;
+}
+
+static bool trans_sb(DisasContext *ctx, arg_sb *a)
+{
+gen_store(ctx, OPC_RISC_SB, a->rs1, a->rs2, a->imm);
+return true;
+}
+
+static bool trans_sh(DisasContext *ctx, arg_sh *a)
+{
+gen_store(ctx, OPC_RISC_SH, a->rs1, a->rs2, a->imm);
+return true;
+}
+
+static bool trans_sw(DisasContext *ctx, arg_sw *a)
+{
+gen_store(ctx, OPC_RISC_SW, a->rs1, a->rs2, a->imm);
+return true;
+}
-- 
2.19.2




[Qemu-devel] [PULL] target/riscv: Convert to decodetree

2019-03-13 Thread Palmer Dabbelt
merged tag 'pull-request-2019-03-12'
Primary key fingerprint: 27B8 8847 EEE0 2501 18F3  EAB9 2ED9 D774 FE70 2DB5
The following changes since commit 3f3bbfc7cef4490c5ed5550766a81e7d18f08db1:

  Merge remote-tracking branch 
'remotes/huth-gitlab/tags/pull-request-2019-03-12' into staging (2019-03-12 
21:06:26 +)

are available in the Git repository at:

  git://github.com/palmer-dabbelt/qemu.git tags/riscv-for-master-4.0-sf4

for you to fetch changes up to 25e6ca30c668783cd72ff97080ff44e141b99f9b:

  target/riscv: Remove decode_RV32_64G() (2019-03-13 10:40:50 +0100)


target/riscv: Convert to decodetree

Bastian: this patchset converts the RISC-V decoder to decodetree in four major 
steps:

1) Convert 32-bit instructions to decodetree [Patch 1-15]:
Many of the gen_* functions are called by the decode functions for 16-bit
and 32-bit functions. If we move translation code from the gen_*
functions to the generated trans_* functions of decode-tree, we get a lot of
duplication. Therefore, we mostly generate calls to the old gen_* function
which are properly replaced after step 2).

Each of the trans_ functions are grouped into files corresponding to their
ISA extension, e.g. addi which is in RV32I is translated in the file
'trans_rvi.inc.c'.

2) Convert 16-bit instructions to decodetree [Patch 16-18]:
All 16 bit instructions have a direct mapping to a 32 bit instruction. Thus,
we convert the arguments in the 16 bit trans_ function to the arguments of
the corresponding 32 bit instruction and call the 32 bit trans_ function.

3) Remove old manual decoding in gen_* function [Patch 19-29]:
this move all manual translation code into the trans_* instructions of
decode tree, such that we can remove the old decode_* functions.

Palmer: This, with some additional cleanup patches, passed Alistar's
testing on rv32 and rv64 as well as my testing on rv64, so I think it's
good to go.  I've run my standard test against this exact tag.

I still don't have a Mac to try this on, sorry!  If this doesn't work
then I'll go try to find one tomorrow.


Bastian Koppelmann (29):
  target/riscv: Activate decodetree and implemnt LUI & AUIPC
  target/riscv: Convert RVXI branch insns to decodetree
  target/riscv: Convert RV32I load/store insns to decodetree
  target/riscv: Convert RV64I load/store insns to decodetree
  target/riscv: Convert RVXI arithmetic insns to decodetree
  target/riscv: Convert RVXI fence insns to decodetree
  target/riscv: Convert RVXI csr insns to decodetree
  target/riscv: Convert RVXM insns to decodetree
  target/riscv: Convert RV32A insns to decodetree
  target/riscv: Convert RV64A insns to decodetree
  target/riscv: Convert RV32F insns to decodetree
  target/riscv: Convert RV64F insns to decodetree
  target/riscv: Convert RV32D insns to decodetree
  target/riscv: Convert RV64D insns to decodetree
  target/riscv: Convert RV priv insns to decodetree
  target/riscv: Convert quadrant 0 of RVXC insns to decodetree
  target/riscv: Convert quadrant 1 of RVXC insns to decodetree
  target/riscv: Convert quadrant 2 of RVXC insns to decodetree
  target/riscv: Remove gen_jalr()
  target/riscv: Remove manual decoding from gen_branch()
  target/riscv: Remove manual decoding from gen_load()
  target/riscv: Remove manual decoding from gen_store()
  target/riscv: Move gen_arith_imm() decoding into trans_* functions
  target/riscv: make ADD/SUB/OR/XOR/AND insn use arg lists
  target/riscv: Remove shift and slt insn manual decoding
  target/riscv: Remove manual decoding of RV32/64M insn
  target/riscv: Rename trans_arith to gen_arith
  target/riscv: Remove gen_system()
  target/riscv: Remove decode_RV32_64G()

 target/riscv/Makefile.objs |   19 +
 target/riscv/insn16.decode |  129 ++
 target/riscv/insn32-64.decode  |   72 +
 target/riscv/insn32.decode |  201 +++
 target/riscv/insn_trans/trans_privileged.inc.c |  110 ++
 target/riscv/insn_trans/trans_rva.inc.c|  218 +++
 target/riscv/insn_trans/trans_rvc.inc.c|  327 +
 target/riscv/insn_trans/trans_rvd.inc.c|  442 ++
 target/riscv/insn_trans/trans_rvf.inc.c|  439 ++
 target/riscv/insn_trans/trans_rvi.inc.c|  568 
 target/riscv/insn_trans/trans_rvm.inc.c|  120 ++
 target/riscv/translate.c   | 1847 
 12 files changed, 2897 insertions(+), 1595 deletions(-)
 create mode 100644 target/riscv/insn16.decode
 create mode 100644 target/riscv/insn32-64.decode
 create mode 100644 target/riscv/insn32.decode
 create mode 100644 target/riscv/insn_trans/tr

Re: [Qemu-devel] [PATCH 0/2] kconfig: add fine-grained dependencies for MSI

2019-03-14 Thread Palmer Dabbelt

On Thu, 14 Mar 2019 10:30:20 PDT (-0700), alistai...@gmail.com wrote:

On Thu, Mar 14, 2019 at 10:09 AM Michael S. Tsirkin  wrote:


On Thu, Mar 14, 2019 at 03:30:30PM +0100, Paolo Bonzini wrote:
> RISC-V targets did not include PCIe ports before the Kconfig transition,
> and grew them afterwards, but they are nonfunctional because the interrupt
> controller does not support MSI.  This patch restores the situation prior to
> the introduction of Kconfig; in fact, it will automatically drop devices
> that require MSI unless the binary includes an MSI-enabled board.
>
> Paolo

Reviewed-by: Michael S. Tsirkin 


Thanks for the patch Paolo.

Reviewed-by: Alistair Francis 


Paolo: I assume this is going in through your tree?  I'm dropping it from my 
inbox.


Thanks for fixing this!



Alistair



> Paolo Bonzini (2):
>   kconfig: add CONFIG_MSI
>   kconfig: add dependencies on CONFIG_MSI
>
>  Kconfig.host  | 3 +++
>  Makefile  | 3 ++-
>  hw/Kconfig| 1 +
>  hw/intc/Kconfig   | 3 +++
>  hw/misc/Kconfig   | 4 ++--
>  hw/net/Kconfig| 4 ++--
>  hw/pci-bridge/Kconfig | 6 +++---
>  hw/pci-host/Kconfig   | 1 +
>  hw/pci/Kconfig| 4 
>  hw/ppc/Kconfig| 1 +
>  hw/rdma/Kconfig   | 3 +++
>  hw/rdma/Makefile.objs | 6 ++
>  hw/s390x/Kconfig  | 1 +
>  13 files changed, 28 insertions(+), 12 deletions(-)
>  create mode 100644 hw/rdma/Kconfig
>
> --
> 2.20.1





Re: [Qemu-devel] [PULL 17/29] target/riscv: Convert quadrant 1 of RVXC insns to decodetree

2019-03-14 Thread Palmer Dabbelt

On Thu, 14 Mar 2019 13:28:37 PDT (-0700), alistai...@gmail.com wrote:

On Wed, Mar 13, 2019 at 7:53 AM Palmer Dabbelt  wrote:


From: Bastian Koppelmann 

Reviewed-by: Richard Henderson 
Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 


This commit is the first bad commit in breaking 32-bit boot.

It looks like the jal doesn't jump to the correct address:


IN:
0x8022:  00050433  add s0,a0,zero
0x8026:  000584b3  add s1,a1,zero
0x802a:  2c79  jal ra,670  # 0x82c8


IN:
0x82c8:  0533  add a0,zero,zero
0x82cc:  8082  ret



Sorry, for some reason I thought you'd tested this on 32-bit?  Do you have a 
workflow that I can use to reproduce the bug?





Alistair


---
 target/riscv/insn16.decode  |  43 +++
 target/riscv/insn_trans/trans_rvc.inc.c | 151 
 target/riscv/translate.c| 118 +-
 3 files changed, 195 insertions(+), 117 deletions(-)

diff --git a/target/riscv/insn16.decode b/target/riscv/insn16.decode
index 558c0c41f0b5..45109301c6d4 100644
--- a/target/riscv/insn16.decode
+++ b/target/riscv/insn16.decode
@@ -22,28 +22,53 @@
 %rs2_3 2:3!function=ex_rvc_register

 # Immediates:
+%imm_ci12:s1 2:5
 %nzuimm_ciw7:4 11:2 5:1 6:1   !function=ex_shift_2
 %uimm_cl_d 5:2 10:3   !function=ex_shift_3
 %uimm_cl_w 5:1 10:3 6:1   !function=ex_shift_2
+%imm_cb12:s1 5:2 2:1 10:2 3:2 !function=ex_shift_1
+%imm_cj12:s1 8:1 9:2 6:1 7:1 2:1 11:1 3:3 !function=ex_shift_1
+
+%nzuimm_6bit   12:1 2:5
+
+%imm_addi16sp  12:s1 3:2 5:1 2:1 6:1 !function=ex_shift_4
+%imm_lui   12:s1 2:5 !function=ex_shift_12
+


 # Argument sets:
 &cl   rs1 rd
 &cl_dw uimm   rs1 rd
+&ciimmrd
 &ciw   nzuimm rd
 &cs   rs1 rs2
 &cs_dw uimm   rs1 rs2
+&cbimmrs1
+&cr   rd  rs2
+&cj   imm
+&c_shift   shamt  rd
+

+&caddi16sp_lui  imm_lui imm_addi16sp rd

 # Formats 16:
+@ci... . . .  .. &ci imm=%imm_ci  %rd
 @ciw   ...    ... .. &ciwnzuimm=%nzuimm_ciw   rd=%rs2_3
 @cl_d  ... ... ... .. ... .. &cl_dw  uimm=%uimm_cl_d  rs1=%rs1_3  rd=%rs2_3
 @cl_w  ... ... ... .. ... .. &cl_dw  uimm=%uimm_cl_w  rs1=%rs1_3  rd=%rs2_3
 @cl... ... ... .. ... .. &cl  rs1=%rs1_3  rd=%rs2_3
 @cs... ... ... .. ... .. &cs  rs1=%rs1_3  
rs2=%rs2_3
+@cs_2  ... ... ... .. ... .. &cr  rd=%rs1_3   
rs2=%rs2_3
 @cs_d  ... ... ... .. ... .. &cs_dw  uimm=%uimm_cl_d  rs1=%rs1_3  
rs2=%rs2_3
 @cs_w  ... ... ... .. ... .. &cs_dw  uimm=%uimm_cl_w  rs1=%rs1_3  
rs2=%rs2_3
+@cb... ... ... .. ... .. &cb imm=%imm_cb  rs1=%rs1_3
+@cj...... .. &cj imm=%imm_cj

+@c_addi16sp_lui ... .  . . .. &caddi16sp_lui %imm_lui %imm_addi16sp %rd
+
+@c_shift... . .. ... . .. &c_shift rd=%rs1_3 shamt=%nzuimm_6bit
+
+@c_andi ... . .. ... . .. &ci imm=%imm_ci rd=%rs1_3

 # *** RV64C Standard Extension (Quadrant 0) ***
 c_addi4spn000 ... 00 @ciw
@@ -53,3 +78,21 @@ c_flw_ld  011  --- ... -- ... 00 @cl#Note: Must 
parse uimm manually
 c_fsd 101  ... ... .. ... 00 @cs_d
 c_sw  110  ... ... .. ... 00 @cs_w
 c_fsw_sd  111  --- ... -- ... 00 @cs#Note: Must parse uimm manually
+
+# *** RV64C Standard Extension (Quadrant 1) ***
+c_addi000 .  .  . 01 @ci
+c_jal_addiw   001 .  .  . 01 @ci #Note: parse rd and/or imm 
manually
+c_li  010 .  .  . 01 @ci
+c_addi16sp_lui011 .  .  . 01 @c_addi16sp_lui # shares opc with 
C.LUI
+c_srli100 . 00 ...  . 01 @c_shift
+c_srai100 . 01 ...  . 01 @c_shift
+c_andi100 . 10 ...  . 01 @c_andi
+c_sub 100 0 11 ... 00 ... 01 @cs_2
+c_xor 100 0 11 ... 01 ... 01 @cs_2
+c_or  100 0 11 ... 10 ... 01 @cs_2
+c_and 100 0 11 ... 11 ... 01 @cs_2
+c_subw100 1 11 ... 00 ... 01 @cs_2
+c_addw100 1 11 ... 01 ... 01 @cs_2
+c_j   101 ... 01 @cj
+c_beqz110  ... ...  . 01 @cb
+c_bnez111  ... ...  . 01 @cb
diff --git a/target/riscv/insn_trans/trans_rvc.inc.c 
b/target/riscv/insn_trans/trans_rvc.inc.c
index 93ec8aa30b95..b06c435c9800 100644
--- a/target/riscv/insn_trans/trans_rvc.inc.c
+++ b/target/riscv/insn_trans/trans_rvc.inc.c
@@ -73,3 +73,154 @@ static bool trans_c_fsw_sd(DisasContext *ctx, arg_c_fsw_sd 
*a)
 return false;
 #endif
 }
+
+static bool trans_c_addi(Di

Re: [Qemu-devel] [PULL 17/29] target/riscv: Convert quadrant 1 of RVXC insns to decodetree

2019-03-14 Thread Palmer Dabbelt

On Thu, 14 Mar 2019 21:57:37 PDT (-0700), alistai...@gmail.com wrote:

On Thu, Mar 14, 2019 at 8:59 PM Palmer Dabbelt  wrote:


On Thu, 14 Mar 2019 13:28:37 PDT (-0700), alistai...@gmail.com wrote:
> On Wed, Mar 13, 2019 at 7:53 AM Palmer Dabbelt  wrote:
>>
>> From: Bastian Koppelmann 
>>
>> Reviewed-by: Richard Henderson 
>> Signed-off-by: Bastian Koppelmann 
>> Signed-off-by: Peer Adelt 
>
> This commit is the first bad commit in breaking 32-bit boot.
>
> It looks like the jal doesn't jump to the correct address:
>
> 
> IN:
> 0x8022:  00050433  add s0,a0,zero
> 0x8026:  000584b3  add s1,a1,zero
> 0x802a:  2c79  jal ra,670  # 0x82c8
>
> 
> IN:
> 0x82c8:  0533  add a0,zero,zero
> 0x82cc:  8082  ret


Sorry, for some reason I thought you'd tested this on 32-bit?  Do you have a
workflow that I can use to reproduce the bug?


I did! Not sure what happened there. Maybe something changed between
what I tested and what was merged or somehow I tested the wrong thing.

Just booting 32-bit OpenSBI fails. It seems that the imm for jal is
wrong. I'll keep digging into it.


OK, thanks.  There was some jiggling around of the patch due to OSX build 
issues, maybe that broke something in 32-bit land?




Alistair



>
>
> Alistair
>
>> ---
>>  target/riscv/insn16.decode  |  43 +++
>>  target/riscv/insn_trans/trans_rvc.inc.c | 151 
>>  target/riscv/translate.c| 118 +-
>>  3 files changed, 195 insertions(+), 117 deletions(-)
>>
>> diff --git a/target/riscv/insn16.decode b/target/riscv/insn16.decode
>> index 558c0c41f0b5..45109301c6d4 100644
>> --- a/target/riscv/insn16.decode
>> +++ b/target/riscv/insn16.decode
>> @@ -22,28 +22,53 @@
>>  %rs2_3 2:3!function=ex_rvc_register
>>
>>  # Immediates:
>> +%imm_ci12:s1 2:5
>>  %nzuimm_ciw7:4 11:2 5:1 6:1   !function=ex_shift_2
>>  %uimm_cl_d 5:2 10:3   !function=ex_shift_3
>>  %uimm_cl_w 5:1 10:3 6:1   !function=ex_shift_2
>> +%imm_cb12:s1 5:2 2:1 10:2 3:2 !function=ex_shift_1
>> +%imm_cj12:s1 8:1 9:2 6:1 7:1 2:1 11:1 3:3 !function=ex_shift_1
>> +
>> +%nzuimm_6bit   12:1 2:5
>> +
>> +%imm_addi16sp  12:s1 3:2 5:1 2:1 6:1 !function=ex_shift_4
>> +%imm_lui   12:s1 2:5 !function=ex_shift_12
>> +
>>
>>
>>  # Argument sets:
>>  &cl   rs1 rd
>>  &cl_dw uimm   rs1 rd
>> +&ciimmrd
>>  &ciw   nzuimm rd
>>  &cs   rs1 rs2
>>  &cs_dw uimm   rs1 rs2
>> +&cbimmrs1
>> +&cr   rd  rs2
>> +&cj   imm
>> +&c_shift   shamt  rd
>> +
>>
>> +&caddi16sp_lui  imm_lui imm_addi16sp rd
>>
>>  # Formats 16:
>> +@ci... . . .  .. &ci imm=%imm_ci  %rd
>>  @ciw   ...    ... .. &ciwnzuimm=%nzuimm_ciw   
rd=%rs2_3
>>  @cl_d  ... ... ... .. ... .. &cl_dw  uimm=%uimm_cl_d  rs1=%rs1_3  
rd=%rs2_3
>>  @cl_w  ... ... ... .. ... .. &cl_dw  uimm=%uimm_cl_w  rs1=%rs1_3  
rd=%rs2_3
>>  @cl... ... ... .. ... .. &cl  rs1=%rs1_3  
rd=%rs2_3
>>  @cs... ... ... .. ... .. &cs  rs1=%rs1_3  
rs2=%rs2_3
>> +@cs_2  ... ... ... .. ... .. &cr  rd=%rs1_3   
rs2=%rs2_3
>>  @cs_d  ... ... ... .. ... .. &cs_dw  uimm=%uimm_cl_d  rs1=%rs1_3  
rs2=%rs2_3
>>  @cs_w  ... ... ... .. ... .. &cs_dw  uimm=%uimm_cl_w  rs1=%rs1_3  
rs2=%rs2_3
>> +@cb... ... ... .. ... .. &cb imm=%imm_cb  rs1=%rs1_3
>> +@cj...... .. &cj imm=%imm_cj
>>
>> +@c_addi16sp_lui ... .  . . .. &caddi16sp_lui %imm_lui %imm_addi16sp 
%rd
>> +
>> +@c_shift... . .. ... . .. &c_shift rd=%rs1_3 shamt=%nzuimm_6bit
>> +
>> +@c_andi ... . .. ... . .. &ci imm=%imm_ci rd=%rs1_3
>>
>>  # *** RV64C Standard Extension (Quadrant 0) ***
>>  c_addi4spn000 ... 00 @ciw
>> @@ -53,3 +78,21 @@ c_flw_ld  011  --- ... -- ... 00 @cl#Note: 
Must parse uimm manually
>>  c_fsd 101  ... ... .. ... 00 @cs_d
>>  c_sw  110  ... ... .. ... 00 @cs_w
>>  c_fsw_sd  111  --- ... -- ... 00 @cs#Note: Must 

Re: [Qemu-devel] [PULL 17/29] target/riscv: Convert quadrant 1 of RVXC insns to decodetree

2019-03-15 Thread Palmer Dabbelt

On Fri, 15 Mar 2019 02:06:07 PDT (-0700), Bastian Koppelmann wrote:

Hi Alistair

On 3/14/19 9:28 PM, Alistair Francis wrote:

On Wed, Mar 13, 2019 at 7:53 AM Palmer Dabbelt  wrote:

From: Bastian Koppelmann 

Reviewed-by: Richard Henderson 
Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 

This commit is the first bad commit in breaking 32-bit boot.

It looks like the jal doesn't jump to the correct address:


IN:
0x8022:  00050433  add s0,a0,zero
0x8026:  000584b3  add s1,a1,zero
0x802a:  2c79  jal ra,670  # 0x82c8


IN:
0x82c8:  0533  add a0,zero,zero
0x82cc:  8082  ret



Oops! Can you point me to the binary to reproduce this?


I think I've traced it down to something simple: in my hello world binary I see

   20401a8c:   2a45jal 20401c3c 

in the objdump, and I see

   IN: _start
   0x20401a8c:  2a45  jal ra,432  # 0x20401c3c

but then QEMU jumps to 0x20401a9d.  I have a feeling it's something wrong with 
gen_jal() that disappeared during the cleanups that we dropped in order to fix 
the build issues.


I'm running

   ./riscv32-softmmu/qemu-system-riscv32 -machine sifive_e -kernel 
~/work/sifive/freedom-e-sdk/software/hello/hello -nographic -d 
in_asm,out_asm,exec,cpu -singlestep |& tee out.log

on the "hifive1" branch of github.com/palmer-dabbelt/qemu, which just has a 
PRCI fixup that I forgot about and haven't sent upstream yet (I'll do that 
after this issue).  The binary should be at


   http://www.dabbelt.com/~palmer/hello.elf

and the debug log at 


   http://www.dabbelt.com/~palmer/out.log

You can build the binary from github.com/sifive/freedom-e-sdk via

  make software PROGRAM=hello TARGET=sifive-hifive1

using the riscv64-unknown-elf-gcc-20181127-x86_64-linux-ubuntu14 toolchain 
binaries from our website (newer ones should work, but probably won't produce 
exactly the same output).


I'll poke around after grabbing some dinner...



Re: [PATCH] linux-user/riscv: Propagate fault address

2019-10-14 Thread Palmer Dabbelt

On Tue, 01 Oct 2019 09:39:52 PDT (-0700), thatle...@gmail.com wrote:

The CPU loop tagged all the queued signals as QEMU_SI_KILL while it was
filling the `_sigfault` part of `siginfo`: this caused QEMU to copy the
wrong fields over to the userspace program.

Make sure the fault address recorded by the MMU is is stored in the CPU
environment structure.

In case of memory faults store the exception address into `siginfo`.

Signed-off-by: Giuseppe Musacchio 
---
 linux-user/riscv/cpu_loop.c | 3 ++-
 target/riscv/cpu_helper.c   | 5 -
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/linux-user/riscv/cpu_loop.c b/linux-user/riscv/cpu_loop.c
index 12aa3c0f16..aa9e437875 100644
--- a/linux-user/riscv/cpu_loop.c
+++ b/linux-user/riscv/cpu_loop.c
@@ -89,6 +89,7 @@ void cpu_loop(CPURISCVState *env)
 case RISCV_EXCP_STORE_PAGE_FAULT:
 signum = TARGET_SIGSEGV;
 sigcode = TARGET_SEGV_MAPERR;
+sigaddr = env->badaddr;
 break;
 case EXCP_DEBUG:
 gdbstep:
@@ -108,7 +109,7 @@ void cpu_loop(CPURISCVState *env)
 .si_code = sigcode,
 ._sifields._sigfault._addr = sigaddr
 };
-queue_signal(env, info.si_signo, QEMU_SI_KILL, &info);
+queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
 }

 process_pending_signals(env);
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 87dd6a6ece..58e40e9824 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -446,9 +446,9 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int 
size,
 MMUAccessType access_type, int mmu_idx,
 bool probe, uintptr_t retaddr)
 {
-#ifndef CONFIG_USER_ONLY
 RISCVCPU *cpu = RISCV_CPU(cs);
 CPURISCVState *env = &cpu->env;
+#ifndef CONFIG_USER_ONLY
 hwaddr pa = 0;
 int prot;
 bool pmp_violation = false;
@@ -499,7 +499,10 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int 
size,
 case MMU_DATA_STORE:
 cs->exception_index = RISCV_EXCP_STORE_PAGE_FAULT;
 break;
+default:
+g_assert_not_reached();
 }
+env->badaddr = address;
 cpu_loop_exit_restore(cs, retaddr);
 #endif
 }


Reviewed-by: Palmer Dabbelt 

I fixed up your Author tag and added this to for-master.  Thanks!



Re: [PATCH v1 22/28] target/riscv: Allow specifying MMU stage

2019-10-16 Thread Palmer Dabbelt

On Mon, 07 Oct 2019 11:05:33 PDT (-0700), alistai...@gmail.com wrote:

On Thu, Oct 3, 2019 at 8:53 AM Palmer Dabbelt  wrote:


On Fri, 23 Aug 2019 16:38:47 PDT (-0700), Alistair Francis wrote:
> Signed-off-by: Alistair Francis 
> ---
>  target/riscv/cpu_helper.c | 39 ++-
>  1 file changed, 30 insertions(+), 9 deletions(-)
>
> diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
> index 098873c83e..9aa6906acd 100644
> --- a/target/riscv/cpu_helper.c
> +++ b/target/riscv/cpu_helper.c
> @@ -318,10 +318,19 @@ void riscv_cpu_set_mode(CPURISCVState *env, 
target_ulong newpriv)
>   *
>   * Adapted from Spike's mmu_t::translate and mmu_t::walk
>   *
> + * @env: CPURISCVState
> + * @physical: This will be set to the calculated physical address
> + * @prot: The returned protection attributes
> + * @addr: The virtual address to be translated
> + * @access_type: The type of MMU access
> + * @mmu_idx: Indicates current privilege level
> + * @first_stage: Are we in first stage translation?
> + *   Second stage is used for hypervisor guest translation
>   */
>  static int get_physical_address(CPURISCVState *env, hwaddr *physical,
>  int *prot, target_ulong addr,
> -int access_type, int mmu_idx)
> +int access_type, int mmu_idx,
> +bool first_stage)
>  {
>  /* NOTE: the env->pc value visible here will not be
>   * correct, but the value visible to the exception handler
> @@ -518,13 +527,23 @@ restart:
>  }
>
>  static void raise_mmu_exception(CPURISCVState *env, target_ulong address,
> -MMUAccessType access_type, bool 
pmp_violation)
> +MMUAccessType access_type, bool 
pmp_violation,
> +bool first_stage)
>  {
>  CPUState *cs = env_cpu(env);
> -int page_fault_exceptions =
> -(env->priv_ver >= PRIV_VERSION_1_10_0) &&
> -get_field(env->satp, SATP_MODE) != VM_1_10_MBARE &&
> -!pmp_violation;
> +int page_fault_exceptions;
> +if (first_stage) {
> +page_fault_exceptions =
> +(env->priv_ver >= PRIV_VERSION_1_10_0) &&
> +get_field(env->satp, SATP_MODE) != VM_1_10_MBARE &&
> +!pmp_violation;
> +riscv_cpu_set_force_hs_excep(env, CLEAR_HS_EXCEP);

It might just be email, but the indentation looks wrong here.


Yep, fixed.



> +} else {
> +page_fault_exceptions =
> +get_field(env->hgatp, HGATP_MODE) != VM_1_10_MBARE &&
> +!pmp_violation;
> +riscv_cpu_set_force_hs_excep(env, FORCE_HS_EXCEP);
> +}
>  switch (access_type) {
>  case MMU_INST_FETCH:
>  cs->exception_index = page_fault_exceptions ?
> @@ -551,7 +570,8 @@ hwaddr riscv_cpu_get_phys_page_debug(CPUState *cs, vaddr 
addr)
>  int prot;
>  int mmu_idx = cpu_mmu_index(&cpu->env, false);
>
> -if (get_physical_address(&cpu->env, &phys_addr, &prot, addr, 0, 
mmu_idx)) {
> +if (get_physical_address(&cpu->env, &phys_addr, &prot, addr, 0, mmu_idx,
> + true)) {
>  return -1;
>  }
>  return phys_addr;
> @@ -613,7 +633,8 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int 
size,
>  qemu_log_mask(CPU_LOG_MMU, "%s ad %" VADDR_PRIx " rw %d mmu_idx %d\n",
>__func__, address, access_type, mmu_idx);
>
> -ret = get_physical_address(env, &pa, &prot, address, access_type, 
mmu_idx);
> +ret = get_physical_address(env, &pa, &prot, address, access_type, 
mmu_idx,
> +   true);
>
>  if (mode == PRV_M && access_type != MMU_INST_FETCH) {
>  if (get_field(*env->mstatus, MSTATUS_MPRV)) {
> @@ -640,7 +661,7 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int 
size,
>  } else if (probe) {
>  return false;
>  } else {
> -raise_mmu_exception(env, address, access_type, pmp_violation);
> +raise_mmu_exception(env, address, access_type, pmp_violation, true);
>  riscv_raise_exception(env, cs->exception_index, retaddr);
>  }
>  #else

I don't think it makes sense to split off these two (23 and 24, that add the
argument) out from the implementation.


The goal was just to make it easier to review. If you want them
combined I can easily combine them.


It's making it harder to read on my end :)



Re: [PATCH v1 1/1] target/riscv: Remove atomic accesses to MIP CSR

2019-10-18 Thread Palmer Dabbelt

On Tue, 08 Oct 2019 15:04:18 PDT (-0700), Alistair Francis wrote:

Instead of relying on atomics to access the MIP register let's update
our helper function to instead just lock the IO mutex thread before
writing. This follows the same concept as used in PPC for handling
interrupts

Signed-off-by: Alistair Francis 
---
 target/riscv/cpu.c|  5 ++--
 target/riscv/cpu.h|  9 
 target/riscv/cpu_helper.c | 48 +++
 target/riscv/csr.c|  2 +-
 4 files changed, 21 insertions(+), 43 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index f13e298a36..e09dd7aa23 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -224,8 +224,7 @@ static void riscv_cpu_dump_state(CPUState *cs, FILE *f, int 
flags)
 #ifndef CONFIG_USER_ONLY
 qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mhartid ", env->mhartid);
 qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mstatus ", env->mstatus);
-qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mip ",
- (target_ulong)atomic_read(&env->mip));
+qemu_fprintf(f, " %s 0x%x\n", "mip ", env->mip);
 qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mie ", env->mie);
 qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mideleg ", env->mideleg);
 qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "medeleg ", env->medeleg);
@@ -275,7 +274,7 @@ static bool riscv_cpu_has_work(CPUState *cs)
  * Definition of the WFI instruction requires it to ignore the privilege
  * mode and delegation registers, but respect individual enables
  */
-return (atomic_read(&env->mip) & env->mie) != 0;
+return (env->mip & env->mie) != 0;
 #else
 return true;
 #endif
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 124ed33ee4..a71473b243 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -121,15 +121,6 @@ struct CPURISCVState {
 target_ulong mhartid;
 target_ulong mstatus;

-/*
- * CAUTION! Unlike the rest of this struct, mip is accessed asynchonously
- * by I/O threads. It should be read with atomic_read. It should be updated
- * using riscv_cpu_update_mip with the iothread mutex held. The iothread
- * mutex must be held because mip must be consistent with the CPU inturrept
- * state. riscv_cpu_update_mip calls cpu_interrupt or cpu_reset_interrupt
- * wuth the invariant that CPU_INTERRUPT_HARD is set iff mip is non-zero.
- * mip is 32-bits to allow atomic_read on 32-bit hosts.
- */
 uint32_t mip;
 uint32_t miclaim;

diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 87dd6a6ece..4334978c2e 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -19,6 +19,7 @@

 #include "qemu/osdep.h"
 #include "qemu/log.h"
+#include "qemu/main-loop.h"
 #include "cpu.h"
 #include "exec/exec-all.h"
 #include "tcg-op.h"
@@ -38,7 +39,7 @@ static int riscv_cpu_local_irq_pending(CPURISCVState *env)
 {
 target_ulong mstatus_mie = get_field(env->mstatus, MSTATUS_MIE);
 target_ulong mstatus_sie = get_field(env->mstatus, MSTATUS_SIE);
-target_ulong pending = atomic_read(&env->mip) & env->mie;
+target_ulong pending = env->mip & env->mie;
 target_ulong mie = env->priv < PRV_M || (env->priv == PRV_M && 
mstatus_mie);
 target_ulong sie = env->priv < PRV_S || (env->priv == PRV_S && 
mstatus_sie);
 target_ulong irqs = (pending & ~env->mideleg & -mie) |
@@ -92,42 +93,29 @@ int riscv_cpu_claim_interrupts(RISCVCPU *cpu, uint32_t 
interrupts)
 }
 }

-struct CpuAsyncInfo {
-uint32_t new_mip;
-};
-
-static void riscv_cpu_update_mip_irqs_async(CPUState *target_cpu_state,
-run_on_cpu_data data)
-{
-struct CpuAsyncInfo *info = (struct CpuAsyncInfo *) data.host_ptr;
-
-if (info->new_mip) {
-cpu_interrupt(target_cpu_state, CPU_INTERRUPT_HARD);
-} else {
-cpu_reset_interrupt(target_cpu_state, CPU_INTERRUPT_HARD);
-}
-
-g_free(info);
-}
-
 uint32_t riscv_cpu_update_mip(RISCVCPU *cpu, uint32_t mask, uint32_t value)
 {
 CPURISCVState *env = &cpu->env;
 CPUState *cs = CPU(cpu);
-struct CpuAsyncInfo *info;
-uint32_t old, new, cmp = atomic_read(&env->mip);
+uint32_t old = env->mip;
+bool locked = false;
+
+if (!qemu_mutex_iothread_locked()) {
+locked = true;
+qemu_mutex_lock_iothread();
+}


I must be lost here, because I have no idea what this is trying to do.


-do {
-old = cmp;
-new = (old & ~mask) | (value & mask);
-cmp = atomic_cmpxchg(&env->mip, old, new);
-} while (old != cmp);
+env->mip = (env->mip & ~mask) | (value & mask);

-info = g_new(struct CpuAsyncInfo, 1);
-info->new_mip = new;
+if (env->mip) {
+cpu_interrupt(cs, CPU_INTERRUPT_HARD);
+} else {
+cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
+}

-async_run_on_cpu(cs, riscv_cpu_update_mip_irqs_async,
- RUN_ON_CPU_HOST

Re: [PATCH v5 31/55] target/riscv: fetch code with translator_ld

2019-10-18 Thread Palmer Dabbelt

On Mon, 14 Oct 2019 10:59:07 PDT (-0700), alistai...@gmail.com wrote:

On Mon, Oct 14, 2019 at 4:20 AM Alex Bennée  wrote:


From: "Emilio G. Cota" 

Signed-off-by: Emilio G. Cota 
Reviewed-by: Richard Henderson 
Signed-off-by: Alex Bennée 


Reviewed-by: Alistair Francis 


and

Acked-by: Palmer Dabbelt 

as I'm assuming this will go in with the rest of the patch set.



Alistair


---
 target/riscv/translate.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index adeddb85f6..b26533d4fd 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -779,7 +779,7 @@ static void riscv_tr_translate_insn(DisasContextBase 
*dcbase, CPUState *cpu)
 DisasContext *ctx = container_of(dcbase, DisasContext, base);
 CPURISCVState *env = cpu->env_ptr;

-ctx->opcode = cpu_ldl_code(env, ctx->base.pc_next);
+ctx->opcode = translator_ldl(env, ctx->base.pc_next);
 decode_opc(ctx);
 ctx->base.pc_next = ctx->pc_succ_insn;

--
2.20.1






Re: [PATCH v4 0/3] target/riscv: Expose "priv" register for GDB

2019-10-18 Thread Palmer Dabbelt

On Mon, 14 Oct 2019 08:45:26 PDT (-0700), jonat...@fintelia.io wrote:


This series adds a new "priv" virtual register that reports the current
privilege mode. This is helpful for debugging purposes because that information
is not actually available in any of the real CSRs.

The third patch in this series makes the priv virtual register writitable. I'm
not entirely sure this is a good idea, so I split it out into its own patch. In
particular, this change will conflict with the hypervisor extension work which
assumes that the privilege mode does not change in unexpected cases.

As pointed out in a previous version of this series, GDB actually contains some
support already for the accessing the privilege mode via a virtual "priv"
register, including to convert the values into human readable forms:

(gdb) info reg priv
priv   0x3  prv:3 [Machine]

Changlog V4:
- Fix typo in filename

Changlog V3:
- Break patch into series
- Make priv a virtual register

Changelog V2:
- Use PRV_H and PRV_S instead of integer literals

Jonathan Behrens (3)
  target/riscv: Tell gdbstub the correct number of CSRs
  target/riscv: Expose priv register for GDB for reads
  target/riscv: Make the priv register writable by GDB

 configure   |  4 ++--
 gdb-xml/riscv-32bit-virtual.xml | 11 +++
 gdb-xml/riscv-64bit-virtual.xml | 11 +++
 target/riscv/gdbstub.c  | 36 ++--
 4 files changed, 58 insertions(+), 4 deletions(-)


Thanks.  I've taken these into my patch queue, which I hope to submit soon!



Re: [PATCH v3 1/2] hw: timer: Add Goldfish RTC device

2019-10-18 Thread Palmer Dabbelt

On Tue, 15 Oct 2019 01:35:31 PDT (-0700), Anup Patel wrote:

This patch adds model for Google Goldfish virtual platform RTC device.

We will be adding Goldfish RTC device to the QEMU RISC-V virt machine
for providing real date-time to Guest Linux. The corresponding Linux
driver for Goldfish RTC device is already available in upstream Linux.

For now, VM migration support is available but untested for Goldfish RTC
device. It will be hardened in-future when we implement VM migration for
KVM RISC-V.

Signed-off-by: Anup Patel 
---
 hw/rtc/Kconfig  |   3 +
 hw/rtc/Makefile.objs|   1 +
 hw/rtc/goldfish_rtc.c   | 278 
 include/hw/timer/goldfish_rtc.h |  46 ++
 4 files changed, 328 insertions(+)
 create mode 100644 hw/rtc/goldfish_rtc.c
 create mode 100644 include/hw/timer/goldfish_rtc.h


I'd be happy to take a look at this, but I don't have a hw/rtc directory in my 
QEMU.  IIRC there was a refactoring going on here, is there a tree this is 
based on?



diff --git a/hw/rtc/Kconfig b/hw/rtc/Kconfig
index 45daa8d655..bafe6ac2c9 100644
--- a/hw/rtc/Kconfig
+++ b/hw/rtc/Kconfig
@@ -21,3 +21,6 @@ config MC146818RTC
 
 config SUN4V_RTC

 bool
+
+config GOLDFISH_RTC
+bool
diff --git a/hw/rtc/Makefile.objs b/hw/rtc/Makefile.objs
index 8dc9fcd3a9..aa208d0d10 100644
--- a/hw/rtc/Makefile.objs
+++ b/hw/rtc/Makefile.objs
@@ -11,3 +11,4 @@ common-obj-$(CONFIG_EXYNOS4) += exynos4210_rtc.o
 obj-$(CONFIG_MC146818RTC) += mc146818rtc.o
 common-obj-$(CONFIG_SUN4V_RTC) += sun4v-rtc.o
 common-obj-$(CONFIG_ASPEED_SOC) += aspeed_rtc.o
+common-obj-$(CONFIG_GOLDFISH_RTC) += goldfish_rtc.o
diff --git a/hw/rtc/goldfish_rtc.c b/hw/rtc/goldfish_rtc.c
new file mode 100644
index 00..223616ed75
--- /dev/null
+++ b/hw/rtc/goldfish_rtc.c
@@ -0,0 +1,278 @@
+/*
+ * Goldfish virtual platform RTC
+ *
+ * Copyright (C) 2019 Western Digital Corporation or its affiliates.
+ *
+ * For more details on Google Goldfish virtual platform refer:
+ * 
https://android.googlesource.com/platform/external/qemu/+/master/docs/GOLDFISH-VIRTUAL-HARDWARE.TXT
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see .
+ */
+
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "hw/timer/goldfish_rtc.h"
+#include "migration/vmstate.h"
+#include "hw/irq.h"
+#include "hw/qdev-properties.h"
+#include "hw/sysbus.h"
+#include "qemu/timer.h"
+#include "sysemu/sysemu.h"
+#include "qemu/cutils.h"
+#include "qemu/log.h"
+
+#define RTC_TIME_LOW0x00
+#define RTC_TIME_HIGH   0x04
+#define RTC_ALARM_LOW   0x08
+#define RTC_ALARM_HIGH  0x0c
+#define RTC_IRQ_ENABLED 0x10
+#define RTC_CLEAR_ALARM 0x14
+#define RTC_ALARM_STATUS0x18
+#define RTC_CLEAR_INTERRUPT 0x1c
+
+static void goldfish_rtc_update(GoldfishRTCState *s)
+{
+qemu_set_irq(s->irq, (s->irq_pending & s->irq_enabled) ? 1 : 0);
+}
+
+static void goldfish_rtc_interrupt(void *opaque)
+{
+GoldfishRTCState *s = (GoldfishRTCState *)opaque;
+
+s->alarm_running = 0;
+s->irq_pending = 1;
+goldfish_rtc_update(s);
+}
+
+static uint64_t goldfish_rtc_get_count(GoldfishRTCState *s)
+{
+return s->tick_offset + (uint64_t)qemu_clock_get_ns(rtc_clock);
+}
+
+static void goldfish_rtc_clear_alarm(GoldfishRTCState *s)
+{
+timer_del(s->timer);
+s->alarm_running = 0;
+}
+
+static void goldfish_rtc_set_alarm(GoldfishRTCState *s)
+{
+uint64_t ticks = goldfish_rtc_get_count(s);
+uint64_t event = s->alarm_next;
+
+if (event <= ticks) {
+goldfish_rtc_clear_alarm(s);
+goldfish_rtc_interrupt(s);
+} else {
+int64_t now = qemu_clock_get_ns(rtc_clock);
+timer_mod(s->timer, now + (event - ticks));
+s->alarm_running = 1;
+}
+}
+
+static uint64_t goldfish_rtc_read(void *opaque, hwaddr offset,
+  unsigned size)
+{
+GoldfishRTCState *s = (GoldfishRTCState *)opaque;
+uint64_t r;
+
+switch (offset) {
+case RTC_TIME_LOW:
+r = goldfish_rtc_get_count(s) & 0x;
+break;
+case RTC_TIME_HIGH:
+r = goldfish_rtc_get_count(s) >> 32;
+break;
+case RTC_ALARM_LOW:
+r = s->alarm_next & 0x;
+break;
+case RTC_ALARM_HIGH:
+r = s->alarm_next >> 32;
+break;
+case RTC_IRQ_ENABLED:
+r = s->irq_enabled;
+break;
+case RTC_ALARM_STATU

Re: [PATCH v3 2/2] riscv: virt: Use Goldfish RTC device

2019-10-18 Thread Palmer Dabbelt

On Tue, 15 Oct 2019 01:35:42 PDT (-0700), Anup Patel wrote:

We extend QEMU RISC-V virt machine by adding Goldfish RTC device
to it. This will allow Guest Linux to sync it's local date/time
with Host date/time via RTC device.

Signed-off-by: Anup Patel 
---
 hw/riscv/Kconfig|  1 +
 hw/riscv/virt.c | 15 +++
 include/hw/riscv/virt.h |  2 ++
 3 files changed, 18 insertions(+)

diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig
index fb19b2df3a..b33753c780 100644
--- a/hw/riscv/Kconfig
+++ b/hw/riscv/Kconfig
@@ -34,6 +34,7 @@ config RISCV_VIRT
 select PCI
 select HART
 select SERIAL
+select GOLDFISH_RTC
 select VIRTIO_MMIO
 select PCI_EXPRESS_GENERIC_BRIDGE
 select SIFIVE
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index d36f5625ec..95c42ab993 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -57,6 +57,7 @@ static const struct MemmapEntry {
 [VIRT_DEBUG] =   {0x0, 0x100 },
 [VIRT_MROM] ={ 0x1000,   0x11000 },
 [VIRT_TEST] ={   0x10,0x1000 },
+[VIRT_RTC] = {   0x101000,0x1000 },
 [VIRT_CLINT] =   {  0x200,   0x1 },
 [VIRT_PLIC] ={  0xc00, 0x400 },
 [VIRT_UART0] =   { 0x1000, 0x100 },
@@ -310,6 +311,17 @@ static void create_fdt(RISCVVirtState *s, const struct 
MemmapEntry *memmap,
 qemu_fdt_setprop_cell(fdt, nodename, "interrupt-parent", plic_phandle);
 qemu_fdt_setprop_cell(fdt, nodename, "interrupts", UART0_IRQ);
 
+nodename = g_strdup_printf("/rtc@%lx",

+(long)memmap[VIRT_RTC].base);
+qemu_fdt_add_subnode(fdt, nodename);
+qemu_fdt_setprop_string(fdt, nodename, "compatible",
+"google,goldfish-rtc");
+qemu_fdt_setprop_cells(fdt, nodename, "reg",
+0x0, memmap[VIRT_RTC].base,
+0x0, memmap[VIRT_RTC].size);
+qemu_fdt_setprop_cell(fdt, nodename, "interrupt-parent", plic_phandle);
+qemu_fdt_setprop_cell(fdt, nodename, "interrupts", RTC_IRQ);
+
 qemu_fdt_add_subnode(fdt, "/chosen");
 qemu_fdt_setprop_string(fdt, "/chosen", "stdout-path", nodename);
 if (cmdline) {
@@ -496,6 +508,9 @@ static void riscv_virt_board_init(MachineState *machine)
 0, qdev_get_gpio_in(DEVICE(s->plic), UART0_IRQ), 399193,
 serial_hd(0), DEVICE_LITTLE_ENDIAN);
 
+sysbus_create_simple("goldfish_rtc", memmap[VIRT_RTC].base,

+qdev_get_gpio_in(DEVICE(s->plic), RTC_IRQ));
+
 g_free(plic_hart_config);
 }
 
diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h

index 6e5fbe5d3b..e6423258d3 100644
--- a/include/hw/riscv/virt.h
+++ b/include/hw/riscv/virt.h
@@ -37,6 +37,7 @@ enum {
 VIRT_DEBUG,
 VIRT_MROM,
 VIRT_TEST,
+VIRT_RTC,
 VIRT_CLINT,
 VIRT_PLIC,
 VIRT_UART0,
@@ -49,6 +50,7 @@ enum {
 
 enum {

 UART0_IRQ = 10,
+RTC_IRQ = 11,
 VIRTIO_IRQ = 1, /* 1 to 8 */
 VIRTIO_COUNT = 8,
 PCIE_IRQ = 0x20, /* 32 to 35 */


This is a wacky enum, but it's already there.  I'm going to assume this patch 
will get merged and then fix it later.



--
2.17.1


Reviewed-by: Palmer Dabbelt 
Acked-by: Palmer Dabbelt 

I think it's easier to just keep this with the goldfish implementation.  I'm 
assuming that will go in through a different tree, as per my comments on that 
patch.




Re: [PATCH] target/riscv: PMP violation due to wrong size parameter

2019-10-18 Thread Palmer Dabbelt

On Tue, 15 Oct 2019 10:04:32 PDT (-0700), day...@berkeley.edu wrote:

Hi,

Could this patch go through?
If not please let me know so that I can fix.
Thank you!


Sorry, I dropped this one.  It's in the patch queue now.  We should also check 
for size==0 in pmp_hart_has_privs(), as that won't work.  LMK if you want to 
send a patch for that.




Dayeol


On Sat, Oct 12, 2019, 11:30 AM Dayeol Lee  wrote:


No it doesn't mean that.
But the following code will make the size TARGET_PAGE_SIZE - (page offset)
if the address is not aligned.

pmp_size = -(address | TARGET_PAGE_MASK)


On Fri, Oct 11, 2019, 7:37 PM Jonathan Behrens  wrote:


How do you know that the access won't straddle a page boundary? Is there
a guarantee somewhere that size=0 means that the access is naturally
aligned?

Jonathan


On Fri, Oct 11, 2019 at 7:14 PM Dayeol Lee  wrote:


riscv_cpu_tlb_fill() uses the `size` parameter to check PMP violation
using pmp_hart_has_privs().
However, if the size is unknown (=0), the ending address will be
`addr - 1` as it is `addr + size - 1` in `pmp_hart_has_privs()`.
This always causes a false PMP violation on the starting address of the
range, as `addr - 1` is not in the range.

In order to fix, we just assume that all bytes from addr to the end of
the page will be accessed if the size is unknown.

Signed-off-by: Dayeol Lee 
Reviewed-by: Richard Henderson 
---
 target/riscv/cpu_helper.c | 13 -
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index e32b6126af..7d9a22b601 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -441,6 +441,7 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address,
int size,
 CPURISCVState *env = &cpu->env;
 hwaddr pa = 0;
 int prot;
+int pmp_size = 0;
 bool pmp_violation = false;
 int ret = TRANSLATE_FAIL;
 int mode = mmu_idx;
@@ -460,9 +461,19 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr
address, int size,
   "%s address=%" VADDR_PRIx " ret %d physical "
TARGET_FMT_plx
   " prot %d\n", __func__, address, ret, pa, prot);

+/*
+ * if size is unknown (0), assume that all bytes
+ * from addr to the end of the page will be accessed.
+ */
+if (size == 0) {
+pmp_size = -(address | TARGET_PAGE_MASK);
+} else {
+pmp_size = size;
+}
+
 if (riscv_feature(env, RISCV_FEATURE_PMP) &&
 (ret == TRANSLATE_SUCCESS) &&
-!pmp_hart_has_privs(env, pa, size, 1 << access_type, mode)) {
+!pmp_hart_has_privs(env, pa, pmp_size, 1 << access_type, mode))
{
 ret = TRANSLATE_PMP_FAIL;
 }
 if (ret == TRANSLATE_PMP_FAIL) {
--
2.20.1







Re: [PATCH v2 1/1] riscv/boot: Fix possible memory leak

2019-10-18 Thread Palmer Dabbelt

On Thu, 17 Oct 2019 05:08:39 PDT (-0700), Peter Maydell wrote:

Ping? It would be nice to see this patch get into master
to silence the coverity errors.


Sorry, it looks like I dropped this.  It's in my queue, I hope to submit a PR 
soon.




thanks
-- PMM

On Thu, 3 Oct 2019 at 18:05, Alistair Francis  wrote:


Coverity (CID 1405786) thinks that there is a possible memory leak as
we don't guarantee that the memory allocated from riscv_find_firmware()
is freed. This is a false positive, but let's tidy up the code to fix
the warning.

Signed-off-by: Alistair Francis 
Reviewed-by: Richard Henderson 
Reviewed-by: Bin Meng 
Reviewed-by: Philippe Mathieu-Daudé 
---
v2:
 - Fix commit typos

 hw/riscv/boot.c | 11 ---
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
index 2e92fb0680..7fee98d2f8 100644
--- a/hw/riscv/boot.c
+++ b/hw/riscv/boot.c
@@ -38,7 +38,7 @@ void riscv_find_and_load_firmware(MachineState *machine,
   const char *default_machine_firmware,
   hwaddr firmware_load_addr)
 {
-char *firmware_filename;
+char *firmware_filename = NULL;

 if (!machine->firmware) {
 /*
@@ -70,14 +70,11 @@ void riscv_find_and_load_firmware(MachineState *machine,
  * if no -bios option is set without breaking anything.
  */
 firmware_filename = riscv_find_firmware(default_machine_firmware);
-} else {
-firmware_filename = machine->firmware;
-if (strcmp(firmware_filename, "none")) {
-firmware_filename = riscv_find_firmware(firmware_filename);
-}
+} else if (strcmp(machine->firmware, "none")) {
+firmware_filename = riscv_find_firmware(machine->firmware);
 }

-if (strcmp(firmware_filename, "none")) {
+if (firmware_filename) {
 /* If not "none" load the firmware */
 riscv_load_firmware(firmware_filename, firmware_load_addr);
 g_free(firmware_filename);
--
2.23.0




Re: [PATCH] target/riscv: PMP violation due to wrong size parameter

2019-10-23 Thread Palmer Dabbelt

On Tue, 22 Oct 2019 14:21:29 PDT (-0700), day...@berkeley.edu wrote:

riscv_cpu_tlb_fill() uses the `size` parameter to check PMP violation
using pmp_hart_has_privs().
However, if the size is unknown (=0), the ending address will be
`addr - 1` as it is `addr + size - 1` in `pmp_hart_has_privs()`.
This always causes a false PMP violation on the starting address of the
range, as `addr - 1` is not in the range.

In order to fix, we just assume that all bytes from addr to the end of
the page will be accessed if the size is unknown.

Signed-off-by: Dayeol Lee 
Reviewed-by: Richard Henderson 
---
 target/riscv/pmp.c | 13 -
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
index 958c7502a0..7a9fd415ba 100644
--- a/target/riscv/pmp.c
+++ b/target/riscv/pmp.c
@@ -232,6 +232,7 @@ bool pmp_hart_has_privs(CPURISCVState *env, target_ulong 
addr,
 {
 int i = 0;
 int ret = -1;
+int pmp_size = 0;
 target_ulong s = 0;
 target_ulong e = 0;
 pmp_priv_t allowed_privs = 0;
@@ -241,11 +242,21 @@ bool pmp_hart_has_privs(CPURISCVState *env, target_ulong 
addr,
 return true;
 }

+/*
+ * if size is unknown (0), assume that all bytes
+ * from addr to the end of the page will be accessed.
+ */
+if (size == 0) {
+pmp_size = -(addr | TARGET_PAGE_MASK);
+} else {
+pmp_size = size;
+}
+
 /* 1.10 draft priv spec states there is an implicit order
  from low to high */
 for (i = 0; i < MAX_RISCV_PMPS; i++) {
 s = pmp_is_in_range(env, i, addr);
-e = pmp_is_in_range(env, i, addr + size - 1);
+e = pmp_is_in_range(env, i, addr + pmp_size - 1);

 /* partially inside */
 if ((s + e) == 1) {


Thanks.  I've queued this up for my next pull request.



Re: [PATCH v2 25/35] target/riscv: Only set TB flags with FP status if enabled

2020-02-13 Thread Palmer Dabbelt

On Fri, 31 Jan 2020 17:02:41 PST (-0800), Alistair Francis wrote:

Signed-off-by: Alistair Francis 
---
 target/riscv/cpu.h | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 5b889a0065..aa04e5cca7 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -332,7 +332,10 @@ static inline void cpu_get_tb_cpu_state(CPURISCVState 
*env, target_ulong *pc,
 #ifdef CONFIG_USER_ONLY
 *flags = TB_FLAGS_MSTATUS_FS;
 #else
-*flags = cpu_mmu_index(env, 0) | (env->mstatus & MSTATUS_FS);
+*flags = cpu_mmu_index(env, 0);
+if (riscv_cpu_fp_enabled(env)) {
+*flags |= env->mstatus & MSTATUS_FS;
+}
 #endif
 }


Reviewed-by: Palmer Dabbelt 



Re: [PATCH v2 26/35] target/riscv: Disable guest FP support based on virtual status

2020-02-13 Thread Palmer Dabbelt

On Fri, 31 Jan 2020 17:02:44 PST (-0800), Alistair Francis wrote:

When the Hypervisor extension is in use we only enable floating point
support when both status and vsstatus have enabled floating point
support.

Signed-off-by: Alistair Francis 
---
 target/riscv/cpu_helper.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index e7728cb0ca..827a38324c 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -99,6 +99,9 @@ bool riscv_cpu_exec_interrupt(CPUState *cs, int 
interrupt_request)
 bool riscv_cpu_fp_enabled(CPURISCVState *env)
 {
 if (env->mstatus & MSTATUS_FS) {
+if (riscv_cpu_virt_enabled(env) && !(env->mstatus_hs & MSTATUS_FS)) {
+return false;
+}
 return true;
 }


Reviewed-by: Palmer Dabbelt 



  1   2   3   4   5   6   7   8   9   10   >