[Qemu-devel] [RISU PATCH v3 05/18] risugen_x86_memory: add module

Jan Bobek posted 18 patches 6 years, 7 months ago
[Qemu-devel] [RISU PATCH v3 05/18] risugen_x86_memory: add module
Posted by Jan Bobek 6 years, 7 months ago
The module risugen_x86_memory.pm provides environment for evaluating
x86 "!memory" blocks. This is facilitated by the single exported
function eval_memory_block.

Signed-off-by: Jan Bobek <jan.bobek@gmail.com>
---
 risugen_x86_memory.pm | 87 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 87 insertions(+)
 create mode 100644 risugen_x86_memory.pm

diff --git a/risugen_x86_memory.pm b/risugen_x86_memory.pm
new file mode 100644
index 0000000..6aa6877
--- /dev/null
+++ b/risugen_x86_memory.pm
@@ -0,0 +1,87 @@
+#!/usr/bin/perl -w
+###############################################################################
+# Copyright (c) 2019 Jan Bobek
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+#     Jan Bobek - initial implementation
+###############################################################################
+
+# risugen_x86_memory -- risugen_x86's helper module for "!memory" blocks
+package risugen_x86_memory;
+
+use strict;
+use warnings;
+
+use risugen_common;
+use risugen_x86_asm;
+
+our @ISA    = qw(Exporter);
+our @EXPORT = qw(eval_memory_block);
+
+my %memory_opts;
+
+sub load(%)
+{
+    my (%args) = @_;
+
+    @memory_opts{keys %args} = values %args;
+    $memory_opts{is_write}   = 0;
+}
+
+sub store(%)
+{
+    my (%args) = @_;
+
+    @memory_opts{keys %args} = values %args;
+    $memory_opts{is_write}   = 1;
+}
+
+sub eval_memory_block(%)
+{
+    my (%args) = @_;
+    my $rec = $args{rec};
+    my $insn = $args{insn};
+    my $insnname = $rec->{name};
+    my $opcode = $insn->{opcode}{value};
+
+    # Setup reasonable defaults
+    %memory_opts           = ();
+    $memory_opts{size}     = 0;
+    $memory_opts{align}    = 1;
+    $memory_opts{disp}     = 0;
+    $memory_opts{ss}       = 0;
+    $memory_opts{value}    = 0;
+    $memory_opts{mask}     = 0;
+    $memory_opts{rollback} = 0;
+    $memory_opts{is_write} = 0;
+
+    if (defined $insn->{modrm}) {
+        my $modrm = $insn->{modrm};
+
+        $memory_opts{ss}     = $modrm->{ss}          if defined $modrm->{ss};
+        $memory_opts{index}  = $modrm->{index}       if defined $modrm->{index};
+        $memory_opts{vindex} = $modrm->{vindex}      if defined $modrm->{vindex};
+        $memory_opts{base}   = $modrm->{base}        if defined $modrm->{base};
+        $memory_opts{disp}   = $modrm->{disp}{value} if defined $modrm->{disp};
+
+        $memory_opts{rollback} = defined $modrm->{base};
+    }
+
+    my $memory = $rec->{blocks}{"memory"};
+    if (defined $memory) {
+        # Evaluate in an environment with variables set corresponding
+        # to the variable fields.
+        my %env = extract_fields($opcode, $rec);
+        # set the variable $_ to the instruction in question
+        $env{_} = $insn;
+
+        eval_block($insnname, "memory", $memory, \%env);
+    }
+    return %memory_opts;
+}
+
+1;
-- 
2.20.1


Re: [Qemu-devel] [RISU PATCH v3 05/18] risugen_x86_memory: add module
Posted by Richard Henderson 6 years, 6 months ago
On 7/11/19 3:32 PM, Jan Bobek wrote:
> +sub load(%)
> +{
> +    my (%args) = @_;
> +
> +    @memory_opts{keys %args} = values %args;
> +    $memory_opts{is_write}   = 0;
> +}
> +
> +sub store(%)
> +{
> +    my (%args) = @_;
> +
> +    @memory_opts{keys %args} = values %args;
> +    $memory_opts{is_write}   = 1;
> +}

I was thinking maybe we should add a mem() that allows a "store => $d", which
would simplify the "$d ? store(size => x) : load(size => x)" pattern.

Anyway, that's incremental improvement.

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~

Re: [Qemu-devel] [RISU PATCH v3 05/18] risugen_x86_memory: add module
Posted by Jan Bobek 6 years, 6 months ago
On 7/20/19 9:58 PM, Richard Henderson wrote:
> On 7/11/19 3:32 PM, Jan Bobek wrote:
>> +sub load(%)
>> +{
>> +    my (%args) = @_;
>> +
>> +    @memory_opts{keys %args} = values %args;
>> +    $memory_opts{is_write}   = 0;
>> +}
>> +
>> +sub store(%)
>> +{
>> +    my (%args) = @_;
>> +
>> +    @memory_opts{keys %args} = values %args;
>> +    $memory_opts{is_write}   = 1;
>> +}
> 
> I was thinking maybe we should add a mem() that allows a "store => $d", which
> would simplify the "$d ? store(size => x) : load(size => x)" pattern.
> 
> Anyway, that's incremental improvement.

It's possible. I suppose the reason why I did it like I did was that I
wanted the config file to be more descriptive: if you specify a
constraint like mem(store => 0, ...), it might not be immediately
clear that it actually means a load. It's not an issue when you know
the code, but if somebody were just browsing the x86.risu without
prior knowledge of anything, they might find it more cryptic.

Anyway, so much for my reasoning; I agree that it would make the
conditions simpler, so feel free to change it if you like.

-Jan