⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gen_insn_test.pl

📁 The Valgrind distribution has multiple tools. The most popular is the memory checking tool (called M
💻 PL
📖 第 1 页 / 共 2 页
字号:
#!/usr/bin/perluse 5.006;use strict;use warnings;our %ArgTypes = (                 r8 => "reg8_t",                 r16 => "reg16_t",                 r32 => "reg32_t",                 mm => "reg64_t",                 xmm => "reg128_t",                 m8 => "reg8_t",                 m16 => "reg16_t",                 m32 => "reg32_t",                 m64 => "reg64_t",                 m128 => "reg128_t",                 eflags => "reg32_t",                 st => "reg64_t",                 fpucw => "reg16_t",                 fpusw => "reg16_t"                 );our %SubTypeFormats = (                       sb => "%d",                       ub => "%u",                       sw => "%d",                       uw => "%u",                       sd => "%ld",                       ud => "%lu",                       sq => "%lld",                       uq => "%llu",                       ps => "%.16g",                       pd => "%.16g"                       );our %SubTypeSuffixes = (                        sb => "",                        ub => "U",                        sw => "",                        uw => "",                        sd => "L",                        ud => "UL",                        sq => "LL",                        uq => "ULL",                        ps => "F",                        pd => ""                        );our %RegNums = (                al => 0, ax => 0, eax => 0,                bl => 1, bx => 1, ebx => 1,                cl => 2, cx => 2, ecx => 2,                dl => 3, dx => 3, edx => 3,                ah => 4,                bh => 5,                ch => 6,                dh => 7,                st0 => 0, st1 => 1, st2 => 2, st3 => 3,                st4 => 4, st5 => 5, st6 => 6, st7 => 7                );our %RegTypes = (                 al => "r8", ah => "r8", ax => "r16", eax => "r32",                 bl => "r8", bh => "r8", bx => "r16", ebx => "r32",                 cl => "r8", ch => "r8", cx => "r16", ecx => "r32",                 dl => "r8", dh => "r8", dx => "r16", edx => "r32"                 );our @IntRegs = (                { r8 => "al", r16 => "ax", r32 => "eax" },                { r8 => "bl", r16 => "bx", r32 => "ebx" },                { r8 => "cl", r16 => "cx", r32 => "ecx" },                { r8 => "dl", r16 => "dx", r32 => "edx" },                { r8 => "ah" },                { r8 => "bh" },                { r8 => "ch" },                { r8 => "dh" }                );print <<EOF;#include <math.h>#include <setjmp.h>#include <signal.h>#include <stdio.h>#include <stdlib.h>typedef union {  char sb[1];  unsigned char ub[1];} reg8_t;typedef union {  char sb[2];  unsigned char ub[2];  short sw[1];  unsigned short uw[1];} reg16_t;typedef union {  char sb[4];  unsigned char ub[4];  short sw[2];  unsigned short uw[2];  long int sd[1];  unsigned long int ud[1];  float ps[1];} reg32_t;typedef union {  char sb[8];  unsigned char ub[8];  short sw[4];  unsigned short uw[4];  long int sd[2];  unsigned long int ud[2];  long long int sq[1];  unsigned long long int uq[1];  float ps[2];  double pd[1];} reg64_t __attribute__ ((aligned (8)));typedef union {  char sb[16];  unsigned char ub[16];  short sw[8];  unsigned short uw[8];  long int sd[4];  unsigned long int ud[4];  long long int sq[2];  unsigned long long int uq[2];  float ps[4];  double pd[2];} reg128_t __attribute__ ((aligned (16)));static sigjmp_buf catchpoint;static void handle_sigill(int signum){   siglongjmp(catchpoint, 1);}__attribute__((unused))static int eq_float(float f1, float f2){   return f1 == f2 || fabsf(f1 - f2) < fabsf(f1) * 1.5 * pow(2,-12);}__attribute__((unused))static int eq_double(double d1, double d2){   return d1 == d2 || fabs(d1 - d2) < fabs(d1) * 1.5 * pow(2,-12);}EOFmy %tests;my @tests;while (<>){    next if /^#/;    my $insn;    my $presets;    my $args;    my $results;    if (/^(\S+)\s+(?:(\S+(?:\s+\S+)*)\s+:\s+)?((?:\S+\s+)*?)(?:=>\s+(\S+(?:\s+\S+)*))?$/)    {        $insn = $1;        $presets = $2 || "";        $args = $3 || "";        $results = $4 || "";#        print STDERR "insn: $insn\n";#        print STDERR "presets: $presets\n";#        print STDERR "args: $args\n";#        print STDERR "results: $results\n";    }    else    {        die "Can't parse test $_";    }        $tests{$insn}++;        my $test = "${insn}_$tests{$insn}";        push @tests, $test;        print qq|static void $test(void)\n|;    print qq|\{\n|;    my @intregs = @IntRegs;    my @mmregs  = map { "mm$_" }  (6,7,0,1,2,3,4,5);    my @xmmregs = map { "xmm$_" } (4,5,0,1,2,3,6,7);    my @fpregs  = map { "st$_" }  (0 .. 7);    my @presets;    my $presetc = 0;    my $eflagsmask;    my $eflagsset;    my $fpucwmask;    my $fpucwset;    my $fpuswmask;    my $fpuswset;    foreach my $preset (split(/\s+/, $presets))    {        if ($preset =~ /^([abcd][lh]|[abcd]x|e[abcd]x)\.(sb|ub|sw|uw|sd|ud|sq|uq|ps|pd)\[([^\]]+)\]$/)        {            my $name = "preset$presetc";            my $type = $RegTypes{$1};            my $regnum = $RegNums{$1};            my $register = $intregs[$regnum];            my $subtype = $2;            my @values = split(/,/, $3);                die "Register $1 already used" unless defined($register);            my $preset = {                name => $name,                type => $type,                subtype => $subtype,                register => $register            };            delete($intregs[$regnum]);            push @presets, $preset;                        print qq|   $ArgTypes{$type} $name = \{ .$subtype = \{|;                        my $valuec = 0;                        foreach my $value (@values)            {                print qq|,| if $valuec > 0;                print qq| $value$SubTypeSuffixes{$subtype}|;                $valuec++;            }                        print qq| \} \};\n|;            $presetc++;        }        elsif ($preset =~ /^st([0-9]+)\.(ps|pd)\[([^\]]+)\]$/)        {            my $name = "preset$presetc";            my $type = "st";            my $regnum = $1;            my $register = $fpregs[$regnum];            my $subtype = $2;            my @values = split(/,/, $3);            die "Register st$1 already used" unless defined($register);            my $preset = {                name => $name,                type => $type,                subtype => $subtype,                register => $register            };            delete($fpregs[$regnum]);            push @presets, $preset;                        print qq|   $ArgTypes{$type} $name = \{ .$subtype = \{|;                        my $valuec = 0;                        foreach my $value (@values)            {                print qq|,| if $valuec > 0;                print qq| $value$SubTypeSuffixes{$subtype}|;                $valuec++;            }                        print qq| \} \};\n|;            $presetc++;        }        elsif ($preset =~ /^(eflags)\[([^\]]+)\]$/)        {            my $type = $1;            my @values = split(/,/, $2);            $values[0] = oct($values[0]) if $values[0] =~ /^0/;            $values[1] = oct($values[1]) if $values[1] =~ /^0/;            $eflagsmask = sprintf "0x%08x", $values[0] ^ 0xffffffff;            $eflagsset = sprintf "0x%08x", $values[1];        }        elsif ($preset =~ /^(fpucw)\[([^\]]+)\]$/)        {            my $type = $1;            my @values = split(/,/, $2);            $values[0] = oct($values[0]) if $values[0] =~ /^0/;            $values[1] = oct($values[1]) if $values[1] =~ /^0/;            $fpucwmask = sprintf "0x%04x", $values[0] ^ 0xffff;            $fpucwset = sprintf "0x%04x", $values[1];        }        elsif ($preset =~ /^(fpusw)\[([^\]]+)\]$/)        {            my $type = $1;            my @values = split(/,/, $2);            $values[0] = oct($values[0]) if $values[0] =~ /^0/;            $values[1] = oct($values[1]) if $values[1] =~ /^0/;            $fpuswmask = sprintf "0x%04x", $values[0] ^ 0xffff;            $fpuswset = sprintf "0x%04x", $values[1];        }        else        {            die "Can't parse preset $preset";        }    }    my @args;    my $argc = 0;        foreach my $arg (split(/\s+/, $args))    {        my $name = "arg$argc";        if ($arg =~ /^([abcd]l|[abcd]x|e[abcd]x|r8|r16|r32|mm|xmm|m8|m16|m32|m64|m128)\.(sb|ub|sw|uw|sd|ud|sq|uq|ps|pd)\[([^\]]+)\]$/)        {            my $type = $RegTypes{$1} || $1;            my $regnum = $RegNums{$1};            my $register = $intregs[$regnum] if defined($regnum);            my $subtype = $2;            my @values = split(/,/, $3);                        die "Register $1 already used" if defined($regnum) && !defined($register);            my $arg = {                name => $name,                type => $type,                subtype => $subtype            };            if (defined($register))            {                $arg->{register} = $register;                delete($intregs[$regnum]);            }            push @args, $arg;                        print qq|   $ArgTypes{$type} $name = \{ .$subtype = \{|;                        my $valuec = 0;                        foreach my $value (@values)            {                print qq|,| if $valuec > 0;                print qq| $value$SubTypeSuffixes{$subtype}|;                $valuec++;            }            print qq| \} \};\n|;        }        elsif ($arg =~ /^st([0-9]+)\.(ps|pd)\[([^\]]+)\]$/)        {            my $type = "st";            my $regnum = $1;            my $register = $fpregs[$regnum] if defined($regnum);            my $subtype = $2;            my @values = split(/,/, $3);                        die "Register st$1 already used" if defined($regnum) && !defined($register);            my $arg = {                name => $name,                type => $type,                subtype => $subtype            };            if (defined($register))            {                $arg->{register} = $register;                delete($fpregs[$regnum]);            }            push @args, $arg;                        print qq|   $ArgTypes{$type} $name = \{ .$subtype = \{|;                        my $valuec = 0;                        foreach my $value (@values)            {                print qq|,| if $valuec > 0;                print qq| $value$SubTypeSuffixes{$subtype}|;                $valuec++;            }            print qq| \} \};\n|;        }        elsif ($arg =~ /^(imm8|imm16|imm32)\[([^\]]+)\]$/)        {            my $type = $1;            my $value = $2;                        my $arg = {                type => $type,                value => $value            };            push @args, $arg;        }        else        {            die "Can't parse argument $arg";        }        $argc++;    }        foreach my $arg (@presets, @args)    {        if ($arg->{type} =~ /^(r8|r16|r32|m8|m16|m32)$/)        {            while (!exists($arg->{register}) || !defined($arg->{register}))            {                $arg->{register} = shift @intregs;            }            $arg->{register} = $arg->{register}->{$arg->{type}};        }        elsif ($arg->{type} =~ /^(mm|m64)$/)        {            $arg->{register} = shift @mmregs;        }        elsif ($arg->{type} =~ /^(xmm|m128)$/)        {            $arg->{register} = shift @xmmregs;        }        elsif ($arg->{type} =~ /^st$/)        {            while (!exists($arg->{register}) || !defined($arg->{register}))            {                $arg->{register} = shift @fpregs;            }        }    }    my @results;    my $resultc = 0;        foreach my $result (split(/\s+/, $results))    {        my $name = "result$resultc";            if ($result =~ /^(\d+)\.(sb|ub|sw|uw|sd|ud|sq|uq|ps|pd)\[([^\]]+)\]$/)        {            my $index = $1;            my $type = $args[$index]->{type};            my $subtype = $2;            my @values = split(/,/, $3);                        die "Argument $index not specified" unless exists($args[$index]);            my $result = {                name => $name,                type => $type,                subtype => $subtype,                arg => $args[$index],                register => $args[$index]->{register},                values => [ @values ]            };            push @results, $result;            print qq|   $ArgTypes{$type} $name|;            print qq| = arg$index| if $type =~ /^m(8|16|32|64|128)$/;            print qq|;\n|;            $args[$index]->{result} = $result;        }        elsif ($result =~ /^([abcd][lh]|[abcd]x|e[abcd]x)\.(sb|ub|sw|uw|sd|ud|sq|uq|ps|pd)\[([^\]]+)\]$/)        {            my $register = $1;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -