diff mbox series

[RISU,v3,05/18] risugen_x86_memory: add module

Message ID 20190711223300.6061-6-jan.bobek@gmail.com (mailing list archive)
State New, archived
Headers show
Series Support for generating x86 SIMD test images | expand

Commit Message

Jan Bobek July 11, 2019, 10:32 p.m. UTC
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

Comments

Richard Henderson July 21, 2019, 1:58 a.m. UTC | #1
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~
Jan Bobek July 22, 2019, 1:53 p.m. UTC | #2
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
diff mbox series

Patch

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;