Name

Nasm::X86 - Generate X86 assembler code using Perl as a macro pre-processor.

Synopsis

Write and execute x64 Avx512 assembler code from perl using perl as a powerful macro assembler. The generated code can be run under the Intel emulator to obtain execution trace and instruction counts.

Please see: https://github.com/philiprbrenan/NasmX86 for a complete working demonstration of how to run code produced by this module and foir examples of its use.

While this module allows you to intermix Perl and Assembler code it is noticeable that the more Perl code that is written the less new Assembler code is required because there are more opportunities to call a Perl routine to generate the required Assembler code rather than writing the Assembler out by hand.

Use Avx512 instructions to perform 64 comparisons in parallel.

  my $P = "2F";                                                                 # Value to test for
  my $l = Rb 0;  Rb $_ for 1..RegisterSize zmm0;                                # 0..63
  Vmovdqu8 zmm0, "[$l]";                                                        # Load data to test
  PrintOutRegisterInHex zmm0;

  Mov rax, "0x$P";                                                              # Broadcast the value to be tested
  Vpbroadcastb zmm1, rax;
  PrintOutRegisterInHex zmm1;

  for my $c(0..7)                                                               # Each possible test
   {my $m = "k$c";
    Vpcmpub $m, zmm1, zmm0, $c;
    PrintOutRegisterInHex $m;
   }

  Kmovq rax, k0;                                                                # Count the number of trailing zeros in k0
  Tzcnt rax, rax;
  PrintOutRegisterInHex rax;

  is_deeply Assemble, <<END;                                                    # Assemble and test
  zmm0: 3F3E 3D3C 3B3A 3938   3736 3534 3332 3130   2F2E 2D2C 2B2A 2928   2726 2524 2322 2120   1F1E 1D1C 1B1A 1918   1716 1514 1312 1110   0F0E 0D0C 0B0A 0908   0706 0504 0302 0100
  zmm1: 2F2F 2F2F 2F2F 2F2F   2F2F 2F2F 2F2F 2F2F   2F2F 2F2F 2F2F 2F2F   2F2F 2F2F 2F2F 2F2F   2F2F 2F2F 2F2F 2F2F   2F2F 2F2F 2F2F 2F2F   2F2F 2F2F 2F2F 2F2F   2F2F 2F2F 2F2F 2F2F
    k0: 0000 8000 0000 0000
    k1: FFFF 0000 0000 0000
    k2: FFFF 8000 0000 0000
    k3: 0000 0000 0000 0000
    k4: FFFF 7FFF FFFF FFFF
    k5: 0000 FFFF FFFF FFFF
    k6: 0000 7FFF FFFF FFFF
    k7: FFFF FFFF FFFF FFFF
   rax: 0000 0000 0000 002F
END

With the print statements removed, the Intel Emulator indicates that 26 instructions were executed:

  CALL_NEAR                                                              1
  ENTER                                                                  2
  JMP                                                                    1
  KMOVQ                                                                  1
  MOV                                                                    5
  POP                                                                    1
  PUSH                                                                   3
  SYSCALL                                                                1
  TZCNT                                                                  1
  VMOVDQU8                                                               1
  VPBROADCASTB                                                           1
  VPCMPUB                                                                8

  *total                                                                26

Description

Generate X86 assembler code using Perl as a macro pre-processor.

Version "20220712".

The following sections describe the methods in each functional area of this module. For an alphabetic listing of all methods by name see Index.

Labels

Create and set labels.

Label()

Create a unique label. Useful for constructing for and if statements.

Example:

    Mov rax, 1;
    Mov rdi, 1;
    SaveFirstFour;
    Mov rax, 2;
    Mov rdi, 2;
    SaveFirstSeven;
    Mov rax, 3;
    Mov rdi, 4;
    PrintOutRegisterInHex rax, rdi;
    RestoreFirstSeven;
    PrintOutRegisterInHex rax, rdi;
    RestoreFirstFour;
    PrintOutRegisterInHex rax, rdi;

    SaveFirstFour;
    Mov rax, 2;
    Mov rdi, 2;
    SaveFirstSeven;
    Mov rax, 3;
    Mov rdi, 4;
    PrintOutRegisterInHex rax, rdi;
    RestoreFirstSevenExceptRax;
    PrintOutRegisterInHex rax, rdi;
    RestoreFirstFourExceptRax;
    PrintOutRegisterInHex rax, rdi;

    SaveFirstFour;
    Mov rax, 2;
    Mov rdi, 2;
    SaveFirstSeven;
    Mov rax, 3;
    Mov rdi, 4;
    PrintOutRegisterInHex rax, rdi;

    Bswap rax;
    PrintOutRegisterInHex rax;


    my $l = Label;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    Jmp $l;
    SetLabel $l;

    ok Assemble eq => <<END, avx512=>0;
     rax: .... .... .... ...3
     rdi: .... .... .... ...4
     rax: .... .... .... ...2
     rdi: .... .... .... ...2
     rax: .... .... .... ...1
     rdi: .... .... .... ...1
     rax: .... .... .... ...3
     rdi: .... .... .... ...4
     rax: .... .... .... ...3
     rdi: .... .... .... ...2
     rax: .... .... .... ...3
     rdi: .... .... .... ...1
     rax: .... .... .... ...3
     rdi: .... .... .... ...4
     rax: .3.. .... .... ....
  END

    ok 8 == RegisterSize rax;

SetLabel($l)

Create (if necessary) and set a label in the code section returning the label so set.

     Parameter  Description
  1  $l         Label

Example:

    Mov rax, 1;
    Mov rdi, 1;
    SaveFirstFour;
    Mov rax, 2;
    Mov rdi, 2;
    SaveFirstSeven;
    Mov rax, 3;
    Mov rdi, 4;
    PrintOutRegisterInHex rax, rdi;
    RestoreFirstSeven;
    PrintOutRegisterInHex rax, rdi;
    RestoreFirstFour;
    PrintOutRegisterInHex rax, rdi;

    SaveFirstFour;
    Mov rax, 2;
    Mov rdi, 2;
    SaveFirstSeven;
    Mov rax, 3;
    Mov rdi, 4;
    PrintOutRegisterInHex rax, rdi;
    RestoreFirstSevenExceptRax;
    PrintOutRegisterInHex rax, rdi;
    RestoreFirstFourExceptRax;
    PrintOutRegisterInHex rax, rdi;

    SaveFirstFour;
    Mov rax, 2;
    Mov rdi, 2;
    SaveFirstSeven;
    Mov rax, 3;
    Mov rdi, 4;
    PrintOutRegisterInHex rax, rdi;

    Bswap rax;
    PrintOutRegisterInHex rax;

    my $l = Label;
    Jmp $l;

    SetLabel $l;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲


    ok Assemble eq => <<END, avx512=>0;
     rax: .... .... .... ...3
     rdi: .... .... .... ...4
     rax: .... .... .... ...2
     rdi: .... .... .... ...2
     rax: .... .... .... ...1
     rdi: .... .... .... ...1
     rax: .... .... .... ...3
     rdi: .... .... .... ...4
     rax: .... .... .... ...3
     rdi: .... .... .... ...2
     rax: .... .... .... ...3
     rdi: .... .... .... ...1
     rax: .... .... .... ...3
     rdi: .... .... .... ...4
     rax: .3.. .... .... ....
  END

    ok 8 == RegisterSize rax;

Data

Layout data

Global variables

Create variables in the data segment if you are willing to make your program non reentrant.

Ds(@d)

Layout bytes in memory and return their label.

     Parameter  Description
  1  @d         Data to be laid out

Example:

    my $q = Rs('a'..'z');

    Mov rax, Ds('0'x64);                                                          # Output area  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    Vmovdqu32(xmm0, "[$q]");                                                      # Load
    Vprolq   (xmm0,   xmm0, 32);                                                  # Rotate double words in quad words
    Vmovdqu32("[rax]", xmm0);                                                     # Save
    Mov rdi, 16;
    PrintOutMemoryNL;

    ok Assemble eq=><<END;
  efghabcdmnopijkl
  END

Db(@bytes)

Layout bytes in the data segment and return their label.

     Parameter  Description
  1  @bytes     Bytes to layout

Example:

    my $s = Rb 0; Rb 1; Rw 2; Rd 3;  Rq 4;

    my $t = Db 0; Db 1; Dw 2; Dd 3;  Dq 4;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲


    Vmovdqu8 xmm0, "[$s]";
    Vmovdqu8 xmm1, "[$t]";
    PrintOutRegisterInHex xmm0;
    PrintOutRegisterInHex xmm1;
    Sub rsp, 16;

    Mov rax, rsp;                                                                 # Copy memory, the target is addressed by rax, the length is in rdi, the source is addressed by rsi
    Mov rdi, 16;
    Mov rsi, $s;
    CopyMemory(V(source => rsi), V(target => rax), V size => rdi);
    PrintOutMemory_InHexNL;

    ok Assemble eq => <<END;
    xmm0: .... .... .... ...4  .... ...3 ...2 .1..
    xmm1: .... .... .... ...4  .... ...3 ...2 .1..
  __.1 .2__ .3__ ____  .4__ ____ ____ ____
  END

Dw(@words)

Layout words in the data segment and return their label.

     Parameter  Description
  1  @words     Words to layout

Example:

    my $s = Rb 0; Rb 1; Rw 2; Rd 3;  Rq 4;

    my $t = Db 0; Db 1; Dw 2; Dd 3;  Dq 4;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲


    Vmovdqu8 xmm0, "[$s]";
    Vmovdqu8 xmm1, "[$t]";
    PrintOutRegisterInHex xmm0;
    PrintOutRegisterInHex xmm1;
    Sub rsp, 16;

    Mov rax, rsp;                                                                 # Copy memory, the target is addressed by rax, the length is in rdi, the source is addressed by rsi
    Mov rdi, 16;
    Mov rsi, $s;
    CopyMemory(V(source => rsi), V(target => rax), V size => rdi);
    PrintOutMemory_InHexNL;

    ok Assemble eq => <<END;
    xmm0: .... .... .... ...4  .... ...3 ...2 .1..
    xmm1: .... .... .... ...4  .... ...3 ...2 .1..
  __.1 .2__ .3__ ____  .4__ ____ ____ ____
  END

Dd(@dwords)

Layout double words in the data segment and return their label.

     Parameter  Description
  1  @dwords    Double words to layout

Example:

    my $s = Rb 0; Rb 1; Rw 2; Rd 3;  Rq 4;

    my $t = Db 0; Db 1; Dw 2; Dd 3;  Dq 4;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲


    Vmovdqu8 xmm0, "[$s]";
    Vmovdqu8 xmm1, "[$t]";
    PrintOutRegisterInHex xmm0;
    PrintOutRegisterInHex xmm1;
    Sub rsp, 16;

    Mov rax, rsp;                                                                 # Copy memory, the target is addressed by rax, the length is in rdi, the source is addressed by rsi
    Mov rdi, 16;
    Mov rsi, $s;
    CopyMemory(V(source => rsi), V(target => rax), V size => rdi);
    PrintOutMemory_InHexNL;

    ok Assemble eq => <<END;
    xmm0: .... .... .... ...4  .... ...3 ...2 .1..
    xmm1: .... .... .... ...4  .... ...3 ...2 .1..
  __.1 .2__ .3__ ____  .4__ ____ ____ ____
  END

Dq(@qwords)

Layout quad words in the data segment and return their label.

     Parameter  Description
  1  @qwords    Quad words to layout

Example:

    my $s = Rb 0; Rb 1; Rw 2; Rd 3;  Rq 4;

    my $t = Db 0; Db 1; Dw 2; Dd 3;  Dq 4;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲


    Vmovdqu8 xmm0, "[$s]";
    Vmovdqu8 xmm1, "[$t]";
    PrintOutRegisterInHex xmm0;
    PrintOutRegisterInHex xmm1;
    Sub rsp, 16;

    Mov rax, rsp;                                                                 # Copy memory, the target is addressed by rax, the length is in rdi, the source is addressed by rsi
    Mov rdi, 16;
    Mov rsi, $s;
    CopyMemory(V(source => rsi), V(target => rax), V size => rdi);
    PrintOutMemory_InHexNL;

    ok Assemble eq => <<END;
    xmm0: .... .... .... ...4  .... ...3 ...2 .1..
    xmm1: .... .... .... ...4  .... ...3 ...2 .1..
  __.1 .2__ .3__ ____  .4__ ____ ____ ____
  END

Global constants

Create constants in read only memory,

Rb(@bytes)

Layout bytes in the data segment and return their label.

     Parameter  Description
  1  @bytes     Bytes to layout

Example:

    my $s = Rb 0; Rb 1; Rw 2; Rd 3;  Rq 4;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    my $t = Db 0; Db 1; Dw 2; Dd 3;  Dq 4;

    Vmovdqu8 xmm0, "[$s]";
    Vmovdqu8 xmm1, "[$t]";
    PrintOutRegisterInHex xmm0;
    PrintOutRegisterInHex xmm1;
    Sub rsp, 16;

    Mov rax, rsp;                                                                 # Copy memory, the target is addressed by rax, the length is in rdi, the source is addressed by rsi
    Mov rdi, 16;
    Mov rsi, $s;
    CopyMemory(V(source => rsi), V(target => rax), V size => rdi);
    PrintOutMemory_InHexNL;

    ok Assemble eq => <<END;
    xmm0: .... .... .... ...4  .... ...3 ...2 .1..
    xmm1: .... .... .... ...4  .... ...3 ...2 .1..
  __.1 .2__ .3__ ____  .4__ ____ ____ ____
  END

Rw(@words)

Layout words in the data segment and return their label.

     Parameter  Description
  1  @words     Words to layout

Example:

    my $s = Rb 0; Rb 1; Rw 2; Rd 3;  Rq 4;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    my $t = Db 0; Db 1; Dw 2; Dd 3;  Dq 4;

    Vmovdqu8 xmm0, "[$s]";
    Vmovdqu8 xmm1, "[$t]";
    PrintOutRegisterInHex xmm0;
    PrintOutRegisterInHex xmm1;
    Sub rsp, 16;

    Mov rax, rsp;                                                                 # Copy memory, the target is addressed by rax, the length is in rdi, the source is addressed by rsi
    Mov rdi, 16;
    Mov rsi, $s;
    CopyMemory(V(source => rsi), V(target => rax), V size => rdi);
    PrintOutMemory_InHexNL;

    ok Assemble eq => <<END;
    xmm0: .... .... .... ...4  .... ...3 ...2 .1..
    xmm1: .... .... .... ...4  .... ...3 ...2 .1..
  __.1 .2__ .3__ ____  .4__ ____ ____ ____
  END

Rd(@dwords)

Layout double words in the data segment and return their label.

     Parameter  Description
  1  @dwords    Double words to layout

Example:

    my $s = Rb 0; Rb 1; Rw 2; Rd 3;  Rq 4;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    my $t = Db 0; Db 1; Dw 2; Dd 3;  Dq 4;

    Vmovdqu8 xmm0, "[$s]";
    Vmovdqu8 xmm1, "[$t]";
    PrintOutRegisterInHex xmm0;
    PrintOutRegisterInHex xmm1;
    Sub rsp, 16;

    Mov rax, rsp;                                                                 # Copy memory, the target is addressed by rax, the length is in rdi, the source is addressed by rsi
    Mov rdi, 16;
    Mov rsi, $s;
    CopyMemory(V(source => rsi), V(target => rax), V size => rdi);
    PrintOutMemory_InHexNL;

    ok Assemble eq => <<END;
    xmm0: .... .... .... ...4  .... ...3 ...2 .1..
    xmm1: .... .... .... ...4  .... ...3 ...2 .1..
  __.1 .2__ .3__ ____  .4__ ____ ____ ____
  END

Rq(@qwords)

Layout quad words in the data segment and return their label.

     Parameter  Description
  1  @qwords    Quad words to layout

Example:

    my $s = Rb 0; Rb 1; Rw 2; Rd 3;  Rq 4;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    my $t = Db 0; Db 1; Dw 2; Dd 3;  Dq 4;

    Vmovdqu8 xmm0, "[$s]";
    Vmovdqu8 xmm1, "[$t]";
    PrintOutRegisterInHex xmm0;
    PrintOutRegisterInHex xmm1;
    Sub rsp, 16;

    Mov rax, rsp;                                                                 # Copy memory, the target is addressed by rax, the length is in rdi, the source is addressed by rsi
    Mov rdi, 16;
    Mov rsi, $s;
    CopyMemory(V(source => rsi), V(target => rax), V size => rdi);
    PrintOutMemory_InHexNL;

    ok Assemble eq => <<END;
    xmm0: .... .... .... ...4  .... ...3 ...2 .1..
    xmm1: .... .... .... ...4  .... ...3 ...2 .1..
  __.1 .2__ .3__ ____  .4__ ____ ____ ____
  END

Rs(@d)

Layout bytes in read only memory and return their label.

     Parameter  Description
  1  @d         Data to be laid out

Example:

    Comment "Print a string from memory";
    my $s = "Hello World";

    Mov rax, Rs($s);  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    Mov rdi, length $s;
    PrintOutMemory;
    Exit(0);

    ok Assemble(avx512=>0) =~ m(Hello World);


    my $q = Rs('abababab');  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    Mov r10, 0x10;
    Mov r11, 0x11;
    Mov r12, 0x12;
    Mov r13, 0x13;
    Mov r14, 0x14;
    Mov r15, 0x15;
    Mov  r8, 0x08;
    Mov  r9, 0x09;
    Mov rax, 1;
    Mov rbx, 2;
    Mov rcx, 3;
    Mov rdi, 4;
    Mov rdx, 5;
    Mov rsi, 6;
    PrintOutRegistersInHex;

    my $r = Assemble avx512=>0, eq=><<END;
  rfl: .... .... .... .2.2
  r10: .... .... .... ..10
  r11: .... .... .... .2.6
  r12: .... .... .... ..12
  r13: .... .... .... ..13
  r14: .... .... .... ..14
  r15: .... .... .... ..15
   r8: .... .... .... ...8
   r9: .... .... .... ...9
  rax: .... .... .... ...1
  rbx: .... .... .... ...2
  rcx: .... .... ..40 197F
  rdi: .... .... .... ...4
  rdx: .... .... .... ...5
  rsi: .... .... .... ...6
  END

Rutf8(@d)

Layout a utf8 encoded string as bytes in read only memory and return their label.

     Parameter  Description
  1  @d         Data to be laid out

Example:

    my ($out, $size, $fail);

    my $Chars = Rb(0x24, 0xc2, 0xa2, 0xc9, 0x91, 0xE2, 0x82, 0xAC, 0xF0, 0x90, 0x8D, 0x88);
    my $chars = V(chars => $Chars);

   ($out, $size, $fail) = GetNextUtf8CharAsUtf32 $chars+0;                        # Dollar               UTF-8 Encoding: 0x24                UTF-32 Encoding: 0x00000024
    $out->out('out1 : ');
    $size->outNL(' size : ');

   ($out, $size, $fail) = GetNextUtf8CharAsUtf32 $chars+1;                        # Cents                UTF-8 Encoding: 0xC2 0xA2           UTF-32 Encoding: 0x000000a2
    $out->out('out2 : ');     $size->outNL(' size : ');

   ($out, $size, $fail) = GetNextUtf8CharAsUtf32 $chars+3;                        # Alpha                UTF-8 Encoding: 0xC9 0x91           UTF-32 Encoding: 0x00000251
    $out->out('out3 : ');     $size->outNL(' size : ');

   ($out, $size, $fail) = GetNextUtf8CharAsUtf32 $chars+5;                        # Euro                 UTF-8 Encoding: 0xE2 0x82 0xAC      UTF-32 Encoding: 0x000020AC
    $out->out('out4 : ');     $size->outNL(' size : ');

   ($out, $size, $fail) = GetNextUtf8CharAsUtf32 $chars+8;                        # Gothic Letter Hwair  UTF-8 Encoding  0xF0 0x90 0x8D 0x88 UTF-32 Encoding: 0x00010348
    $out->out('out5 : ');     $size->outNL(' size : ');

    my $statement = qq(𝖺
 𝑎𝑠𝑠𝑖𝑔𝑛 【【𝖻 𝐩𝐥𝐮𝐬 𝖼】】
AAAAAAAA);                        # A sample sentence to parse


    my $s = K(statement => Rutf8($statement));  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    my $l = StringLength $s;

    my $address = AllocateMemory $l;                                              # Allocate enough memory for a copy of the string
    CopyMemory($s, $address, $l);

   ($out, $size, $fail) = GetNextUtf8CharAsUtf32 $address;
    $out->out('outA : ');     $size->outNL(' size : ');

   ($out, $size, $fail) = GetNextUtf8CharAsUtf32 $address+4;
    $out->out('outB : ');     $size->outNL(' size : ');

   ($out, $size, $fail) = GetNextUtf8CharAsUtf32 $address+5;
    $out->out('outC : ');     $size->outNL(' size : ');

   ($out, $size, $fail) = GetNextUtf8CharAsUtf32 $address+30;
    $out->out('outD : ');     $size->outNL(' size : ');

   ($out, $size, $fail) = GetNextUtf8CharAsUtf32 $address+35;
    $out->out('outE : ');     $size->outNL(' size : ');

    $address->printOutMemoryInHexNL($l);

    ok Assemble(debug => 0, eq => <<END, avx512=>0);
  out1 : .... .... .... ..24 size : .... .... .... ...1
  out2 : .... .... .... ..A2 size : .... .... .... ...2
  out3 : .... .... .... .251 size : .... .... .... ...2
  out4 : .... .... .... 20AC size : .... .... .... ...3
  out5 : .... .... ...1 .348 size : .... .... .... ...4
  outA : .... .... ...1 D5BA size : .... .... .... ...4
  outB : .... .... .... ...A size : .... .... .... ...1
  outC : .... .... .... ..20 size : .... .... .... ...1
  outD : .... .... .... ..20 size : .... .... .... ...1
  outE : .... .... .... ..10 size : .... .... .... ...2
  F09D 96BA .A20 F09D  918E F09D 91A0 F09D  91A0 F09D 9196 F09D  9194 F09D 919B 20E3  8090 E380 90F0 9D96  BB20 F09D 90A9 F09D  90A5 F09D 90AE F09D  90AC 20F0 9D96 BCE3  8091 E380 91.A 4141  4141 4141 4141 ....
  END

Registers

Operations on registers

Size

Sizes of each register

RegisterSize($R)

Return the size of a register.

     Parameter  Description
  1  $R         Register

Example:

    Mov rax, 1;
    Mov rdi, 1;
    SaveFirstFour;
    Mov rax, 2;
    Mov rdi, 2;
    SaveFirstSeven;
    Mov rax, 3;
    Mov rdi, 4;
    PrintOutRegisterInHex rax, rdi;
    RestoreFirstSeven;
    PrintOutRegisterInHex rax, rdi;
    RestoreFirstFour;
    PrintOutRegisterInHex rax, rdi;

    SaveFirstFour;
    Mov rax, 2;
    Mov rdi, 2;
    SaveFirstSeven;
    Mov rax, 3;
    Mov rdi, 4;
    PrintOutRegisterInHex rax, rdi;
    RestoreFirstSevenExceptRax;
    PrintOutRegisterInHex rax, rdi;
    RestoreFirstFourExceptRax;
    PrintOutRegisterInHex rax, rdi;

    SaveFirstFour;
    Mov rax, 2;
    Mov rdi, 2;
    SaveFirstSeven;
    Mov rax, 3;
    Mov rdi, 4;
    PrintOutRegisterInHex rax, rdi;

    Bswap rax;
    PrintOutRegisterInHex rax;

    my $l = Label;
    Jmp $l;
    SetLabel $l;

    ok Assemble eq => <<END, avx512=>0;
     rax: .... .... .... ...3
     rdi: .... .... .... ...4
     rax: .... .... .... ...2
     rdi: .... .... .... ...2
     rax: .... .... .... ...1
     rdi: .... .... .... ...1
     rax: .... .... .... ...3
     rdi: .... .... .... ...4
     rax: .... .... .... ...3
     rdi: .... .... .... ...2
     rax: .... .... .... ...3
     rdi: .... .... .... ...1
     rax: .... .... .... ...3
     rdi: .... .... .... ...4
     rax: .3.. .... .... ....
  END


    ok 8 == RegisterSize rax;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

Push and Pop

Generic versions of push and pop with pop popping the last push.

PushR(@r)

Push registers onto the stack.

     Parameter  Description
  1  @r         Registers

Example:

    Mov rax, 0x11111111;
    Mov rbx, 0x22222222;

    PushR my @save = (rax, rbx);  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    Mov rax, 0x33333333;
    PopR;
    PrintOutRegisterInHex rax;
    PrintOutRegisterInHex rbx;

    ok Assemble eq => <<END, avx512=>0;
     rax: .... .... 1111 1111
     rbx: .... .... 2222 2222
  END

    LoadZmm(17, 0x10..0x50);
    PrintOutRegisterInHex zmm17;
    Mov r14, 2; Mov r15, 3;
    PrintOutRegisterInHex r14, r15;

    PushR 14, 15, 16..31;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    LoadZmm(17, 0x20..0x70);
    PrintOutRegisterInHex zmm17;
    Mov r14, 22; Mov r15, 33;
    PopR;
    PrintOutRegisterInHex zmm17;
    PrintOutRegisterInHex r14, r15;
    ok Assemble eq => <<END, avx512=>1;
   zmm17: 4F4E 4D4C 4B4A 4948  4746 4544 4342 4140 - 3F3E 3D3C 3B3A 3938  3736 3534 3332 3130 + 2F2E 2D2C 2B2A 2928  2726 2524 2322 2120 - 1F1E 1D1C 1B1A 1918  1716 1514 1312 1110
     r14: .... .... .... ...2
     r15: .... .... .... ...3
   zmm17: 5F5E 5D5C 5B5A 5958  5756 5554 5352 5150 - 4F4E 4D4C 4B4A 4948  4746 4544 4342 4140 + 3F3E 3D3C 3B3A 3938  3736 3534 3332 3130 - 2F2E 2D2C 2B2A 2928  2726 2524 2322 2120
   zmm17: 4F4E 4D4C 4B4A 4948  4746 4544 4342 4140 - 3F3E 3D3C 3B3A 3938  3736 3534 3332 3130 + 2F2E 2D2C 2B2A 2928  2726 2524 2322 2120 - 1F1E 1D1C 1B1A 1918  1716 1514 1312 1110
     r14: .... .... .... ...2
     r15: .... .... .... ...3
  END

PopR(@r)

Pop registers from the stack. Use the last stored set if none explicitly supplied. Pops are done in reverse order to match the original pushing order.

     Parameter  Description
  1  @r         Register

Example:

    Mov rax, 0x11111111;
    Mov rbx, 0x22222222;
    PushR my @save = (rax, rbx);
    Mov rax, 0x33333333;

    PopR;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    PrintOutRegisterInHex rax;
    PrintOutRegisterInHex rbx;

    ok Assemble eq => <<END, avx512=>0;
     rax: .... .... 1111 1111
     rbx: .... .... 2222 2222
  END

    LoadZmm(17, 0x10..0x50);
    PrintOutRegisterInHex zmm17;
    Mov r14, 2; Mov r15, 3;
    PrintOutRegisterInHex r14, r15;
    PushR 14, 15, 16..31;
    LoadZmm(17, 0x20..0x70);
    PrintOutRegisterInHex zmm17;
    Mov r14, 22; Mov r15, 33;

    PopR;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    PrintOutRegisterInHex zmm17;
    PrintOutRegisterInHex r14, r15;
    ok Assemble eq => <<END, avx512=>1;
   zmm17: 4F4E 4D4C 4B4A 4948  4746 4544 4342 4140 - 3F3E 3D3C 3B3A 3938  3736 3534 3332 3130 + 2F2E 2D2C 2B2A 2928  2726 2524 2322 2120 - 1F1E 1D1C 1B1A 1918  1716 1514 1312 1110
     r14: .... .... .... ...2
     r15: .... .... .... ...3
   zmm17: 5F5E 5D5C 5B5A 5958  5756 5554 5352 5150 - 4F4E 4D4C 4B4A 4948  4746 4544 4342 4140 + 3F3E 3D3C 3B3A 3938  3736 3534 3332 3130 - 2F2E 2D2C 2B2A 2928  2726 2524 2322 2120
   zmm17: 4F4E 4D4C 4B4A 4948  4746 4544 4342 4140 - 3F3E 3D3C 3B3A 3938  3736 3534 3332 3130 + 2F2E 2D2C 2B2A 2928  2726 2524 2322 2120 - 1F1E 1D1C 1B1A 1918  1716 1514 1312 1110
     r14: .... .... .... ...2
     r15: .... .... .... ...3
  END

Save and Restore

Saving and restoring registers via the stack

SaveFirstFour(@keep)

Save the first 4 parameter registers making any parameter registers read only.

     Parameter  Description
  1  @keep      Registers to mark as read only

Example:

    Mov rax, 1;
    Mov rdi, 1;

    SaveFirstFour;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    Mov rax, 2;
    Mov rdi, 2;
    SaveFirstSeven;
    Mov rax, 3;
    Mov rdi, 4;
    PrintOutRegisterInHex rax, rdi;
    RestoreFirstSeven;
    PrintOutRegisterInHex rax, rdi;
    RestoreFirstFour;
    PrintOutRegisterInHex rax, rdi;


    SaveFirstFour;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    Mov rax, 2;
    Mov rdi, 2;
    SaveFirstSeven;
    Mov rax, 3;
    Mov rdi, 4;
    PrintOutRegisterInHex rax, rdi;
    RestoreFirstSevenExceptRax;
    PrintOutRegisterInHex rax, rdi;
    RestoreFirstFourExceptRax;
    PrintOutRegisterInHex rax, rdi;


    SaveFirstFour;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    Mov rax, 2;
    Mov rdi, 2;
    SaveFirstSeven;
    Mov rax, 3;
    Mov rdi, 4;
    PrintOutRegisterInHex rax, rdi;

    Bswap rax;
    PrintOutRegisterInHex rax;

    my $l = Label;
    Jmp $l;
    SetLabel $l;

    ok Assemble eq => <<END, avx512=>0;
     rax: .... .... .... ...3
     rdi: .... .... .... ...4
     rax: .... .... .... ...2
     rdi: .... .... .... ...2
     rax: .... .... .... ...1
     rdi: .... .... .... ...1
     rax: .... .... .... ...3
     rdi: .... .... .... ...4
     rax: .... .... .... ...3
     rdi: .... .... .... ...2
     rax: .... .... .... ...3
     rdi: .... .... .... ...1
     rax: .... .... .... ...3
     rdi: .... .... .... ...4
     rax: .3.. .... .... ....
  END

    ok 8 == RegisterSize rax;

RestoreFirstFour()

Restore the first 4 parameter registers.

Example:

    Mov rax, 1;
    Mov rdi, 1;
    SaveFirstFour;
    Mov rax, 2;
    Mov rdi, 2;
    SaveFirstSeven;
    Mov rax, 3;
    Mov rdi, 4;
    PrintOutRegisterInHex rax, rdi;
    RestoreFirstSeven;
    PrintOutRegisterInHex rax, rdi;

    RestoreFirstFour;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    PrintOutRegisterInHex rax, rdi;

    SaveFirstFour;
    Mov rax, 2;
    Mov rdi, 2;
    SaveFirstSeven;
    Mov rax, 3;
    Mov rdi, 4;
    PrintOutRegisterInHex rax, rdi;
    RestoreFirstSevenExceptRax;
    PrintOutRegisterInHex rax, rdi;
    RestoreFirstFourExceptRax;
    PrintOutRegisterInHex rax, rdi;

    SaveFirstFour;
    Mov rax, 2;
    Mov rdi, 2;
    SaveFirstSeven;
    Mov rax, 3;
    Mov rdi, 4;
    PrintOutRegisterInHex rax, rdi;

    Bswap rax;
    PrintOutRegisterInHex rax;

    my $l = Label;
    Jmp $l;
    SetLabel $l;

    ok Assemble eq => <<END, avx512=>0;
     rax: .... .... .... ...3
     rdi: .... .... .... ...4
     rax: .... .... .... ...2
     rdi: .... .... .... ...2
     rax: .... .... .... ...1
     rdi: .... .... .... ...1
     rax: .... .... .... ...3
     rdi: .... .... .... ...4
     rax: .... .... .... ...3
     rdi: .... .... .... ...2
     rax: .... .... .... ...3
     rdi: .... .... .... ...1
     rax: .... .... .... ...3
     rdi: .... .... .... ...4
     rax: .3.. .... .... ....
  END

    ok 8 == RegisterSize rax;

RestoreFirstFourExceptRax()

Restore the first 4 parameter registers except rax so it can return its value.

Example:

    Mov rax, 1;
    Mov rdi, 1;
    SaveFirstFour;
    Mov rax, 2;
    Mov rdi, 2;
    SaveFirstSeven;
    Mov rax, 3;
    Mov rdi, 4;
    PrintOutRegisterInHex rax, rdi;
    RestoreFirstSeven;
    PrintOutRegisterInHex rax, rdi;
    RestoreFirstFour;
    PrintOutRegisterInHex rax, rdi;

    SaveFirstFour;
    Mov rax, 2;
    Mov rdi, 2;
    SaveFirstSeven;
    Mov rax, 3;
    Mov rdi, 4;
    PrintOutRegisterInHex rax, rdi;
    RestoreFirstSevenExceptRax;
    PrintOutRegisterInHex rax, rdi;

    RestoreFirstFourExceptRax;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    PrintOutRegisterInHex rax, rdi;

    SaveFirstFour;
    Mov rax, 2;
    Mov rdi, 2;
    SaveFirstSeven;
    Mov rax, 3;
    Mov rdi, 4;
    PrintOutRegisterInHex rax, rdi;

    Bswap rax;
    PrintOutRegisterInHex rax;

    my $l = Label;
    Jmp $l;
    SetLabel $l;

    ok Assemble eq => <<END, avx512=>0;
     rax: .... .... .... ...3
     rdi: .... .... .... ...4
     rax: .... .... .... ...2
     rdi: .... .... .... ...2
     rax: .... .... .... ...1
     rdi: .... .... .... ...1
     rax: .... .... .... ...3
     rdi: .... .... .... ...4
     rax: .... .... .... ...3
     rdi: .... .... .... ...2
     rax: .... .... .... ...3
     rdi: .... .... .... ...1
     rax: .... .... .... ...3
     rdi: .... .... .... ...4
     rax: .3.. .... .... ....
  END

    ok 8 == RegisterSize rax;

SaveFirstSeven()

Save the first 7 parameter registers.

Example:

    Mov rax, 1;
    Mov rdi, 1;
    SaveFirstFour;
    Mov rax, 2;
    Mov rdi, 2;

    SaveFirstSeven;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    Mov rax, 3;
    Mov rdi, 4;
    PrintOutRegisterInHex rax, rdi;
    RestoreFirstSeven;
    PrintOutRegisterInHex rax, rdi;
    RestoreFirstFour;
    PrintOutRegisterInHex rax, rdi;

    SaveFirstFour;
    Mov rax, 2;
    Mov rdi, 2;

    SaveFirstSeven;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    Mov rax, 3;
    Mov rdi, 4;
    PrintOutRegisterInHex rax, rdi;
    RestoreFirstSevenExceptRax;
    PrintOutRegisterInHex rax, rdi;
    RestoreFirstFourExceptRax;
    PrintOutRegisterInHex rax, rdi;

    SaveFirstFour;
    Mov rax, 2;
    Mov rdi, 2;

    SaveFirstSeven;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    Mov rax, 3;
    Mov rdi, 4;
    PrintOutRegisterInHex rax, rdi;

    Bswap rax;
    PrintOutRegisterInHex rax;

    my $l = Label;
    Jmp $l;
    SetLabel $l;

    ok Assemble eq => <<END, avx512=>0;
     rax: .... .... .... ...3
     rdi: .... .... .... ...4
     rax: .... .... .... ...2
     rdi: .... .... .... ...2
     rax: .... .... .... ...1
     rdi: .... .... .... ...1
     rax: .... .... .... ...3
     rdi: .... .... .... ...4
     rax: .... .... .... ...3
     rdi: .... .... .... ...2
     rax: .... .... .... ...3
     rdi: .... .... .... ...1
     rax: .... .... .... ...3
     rdi: .... .... .... ...4
     rax: .3.. .... .... ....
  END

    ok 8 == RegisterSize rax;

RestoreFirstSeven()

Restore the first 7 parameter registers.

Example:

    Mov rax, 1;
    Mov rdi, 1;
    SaveFirstFour;
    Mov rax, 2;
    Mov rdi, 2;
    SaveFirstSeven;
    Mov rax, 3;
    Mov rdi, 4;
    PrintOutRegisterInHex rax, rdi;

    RestoreFirstSeven;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    PrintOutRegisterInHex rax, rdi;
    RestoreFirstFour;
    PrintOutRegisterInHex rax, rdi;

    SaveFirstFour;
    Mov rax, 2;
    Mov rdi, 2;
    SaveFirstSeven;
    Mov rax, 3;
    Mov rdi, 4;
    PrintOutRegisterInHex rax, rdi;
    RestoreFirstSevenExceptRax;
    PrintOutRegisterInHex rax, rdi;
    RestoreFirstFourExceptRax;
    PrintOutRegisterInHex rax, rdi;

    SaveFirstFour;
    Mov rax, 2;
    Mov rdi, 2;
    SaveFirstSeven;
    Mov rax, 3;
    Mov rdi, 4;
    PrintOutRegisterInHex rax, rdi;

    Bswap rax;
    PrintOutRegisterInHex rax;

    my $l = Label;
    Jmp $l;
    SetLabel $l;

    ok Assemble eq => <<END, avx512=>0;
     rax: .... .... .... ...3
     rdi: .... .... .... ...4
     rax: .... .... .... ...2
     rdi: .... .... .... ...2
     rax: .... .... .... ...1
     rdi: .... .... .... ...1
     rax: .... .... .... ...3
     rdi: .... .... .... ...4
     rax: .... .... .... ...3
     rdi: .... .... .... ...2
     rax: .... .... .... ...3
     rdi: .... .... .... ...1
     rax: .... .... .... ...3
     rdi: .... .... .... ...4
     rax: .3.. .... .... ....
  END

    ok 8 == RegisterSize rax;

RestoreFirstSevenExceptRax()

Restore the first 7 parameter registers except rax which is being used to return the result.

Example:

    Mov rax, 1;
    Mov rdi, 1;
    SaveFirstFour;
    Mov rax, 2;
    Mov rdi, 2;
    SaveFirstSeven;
    Mov rax, 3;
    Mov rdi, 4;
    PrintOutRegisterInHex rax, rdi;
    RestoreFirstSeven;
    PrintOutRegisterInHex rax, rdi;
    RestoreFirstFour;
    PrintOutRegisterInHex rax, rdi;

    SaveFirstFour;
    Mov rax, 2;
    Mov rdi, 2;
    SaveFirstSeven;
    Mov rax, 3;
    Mov rdi, 4;
    PrintOutRegisterInHex rax, rdi;

    RestoreFirstSevenExceptRax;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    PrintOutRegisterInHex rax, rdi;
    RestoreFirstFourExceptRax;
    PrintOutRegisterInHex rax, rdi;

    SaveFirstFour;
    Mov rax, 2;
    Mov rdi, 2;
    SaveFirstSeven;
    Mov rax, 3;
    Mov rdi, 4;
    PrintOutRegisterInHex rax, rdi;

    Bswap rax;
    PrintOutRegisterInHex rax;

    my $l = Label;
    Jmp $l;
    SetLabel $l;

    ok Assemble eq => <<END, avx512=>0;
     rax: .... .... .... ...3
     rdi: .... .... .... ...4
     rax: .... .... .... ...2
     rdi: .... .... .... ...2
     rax: .... .... .... ...1
     rdi: .... .... .... ...1
     rax: .... .... .... ...3
     rdi: .... .... .... ...4
     rax: .... .... .... ...3
     rdi: .... .... .... ...2
     rax: .... .... .... ...3
     rdi: .... .... .... ...1
     rax: .... .... .... ...3
     rdi: .... .... .... ...4
     rax: .3.. .... .... ....
  END

    ok 8 == RegisterSize rax;

ClearRegisters(@registers)

Clear registers by setting them to zero.

     Parameter   Description
  1  @registers  Registers

Example:

    Mov rax,1;
    Kmovq k0,  rax;
    Kaddb k0,  k0, k0;
    Kaddb k0,  k0, k0;
    Kaddb k0,  k0, k0;
    Kmovq rax, k0;
    PushR k0;

    ClearRegisters k0;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    Kmovq k1, k0;
    PopR  k0;
    PrintOutRegisterInHex k0;
    PrintOutRegisterInHex k1;

    ok Assemble( eq => <<END)
      k0: .... .... .... ...8
      k1: .... .... .... ...0
  END

Zero flag

Actions on the Zero Flag.

SetZF()

Set the zero flag.

Example:

    SetZF;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    PrintOutZF;
    ClearZF;
    PrintOutZF;

    SetZF;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    PrintOutZF;

    SetZF;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    PrintOutZF;
    ClearZF;
    PrintOutZF;


    SetZF;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    IfZ  Then {PrintOutStringNL "Zero"},     Else {PrintOutStringNL "NOT zero"};
    ClearZF;
    IfNz Then {PrintOutStringNL "NOT zero"}, Else {PrintOutStringNL "Zero"};

    Mov r15, 5;
    Shr r15, 1; IfC  Then {PrintOutStringNL "Carry"}   , Else {PrintOutStringNL "NO carry"};
    Shr r15, 1; IfC  Then {PrintOutStringNL "Carry"}   , Else {PrintOutStringNL "NO carry"};
    Shr r15, 1; IfNc Then {PrintOutStringNL "NO carry"}, Else {PrintOutStringNL "Carry"};
    Shr r15, 1; IfNc Then {PrintOutStringNL "NO carry"}, Else {PrintOutStringNL "Carry"};

    ok Assemble eq => <<END, avx512=>0;
  ZF=1
  ZF=0
  ZF=1
  ZF=1
  ZF=0
  Zero
  NOT zero
  Carry
  NO carry
  Carry
  NO carry
  END

ClearZF()

Clear the zero flag.

Example:

    SetZF;
    PrintOutZF;

    ClearZF;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    PrintOutZF;
    SetZF;
    PrintOutZF;
    SetZF;
    PrintOutZF;

    ClearZF;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    PrintOutZF;

    SetZF;
    IfZ  Then {PrintOutStringNL "Zero"},     Else {PrintOutStringNL "NOT zero"};

    ClearZF;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    IfNz Then {PrintOutStringNL "NOT zero"}, Else {PrintOutStringNL "Zero"};

    Mov r15, 5;
    Shr r15, 1; IfC  Then {PrintOutStringNL "Carry"}   , Else {PrintOutStringNL "NO carry"};
    Shr r15, 1; IfC  Then {PrintOutStringNL "Carry"}   , Else {PrintOutStringNL "NO carry"};
    Shr r15, 1; IfNc Then {PrintOutStringNL "NO carry"}, Else {PrintOutStringNL "Carry"};
    Shr r15, 1; IfNc Then {PrintOutStringNL "NO carry"}, Else {PrintOutStringNL "Carry"};

    ok Assemble eq => <<END, avx512=>0;
  ZF=1
  ZF=0
  ZF=1
  ZF=1
  ZF=0
  Zero
  NOT zero
  Carry
  NO carry
  Carry
  NO carry
  END

x, y, zmm

Actions specific to mm registers

xmm(@r)

Add xmm to the front of a list of register expressions.

     Parameter  Description
  1  @r         Register numbers

Example:

    Mov r15, 0x12345678;
    bRegIntoZmm(r15, 1,  0);
    bRegIntoZmm(r15, 1,  1);
    dRegIntoZmm(r15, 1,  4);
    dRegIntoZmm(r15, 1,  8);
    dRegIntoZmm(r15, 1, 12);

    PrintOutRegisterInHex xmm(1);  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    PrintOutRegisterInHex zmm(1);

    bRegFromZmm(r15, 1, 1);
    PrintOutRegisterInHex r15;

    bFromX(1, 0)->outNL;
    bFromZ(1, 0)->outNL;

    dRegFromZmm(r14, 1, 3);
    PrintOutRegisterInHex r14;

    wRegFromZmm(r14, 1, 3);
    PrintOutRegisterInHex r14;

    bFromX(1, 0)->outNL;
    bFromZ(1, 1)->outNL;
    bFromZ(1, 2)->outNL;

    wFromX(1, 0)->outNL;
    wFromZ(1, 1)->outNL;
    wFromZ(1, 2)->outNL;

    dFromX(1, 0)->outNL;
    dFromZ(1, 1)->outNL;
    dFromZ(1, 2)->outNL;

    qFromX(1, 0)->outNL;
    qFromZ(1, 1)->outNL;
    dFromZ(1, 2)->outNL;

    K( offset => 1 << 5)->dFromPointInZ(zmm(1))->outNL;

    Mov       r15, 2;
    Kmovq k7, r15;
    LoadZmm 2, map {0xff} 1..64;
    PrintOutRegisterInHex zmm2;
    Vmovdqu8 zmmM (2, 7), zmm(1);
    Vmovdqu8 zmmMZ(3, 7), zmm(1);
    PrintOutRegisterInHex zmm1, zmm2, zmm3;

    ok Assemble eq => <<END;
    xmm1: 1234 5678 1234 5678  1234 5678 .... 7878
    zmm1: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - 1234 5678 1234 5678  1234 5678 .... 7878
     r15: .... .... 1234 5678
  b at offset 0 in xmm1: .... .... .... ..78
  b at offset 0 in zmm1: .... .... .... ..78
     r14: .... .... 3456 78..
     r14: .... .... 3456 78..
  b at offset 0 in xmm1: .... .... .... ..78
  b at offset 1 in zmm1: .... .... .... ..78
  b at offset 2 in zmm1: .... .... .... ...0
  w at offset 0 in xmm1: .... .... .... 7878
  w at offset 1 in zmm1: .... .... .... ..78
  w at offset 2 in zmm1: .... .... .... ...0
  d at offset 0 in xmm1: .... .... .... 7878
  d at offset 1 in zmm1: .... .... 78.. ..78
  d at offset 2 in zmm1: .... .... 5678 ....
  q at offset 0 in xmm1: 1234 5678 .... 7878
  q at offset 1 in zmm1: 7812 3456 78.. ..78
  d at offset 2 in zmm1: .... .... 5678 ....
  d: .... .... .... ...0
    zmm2: .... .... .... ..-1  .... .... .... ..-1 - .... .... .... ..-1  .... .... .... ..-1 + .... .... .... ..-1  .... .... .... ..-1 - .... .... .... ..-1  .... .... .... ..-1
    zmm1: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - 1234 5678 1234 5678  1234 5678 .... 7878
    zmm2: .... .... .... ..-1  .... .... .... ..-1 - .... .... .... ..-1  .... .... .... ..-1 + .... .... .... ..-1  .... .... .... ..-1 - .... .... .... ..-1  FFFF FFFF FFFF 78FF
    zmm3: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... 78..
  END

ymm(@r)

Add ymm to the front of a list of register expressions.

     Parameter  Description
  1  @r         Register numbers

Example:

    Mov r15, 0x12345678;
    bRegIntoZmm(r15, 1,  0);
    bRegIntoZmm(r15, 1,  1);
    dRegIntoZmm(r15, 1,  4);
    dRegIntoZmm(r15, 1,  8);
    dRegIntoZmm(r15, 1, 12);
    PrintOutRegisterInHex xmm(1);
    PrintOutRegisterInHex zmm(1);

    bRegFromZmm(r15, 1, 1);
    PrintOutRegisterInHex r15;

    bFromX(1, 0)->outNL;
    bFromZ(1, 0)->outNL;

    dRegFromZmm(r14, 1, 3);
    PrintOutRegisterInHex r14;

    wRegFromZmm(r14, 1, 3);
    PrintOutRegisterInHex r14;

    bFromX(1, 0)->outNL;
    bFromZ(1, 1)->outNL;
    bFromZ(1, 2)->outNL;

    wFromX(1, 0)->outNL;
    wFromZ(1, 1)->outNL;
    wFromZ(1, 2)->outNL;

    dFromX(1, 0)->outNL;
    dFromZ(1, 1)->outNL;
    dFromZ(1, 2)->outNL;

    qFromX(1, 0)->outNL;
    qFromZ(1, 1)->outNL;
    dFromZ(1, 2)->outNL;

    K( offset => 1 << 5)->dFromPointInZ(zmm(1))->outNL;

    Mov       r15, 2;
    Kmovq k7, r15;
    LoadZmm 2, map {0xff} 1..64;
    PrintOutRegisterInHex zmm2;
    Vmovdqu8 zmmM (2, 7), zmm(1);
    Vmovdqu8 zmmMZ(3, 7), zmm(1);
    PrintOutRegisterInHex zmm1, zmm2, zmm3;

    ok Assemble eq => <<END;
    xmm1: 1234 5678 1234 5678  1234 5678 .... 7878
    zmm1: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - 1234 5678 1234 5678  1234 5678 .... 7878
     r15: .... .... 1234 5678
  b at offset 0 in xmm1: .... .... .... ..78
  b at offset 0 in zmm1: .... .... .... ..78
     r14: .... .... 3456 78..
     r14: .... .... 3456 78..
  b at offset 0 in xmm1: .... .... .... ..78
  b at offset 1 in zmm1: .... .... .... ..78
  b at offset 2 in zmm1: .... .... .... ...0
  w at offset 0 in xmm1: .... .... .... 7878
  w at offset 1 in zmm1: .... .... .... ..78
  w at offset 2 in zmm1: .... .... .... ...0
  d at offset 0 in xmm1: .... .... .... 7878
  d at offset 1 in zmm1: .... .... 78.. ..78
  d at offset 2 in zmm1: .... .... 5678 ....
  q at offset 0 in xmm1: 1234 5678 .... 7878
  q at offset 1 in zmm1: 7812 3456 78.. ..78
  d at offset 2 in zmm1: .... .... 5678 ....
  d: .... .... .... ...0
    zmm2: .... .... .... ..-1  .... .... .... ..-1 - .... .... .... ..-1  .... .... .... ..-1 + .... .... .... ..-1  .... .... .... ..-1 - .... .... .... ..-1  .... .... .... ..-1
    zmm1: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - 1234 5678 1234 5678  1234 5678 .... 7878
    zmm2: .... .... .... ..-1  .... .... .... ..-1 - .... .... .... ..-1  .... .... .... ..-1 + .... .... .... ..-1  .... .... .... ..-1 - .... .... .... ..-1  FFFF FFFF FFFF 78FF
    zmm3: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... 78..
  END

zmm(@r)

Add zmm to the front of a list of register expressions.

     Parameter  Description
  1  @r         Register numbers

Example:

    LoadZmm 0, 0..63;

    PrintOutRegisterInHex zmm 0;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲


    ok Assemble(debug => 0, eq => <<END, avx512=>1);
    zmm0: 3F3E 3D3C 3B3A 3938  3736 3534 3332 3130 - 2F2E 2D2C 2B2A 2928  2726 2524 2322 2120 + 1F1E 1D1C 1B1A 1918  1716 1514 1312 1110 - .F.E .D.C .B.A .9.8  .7.6 .5.4 .3.2 .1..
  END

zmmM($z, $m)

Add zmm to the front of a register number and a mask after it.

     Parameter  Description
  1  $z         Zmm number
  2  $m         Mask register

Example:

    Mov r15, 0x12345678;
    bRegIntoZmm(r15, 1,  0);
    bRegIntoZmm(r15, 1,  1);
    dRegIntoZmm(r15, 1,  4);
    dRegIntoZmm(r15, 1,  8);
    dRegIntoZmm(r15, 1, 12);
    PrintOutRegisterInHex xmm(1);
    PrintOutRegisterInHex zmm(1);

    bRegFromZmm(r15, 1, 1);
    PrintOutRegisterInHex r15;

    bFromX(1, 0)->outNL;
    bFromZ(1, 0)->outNL;

    dRegFromZmm(r14, 1, 3);
    PrintOutRegisterInHex r14;

    wRegFromZmm(r14, 1, 3);
    PrintOutRegisterInHex r14;

    bFromX(1, 0)->outNL;
    bFromZ(1, 1)->outNL;
    bFromZ(1, 2)->outNL;

    wFromX(1, 0)->outNL;
    wFromZ(1, 1)->outNL;
    wFromZ(1, 2)->outNL;

    dFromX(1, 0)->outNL;
    dFromZ(1, 1)->outNL;
    dFromZ(1, 2)->outNL;

    qFromX(1, 0)->outNL;
    qFromZ(1, 1)->outNL;
    dFromZ(1, 2)->outNL;

    K( offset => 1 << 5)->dFromPointInZ(zmm(1))->outNL;

    Mov       r15, 2;
    Kmovq k7, r15;
    LoadZmm 2, map {0xff} 1..64;
    PrintOutRegisterInHex zmm2;

    Vmovdqu8 zmmM (2, 7), zmm(1);  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    Vmovdqu8 zmmMZ(3, 7), zmm(1);
    PrintOutRegisterInHex zmm1, zmm2, zmm3;

    ok Assemble eq => <<END;
    xmm1: 1234 5678 1234 5678  1234 5678 .... 7878
    zmm1: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - 1234 5678 1234 5678  1234 5678 .... 7878
     r15: .... .... 1234 5678
  b at offset 0 in xmm1: .... .... .... ..78
  b at offset 0 in zmm1: .... .... .... ..78
     r14: .... .... 3456 78..
     r14: .... .... 3456 78..
  b at offset 0 in xmm1: .... .... .... ..78
  b at offset 1 in zmm1: .... .... .... ..78
  b at offset 2 in zmm1: .... .... .... ...0
  w at offset 0 in xmm1: .... .... .... 7878
  w at offset 1 in zmm1: .... .... .... ..78
  w at offset 2 in zmm1: .... .... .... ...0
  d at offset 0 in xmm1: .... .... .... 7878
  d at offset 1 in zmm1: .... .... 78.. ..78
  d at offset 2 in zmm1: .... .... 5678 ....
  q at offset 0 in xmm1: 1234 5678 .... 7878
  q at offset 1 in zmm1: 7812 3456 78.. ..78
  d at offset 2 in zmm1: .... .... 5678 ....
  d: .... .... .... ...0
    zmm2: .... .... .... ..-1  .... .... .... ..-1 - .... .... .... ..-1  .... .... .... ..-1 + .... .... .... ..-1  .... .... .... ..-1 - .... .... .... ..-1  .... .... .... ..-1
    zmm1: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - 1234 5678 1234 5678  1234 5678 .... 7878
    zmm2: .... .... .... ..-1  .... .... .... ..-1 - .... .... .... ..-1  .... .... .... ..-1 + .... .... .... ..-1  .... .... .... ..-1 - .... .... .... ..-1  FFFF FFFF FFFF 78FF
    zmm3: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... 78..
  END

zmmMZ($z, $m)

Add zmm to the front of a register number and mask and zero after it.

     Parameter  Description
  1  $z         Zmm number
  2  $m         Mask register number

Example:

    Mov r15, 0x12345678;
    bRegIntoZmm(r15, 1,  0);
    bRegIntoZmm(r15, 1,  1);
    dRegIntoZmm(r15, 1,  4);
    dRegIntoZmm(r15, 1,  8);
    dRegIntoZmm(r15, 1, 12);
    PrintOutRegisterInHex xmm(1);
    PrintOutRegisterInHex zmm(1);

    bRegFromZmm(r15, 1, 1);
    PrintOutRegisterInHex r15;

    bFromX(1, 0)->outNL;
    bFromZ(1, 0)->outNL;

    dRegFromZmm(r14, 1, 3);
    PrintOutRegisterInHex r14;

    wRegFromZmm(r14, 1, 3);
    PrintOutRegisterInHex r14;

    bFromX(1, 0)->outNL;
    bFromZ(1, 1)->outNL;
    bFromZ(1, 2)->outNL;

    wFromX(1, 0)->outNL;
    wFromZ(1, 1)->outNL;
    wFromZ(1, 2)->outNL;

    dFromX(1, 0)->outNL;
    dFromZ(1, 1)->outNL;
    dFromZ(1, 2)->outNL;

    qFromX(1, 0)->outNL;
    qFromZ(1, 1)->outNL;
    dFromZ(1, 2)->outNL;

    K( offset => 1 << 5)->dFromPointInZ(zmm(1))->outNL;

    Mov       r15, 2;
    Kmovq k7, r15;
    LoadZmm 2, map {0xff} 1..64;
    PrintOutRegisterInHex zmm2;
    Vmovdqu8 zmmM (2, 7), zmm(1);

    Vmovdqu8 zmmMZ(3, 7), zmm(1);  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    PrintOutRegisterInHex zmm1, zmm2, zmm3;

    ok Assemble eq => <<END;
    xmm1: 1234 5678 1234 5678  1234 5678 .... 7878
    zmm1: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - 1234 5678 1234 5678  1234 5678 .... 7878
     r15: .... .... 1234 5678
  b at offset 0 in xmm1: .... .... .... ..78
  b at offset 0 in zmm1: .... .... .... ..78
     r14: .... .... 3456 78..
     r14: .... .... 3456 78..
  b at offset 0 in xmm1: .... .... .... ..78
  b at offset 1 in zmm1: .... .... .... ..78
  b at offset 2 in zmm1: .... .... .... ...0
  w at offset 0 in xmm1: .... .... .... 7878
  w at offset 1 in zmm1: .... .... .... ..78
  w at offset 2 in zmm1: .... .... .... ...0
  d at offset 0 in xmm1: .... .... .... 7878
  d at offset 1 in zmm1: .... .... 78.. ..78
  d at offset 2 in zmm1: .... .... 5678 ....
  q at offset 0 in xmm1: 1234 5678 .... 7878
  q at offset 1 in zmm1: 7812 3456 78.. ..78
  d at offset 2 in zmm1: .... .... 5678 ....
  d: .... .... .... ...0
    zmm2: .... .... .... ..-1  .... .... .... ..-1 - .... .... .... ..-1  .... .... .... ..-1 + .... .... .... ..-1  .... .... .... ..-1 - .... .... .... ..-1  .... .... .... ..-1
    zmm1: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - 1234 5678 1234 5678  1234 5678 .... 7878
    zmm2: .... .... .... ..-1  .... .... .... ..-1 - .... .... .... ..-1  .... .... .... ..-1 + .... .... .... ..-1  .... .... .... ..-1 - .... .... .... ..-1  FFFF FFFF FFFF 78FF
    zmm3: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... 78..
  END

Via general purpose registers

Load zmm registers from data held in the general purpose registers.

LoadZmm($zmm, @bytes)

Load a numbered zmm with the specified bytes.

     Parameter  Description
  1  $zmm       Numbered zmm
  2  @bytes     Bytes

Example:

    LoadZmm 0, 0..63;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    PrintOutRegisterInHex zmm 0;

    ok Assemble(debug => 0, eq => <<END, avx512=>1);
    zmm0: 3F3E 3D3C 3B3A 3938  3736 3534 3332 3130 - 2F2E 2D2C 2B2A 2928  2726 2524 2322 2120 + 1F1E 1D1C 1B1A 1918  1716 1514 1312 1110 - .F.E .D.C .B.A .9.8  .7.6 .5.4 .3.2 .1..
  END

bRegFromZmm($register, $zmm, $offset)

Load the specified register from the byte at the specified offset located in the numbered zmm.

     Parameter  Description
  1  $register  Register to load
  2  $zmm       Numbered zmm register to load from
  3  $offset    Constant offset in bytes

Example:

    Mov r15, 0x12345678;
    bRegIntoZmm(r15, 1,  0);
    bRegIntoZmm(r15, 1,  1);
    dRegIntoZmm(r15, 1,  4);
    dRegIntoZmm(r15, 1,  8);
    dRegIntoZmm(r15, 1, 12);
    PrintOutRegisterInHex xmm(1);
    PrintOutRegisterInHex zmm(1);


    bRegFromZmm(r15, 1, 1);  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    PrintOutRegisterInHex r15;

    bFromX(1, 0)->outNL;
    bFromZ(1, 0)->outNL;

    dRegFromZmm(r14, 1, 3);
    PrintOutRegisterInHex r14;

    wRegFromZmm(r14, 1, 3);
    PrintOutRegisterInHex r14;

    bFromX(1, 0)->outNL;
    bFromZ(1, 1)->outNL;
    bFromZ(1, 2)->outNL;

    wFromX(1, 0)->outNL;
    wFromZ(1, 1)->outNL;
    wFromZ(1, 2)->outNL;

    dFromX(1, 0)->outNL;
    dFromZ(1, 1)->outNL;
    dFromZ(1, 2)->outNL;

    qFromX(1, 0)->outNL;
    qFromZ(1, 1)->outNL;
    dFromZ(1, 2)->outNL;

    K( offset => 1 << 5)->dFromPointInZ(zmm(1))->outNL;

    Mov       r15, 2;
    Kmovq k7, r15;
    LoadZmm 2, map {0xff} 1..64;
    PrintOutRegisterInHex zmm2;
    Vmovdqu8 zmmM (2, 7), zmm(1);
    Vmovdqu8 zmmMZ(3, 7), zmm(1);
    PrintOutRegisterInHex zmm1, zmm2, zmm3;

    ok Assemble eq => <<END;
    xmm1: 1234 5678 1234 5678  1234 5678 .... 7878
    zmm1: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - 1234 5678 1234 5678  1234 5678 .... 7878
     r15: .... .... 1234 5678
  b at offset 0 in xmm1: .... .... .... ..78
  b at offset 0 in zmm1: .... .... .... ..78
     r14: .... .... 3456 78..
     r14: .... .... 3456 78..
  b at offset 0 in xmm1: .... .... .... ..78
  b at offset 1 in zmm1: .... .... .... ..78
  b at offset 2 in zmm1: .... .... .... ...0
  w at offset 0 in xmm1: .... .... .... 7878
  w at offset 1 in zmm1: .... .... .... ..78
  w at offset 2 in zmm1: .... .... .... ...0
  d at offset 0 in xmm1: .... .... .... 7878
  d at offset 1 in zmm1: .... .... 78.. ..78
  d at offset 2 in zmm1: .... .... 5678 ....
  q at offset 0 in xmm1: 1234 5678 .... 7878
  q at offset 1 in zmm1: 7812 3456 78.. ..78
  d at offset 2 in zmm1: .... .... 5678 ....
  d: .... .... .... ...0
    zmm2: .... .... .... ..-1  .... .... .... ..-1 - .... .... .... ..-1  .... .... .... ..-1 + .... .... .... ..-1  .... .... .... ..-1 - .... .... .... ..-1  .... .... .... ..-1
    zmm1: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - 1234 5678 1234 5678  1234 5678 .... 7878
    zmm2: .... .... .... ..-1  .... .... .... ..-1 - .... .... .... ..-1  .... .... .... ..-1 + .... .... .... ..-1  .... .... .... ..-1 - .... .... .... ..-1  FFFF FFFF FFFF 78FF
    zmm3: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... 78..
  END

bRegIntoZmm($register, $zmm, $offset)

Put the byte content of the specified register into the byte in the numbered zmm at the specified offset in the zmm.

     Parameter  Description
  1  $register  Register to load
  2  $zmm       Numbered zmm register to load from
  3  $offset    Constant offset in bytes

Example:

    Mov r15, 0x12345678;

    bRegIntoZmm(r15, 1,  0);  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲


    bRegIntoZmm(r15, 1,  1);  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    dRegIntoZmm(r15, 1,  4);
    dRegIntoZmm(r15, 1,  8);
    dRegIntoZmm(r15, 1, 12);
    PrintOutRegisterInHex xmm(1);
    PrintOutRegisterInHex zmm(1);

    bRegFromZmm(r15, 1, 1);
    PrintOutRegisterInHex r15;

    bFromX(1, 0)->outNL;
    bFromZ(1, 0)->outNL;

    dRegFromZmm(r14, 1, 3);
    PrintOutRegisterInHex r14;

    wRegFromZmm(r14, 1, 3);
    PrintOutRegisterInHex r14;

    bFromX(1, 0)->outNL;
    bFromZ(1, 1)->outNL;
    bFromZ(1, 2)->outNL;

    wFromX(1, 0)->outNL;
    wFromZ(1, 1)->outNL;
    wFromZ(1, 2)->outNL;

    dFromX(1, 0)->outNL;
    dFromZ(1, 1)->outNL;
    dFromZ(1, 2)->outNL;

    qFromX(1, 0)->outNL;
    qFromZ(1, 1)->outNL;
    dFromZ(1, 2)->outNL;

    K( offset => 1 << 5)->dFromPointInZ(zmm(1))->outNL;

    Mov       r15, 2;
    Kmovq k7, r15;
    LoadZmm 2, map {0xff} 1..64;
    PrintOutRegisterInHex zmm2;
    Vmovdqu8 zmmM (2, 7), zmm(1);
    Vmovdqu8 zmmMZ(3, 7), zmm(1);
    PrintOutRegisterInHex zmm1, zmm2, zmm3;

    ok Assemble eq => <<END;
    xmm1: 1234 5678 1234 5678  1234 5678 .... 7878
    zmm1: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - 1234 5678 1234 5678  1234 5678 .... 7878
     r15: .... .... 1234 5678
  b at offset 0 in xmm1: .... .... .... ..78
  b at offset 0 in zmm1: .... .... .... ..78
     r14: .... .... 3456 78..
     r14: .... .... 3456 78..
  b at offset 0 in xmm1: .... .... .... ..78
  b at offset 1 in zmm1: .... .... .... ..78
  b at offset 2 in zmm1: .... .... .... ...0
  w at offset 0 in xmm1: .... .... .... 7878
  w at offset 1 in zmm1: .... .... .... ..78
  w at offset 2 in zmm1: .... .... .... ...0
  d at offset 0 in xmm1: .... .... .... 7878
  d at offset 1 in zmm1: .... .... 78.. ..78
  d at offset 2 in zmm1: .... .... 5678 ....
  q at offset 0 in xmm1: 1234 5678 .... 7878
  q at offset 1 in zmm1: 7812 3456 78.. ..78
  d at offset 2 in zmm1: .... .... 5678 ....
  d: .... .... .... ...0
    zmm2: .... .... .... ..-1  .... .... .... ..-1 - .... .... .... ..-1  .... .... .... ..-1 + .... .... .... ..-1  .... .... .... ..-1 - .... .... .... ..-1  .... .... .... ..-1
    zmm1: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - 1234 5678 1234 5678  1234 5678 .... 7878
    zmm2: .... .... .... ..-1  .... .... .... ..-1 - .... .... .... ..-1  .... .... .... ..-1 + .... .... .... ..-1  .... .... .... ..-1 - .... .... .... ..-1  FFFF FFFF FFFF 78FF
    zmm3: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... 78..
  END

wRegFromZmm($register, $zmm, $offset)

Load the specified register from the word at the specified offset located in the numbered zmm.

     Parameter  Description
  1  $register  Register to load
  2  $zmm       Numbered zmm register to load from
  3  $offset    Constant offset in bytes

Example:

    Mov r15, 0x12345678;
    bRegIntoZmm(r15, 1,  0);
    bRegIntoZmm(r15, 1,  1);
    dRegIntoZmm(r15, 1,  4);
    dRegIntoZmm(r15, 1,  8);
    dRegIntoZmm(r15, 1, 12);
    PrintOutRegisterInHex xmm(1);
    PrintOutRegisterInHex zmm(1);

    bRegFromZmm(r15, 1, 1);
    PrintOutRegisterInHex r15;

    bFromX(1, 0)->outNL;
    bFromZ(1, 0)->outNL;

    dRegFromZmm(r14, 1, 3);
    PrintOutRegisterInHex r14;


    wRegFromZmm(r14, 1, 3);  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    PrintOutRegisterInHex r14;

    bFromX(1, 0)->outNL;
    bFromZ(1, 1)->outNL;
    bFromZ(1, 2)->outNL;

    wFromX(1, 0)->outNL;
    wFromZ(1, 1)->outNL;
    wFromZ(1, 2)->outNL;

    dFromX(1, 0)->outNL;
    dFromZ(1, 1)->outNL;
    dFromZ(1, 2)->outNL;

    qFromX(1, 0)->outNL;
    qFromZ(1, 1)->outNL;
    dFromZ(1, 2)->outNL;

    K( offset => 1 << 5)->dFromPointInZ(zmm(1))->outNL;

    Mov       r15, 2;
    Kmovq k7, r15;
    LoadZmm 2, map {0xff} 1..64;
    PrintOutRegisterInHex zmm2;
    Vmovdqu8 zmmM (2, 7), zmm(1);
    Vmovdqu8 zmmMZ(3, 7), zmm(1);
    PrintOutRegisterInHex zmm1, zmm2, zmm3;

    ok Assemble eq => <<END;
    xmm1: 1234 5678 1234 5678  1234 5678 .... 7878
    zmm1: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - 1234 5678 1234 5678  1234 5678 .... 7878
     r15: .... .... 1234 5678
  b at offset 0 in xmm1: .... .... .... ..78
  b at offset 0 in zmm1: .... .... .... ..78
     r14: .... .... 3456 78..
     r14: .... .... 3456 78..
  b at offset 0 in xmm1: .... .... .... ..78
  b at offset 1 in zmm1: .... .... .... ..78
  b at offset 2 in zmm1: .... .... .... ...0
  w at offset 0 in xmm1: .... .... .... 7878
  w at offset 1 in zmm1: .... .... .... ..78
  w at offset 2 in zmm1: .... .... .... ...0
  d at offset 0 in xmm1: .... .... .... 7878
  d at offset 1 in zmm1: .... .... 78.. ..78
  d at offset 2 in zmm1: .... .... 5678 ....
  q at offset 0 in xmm1: 1234 5678 .... 7878
  q at offset 1 in zmm1: 7812 3456 78.. ..78
  d at offset 2 in zmm1: .... .... 5678 ....
  d: .... .... .... ...0
    zmm2: .... .... .... ..-1  .... .... .... ..-1 - .... .... .... ..-1  .... .... .... ..-1 + .... .... .... ..-1  .... .... .... ..-1 - .... .... .... ..-1  .... .... .... ..-1
    zmm1: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - 1234 5678 1234 5678  1234 5678 .... 7878
    zmm2: .... .... .... ..-1  .... .... .... ..-1 - .... .... .... ..-1  .... .... .... ..-1 + .... .... .... ..-1  .... .... .... ..-1 - .... .... .... ..-1  FFFF FFFF FFFF 78FF
    zmm3: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... 78..
  END

wRegIntoZmm($register, $zmm, $offset)

Put the specified register into the word in the numbered zmm at the specified offset in the zmm.

     Parameter  Description
  1  $register  Register to load
  2  $zmm       Numbered zmm register to load from
  3  $offset    Constant offset in bytes

Example:

    Mov r15, 0x12345678;
    bRegIntoZmm(r15, 1,  0);
    bRegIntoZmm(r15, 1,  1);
    dRegIntoZmm(r15, 1,  4);
    dRegIntoZmm(r15, 1,  8);
    dRegIntoZmm(r15, 1, 12);
    PrintOutRegisterInHex xmm(1);
    PrintOutRegisterInHex zmm(1);

    bRegFromZmm(r15, 1, 1);
    PrintOutRegisterInHex r15;

    bFromX(1, 0)->outNL;
    bFromZ(1, 0)->outNL;

    dRegFromZmm(r14, 1, 3);
    PrintOutRegisterInHex r14;

    wRegFromZmm(r14, 1, 3);
    PrintOutRegisterInHex r14;

    bFromX(1, 0)->outNL;
    bFromZ(1, 1)->outNL;
    bFromZ(1, 2)->outNL;

    wFromX(1, 0)->outNL;
    wFromZ(1, 1)->outNL;
    wFromZ(1, 2)->outNL;

    dFromX(1, 0)->outNL;
    dFromZ(1, 1)->outNL;
    dFromZ(1, 2)->outNL;

    qFromX(1, 0)->outNL;
    qFromZ(1, 1)->outNL;
    dFromZ(1, 2)->outNL;

    K( offset => 1 << 5)->dFromPointInZ(zmm(1))->outNL;

    Mov       r15, 2;
    Kmovq k7, r15;
    LoadZmm 2, map {0xff} 1..64;
    PrintOutRegisterInHex zmm2;
    Vmovdqu8 zmmM (2, 7), zmm(1);
    Vmovdqu8 zmmMZ(3, 7), zmm(1);
    PrintOutRegisterInHex zmm1, zmm2, zmm3;

    ok Assemble eq => <<END;
    xmm1: 1234 5678 1234 5678  1234 5678 .... 7878
    zmm1: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - 1234 5678 1234 5678  1234 5678 .... 7878
     r15: .... .... 1234 5678
  b at offset 0 in xmm1: .... .... .... ..78
  b at offset 0 in zmm1: .... .... .... ..78
     r14: .... .... 3456 78..
     r14: .... .... 3456 78..
  b at offset 0 in xmm1: .... .... .... ..78
  b at offset 1 in zmm1: .... .... .... ..78
  b at offset 2 in zmm1: .... .... .... ...0
  w at offset 0 in xmm1: .... .... .... 7878
  w at offset 1 in zmm1: .... .... .... ..78
  w at offset 2 in zmm1: .... .... .... ...0
  d at offset 0 in xmm1: .... .... .... 7878
  d at offset 1 in zmm1: .... .... 78.. ..78
  d at offset 2 in zmm1: .... .... 5678 ....
  q at offset 0 in xmm1: 1234 5678 .... 7878
  q at offset 1 in zmm1: 7812 3456 78.. ..78
  d at offset 2 in zmm1: .... .... 5678 ....
  d: .... .... .... ...0
    zmm2: .... .... .... ..-1  .... .... .... ..-1 - .... .... .... ..-1  .... .... .... ..-1 + .... .... .... ..-1  .... .... .... ..-1 - .... .... .... ..-1  .... .... .... ..-1
    zmm1: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - 1234 5678 1234 5678  1234 5678 .... 7878
    zmm2: .... .... .... ..-1  .... .... .... ..-1 - .... .... .... ..-1  .... .... .... ..-1 + .... .... .... ..-1  .... .... .... ..-1 - .... .... .... ..-1  FFFF FFFF FFFF 78FF
    zmm3: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... 78..
  END

dRegFromZmm($register, $zmm, $offset)

Load the specified register from the double word at the specified offset located in the numbered zmm.

     Parameter  Description
  1  $register  Register to load
  2  $zmm       Numbered zmm register to load from
  3  $offset    Constant offset in bytes

Example:

    Mov r15, 0x12345678;
    bRegIntoZmm(r15, 1,  0);
    bRegIntoZmm(r15, 1,  1);
    dRegIntoZmm(r15, 1,  4);
    dRegIntoZmm(r15, 1,  8);
    dRegIntoZmm(r15, 1, 12);
    PrintOutRegisterInHex xmm(1);
    PrintOutRegisterInHex zmm(1);

    bRegFromZmm(r15, 1, 1);
    PrintOutRegisterInHex r15;

    bFromX(1, 0)->outNL;
    bFromZ(1, 0)->outNL;


    dRegFromZmm(r14, 1, 3);  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    PrintOutRegisterInHex r14;

    wRegFromZmm(r14, 1, 3);
    PrintOutRegisterInHex r14;

    bFromX(1, 0)->outNL;
    bFromZ(1, 1)->outNL;
    bFromZ(1, 2)->outNL;

    wFromX(1, 0)->outNL;
    wFromZ(1, 1)->outNL;
    wFromZ(1, 2)->outNL;

    dFromX(1, 0)->outNL;
    dFromZ(1, 1)->outNL;
    dFromZ(1, 2)->outNL;

    qFromX(1, 0)->outNL;
    qFromZ(1, 1)->outNL;
    dFromZ(1, 2)->outNL;

    K( offset => 1 << 5)->dFromPointInZ(zmm(1))->outNL;

    Mov       r15, 2;
    Kmovq k7, r15;
    LoadZmm 2, map {0xff} 1..64;
    PrintOutRegisterInHex zmm2;
    Vmovdqu8 zmmM (2, 7), zmm(1);
    Vmovdqu8 zmmMZ(3, 7), zmm(1);
    PrintOutRegisterInHex zmm1, zmm2, zmm3;

    ok Assemble eq => <<END;
    xmm1: 1234 5678 1234 5678  1234 5678 .... 7878
    zmm1: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - 1234 5678 1234 5678  1234 5678 .... 7878
     r15: .... .... 1234 5678
  b at offset 0 in xmm1: .... .... .... ..78
  b at offset 0 in zmm1: .... .... .... ..78
     r14: .... .... 3456 78..
     r14: .... .... 3456 78..
  b at offset 0 in xmm1: .... .... .... ..78
  b at offset 1 in zmm1: .... .... .... ..78
  b at offset 2 in zmm1: .... .... .... ...0
  w at offset 0 in xmm1: .... .... .... 7878
  w at offset 1 in zmm1: .... .... .... ..78
  w at offset 2 in zmm1: .... .... .... ...0
  d at offset 0 in xmm1: .... .... .... 7878
  d at offset 1 in zmm1: .... .... 78.. ..78
  d at offset 2 in zmm1: .... .... 5678 ....
  q at offset 0 in xmm1: 1234 5678 .... 7878
  q at offset 1 in zmm1: 7812 3456 78.. ..78
  d at offset 2 in zmm1: .... .... 5678 ....
  d: .... .... .... ...0
    zmm2: .... .... .... ..-1  .... .... .... ..-1 - .... .... .... ..-1  .... .... .... ..-1 + .... .... .... ..-1  .... .... .... ..-1 - .... .... .... ..-1  .... .... .... ..-1
    zmm1: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - 1234 5678 1234 5678  1234 5678 .... 7878
    zmm2: .... .... .... ..-1  .... .... .... ..-1 - .... .... .... ..-1  .... .... .... ..-1 + .... .... .... ..-1  .... .... .... ..-1 - .... .... .... ..-1  FFFF FFFF FFFF 78FF
    zmm3: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... 78..
  END

dRegIntoZmm($register, $zmm, $offset)

Put the specified register into the double word in the numbered zmm at the specified offset in the zmm.

     Parameter  Description
  1  $register  Register to load
  2  $zmm       Numbered zmm register to load from
  3  $offset    Constant offset in bytes

Example:

    Mov r15, 0x12345678;
    bRegIntoZmm(r15, 1,  0);
    bRegIntoZmm(r15, 1,  1);

    dRegIntoZmm(r15, 1,  4);  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲


    dRegIntoZmm(r15, 1,  8);  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲


    dRegIntoZmm(r15, 1, 12);  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    PrintOutRegisterInHex xmm(1);
    PrintOutRegisterInHex zmm(1);

    bRegFromZmm(r15, 1, 1);
    PrintOutRegisterInHex r15;

    bFromX(1, 0)->outNL;
    bFromZ(1, 0)->outNL;

    dRegFromZmm(r14, 1, 3);
    PrintOutRegisterInHex r14;

    wRegFromZmm(r14, 1, 3);
    PrintOutRegisterInHex r14;

    bFromX(1, 0)->outNL;
    bFromZ(1, 1)->outNL;
    bFromZ(1, 2)->outNL;

    wFromX(1, 0)->outNL;
    wFromZ(1, 1)->outNL;
    wFromZ(1, 2)->outNL;

    dFromX(1, 0)->outNL;
    dFromZ(1, 1)->outNL;
    dFromZ(1, 2)->outNL;

    qFromX(1, 0)->outNL;
    qFromZ(1, 1)->outNL;
    dFromZ(1, 2)->outNL;

    K( offset => 1 << 5)->dFromPointInZ(zmm(1))->outNL;

    Mov       r15, 2;
    Kmovq k7, r15;
    LoadZmm 2, map {0xff} 1..64;
    PrintOutRegisterInHex zmm2;
    Vmovdqu8 zmmM (2, 7), zmm(1);
    Vmovdqu8 zmmMZ(3, 7), zmm(1);
    PrintOutRegisterInHex zmm1, zmm2, zmm3;

    ok Assemble eq => <<END;
    xmm1: 1234 5678 1234 5678  1234 5678 .... 7878
    zmm1: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - 1234 5678 1234 5678  1234 5678 .... 7878
     r15: .... .... 1234 5678
  b at offset 0 in xmm1: .... .... .... ..78
  b at offset 0 in zmm1: .... .... .... ..78
     r14: .... .... 3456 78..
     r14: .... .... 3456 78..
  b at offset 0 in xmm1: .... .... .... ..78
  b at offset 1 in zmm1: .... .... .... ..78
  b at offset 2 in zmm1: .... .... .... ...0
  w at offset 0 in xmm1: .... .... .... 7878
  w at offset 1 in zmm1: .... .... .... ..78
  w at offset 2 in zmm1: .... .... .... ...0
  d at offset 0 in xmm1: .... .... .... 7878
  d at offset 1 in zmm1: .... .... 78.. ..78
  d at offset 2 in zmm1: .... .... 5678 ....
  q at offset 0 in xmm1: 1234 5678 .... 7878
  q at offset 1 in zmm1: 7812 3456 78.. ..78
  d at offset 2 in zmm1: .... .... 5678 ....
  d: .... .... .... ...0
    zmm2: .... .... .... ..-1  .... .... .... ..-1 - .... .... .... ..-1  .... .... .... ..-1 + .... .... .... ..-1  .... .... .... ..-1 - .... .... .... ..-1  .... .... .... ..-1
    zmm1: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - 1234 5678 1234 5678  1234 5678 .... 7878
    zmm2: .... .... .... ..-1  .... .... .... ..-1 - .... .... .... ..-1  .... .... .... ..-1 + .... .... .... ..-1  .... .... .... ..-1 - .... .... .... ..-1  FFFF FFFF FFFF 78FF
    zmm3: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... 78..
  END

SaveRegIntoMm($mm, $offset, $reg)

Save the specified register into the numbered zmm at the quad offset specified as a constant number.

     Parameter  Description
  1  $mm        Mm register
  2  $offset    Offset in quads
  3  $reg       General purpose register to load

Example:

    Mov rax, 1; SaveRegIntoMm(zmm0, 0, rax);  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲


    Mov rax, 2; SaveRegIntoMm(zmm0, 1, rax);  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲


    Mov rax, 3; SaveRegIntoMm(zmm0, 2, rax);  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲


    Mov rax, 4; SaveRegIntoMm(zmm0, 3, rax);  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲


    LoadRegFromMm(zmm0, 0, r15);
    LoadRegFromMm(zmm0, 1, r14);
    LoadRegFromMm(zmm0, 2, r13);
    LoadRegFromMm(zmm0, 3, r12);

    PrintOutRegisterInHex ymm0, r15, r14, r13, r12;
    ok Assemble(debug => 0, eq => <<END, avx512=>1);
    ymm0: .... .... .... ...4  .... .... .... ...3 - .... .... .... ...2  .... .... .... ...1
     r15: .... .... .... ...1
     r14: .... .... .... ...2
     r13: .... .... .... ...3
     r12: .... .... .... ...4
  END

Via variables

Load zmm registers from data held in variables

bFromX($xmm, $offset)

Get the byte from the numbered xmm register and return it in a variable.

     Parameter  Description
  1  $xmm       Numbered xmm
  2  $offset    Offset in bytes

Example:

    Mov r15, 0x12345678;
    bRegIntoZmm(r15, 1,  0);
    bRegIntoZmm(r15, 1,  1);
    dRegIntoZmm(r15, 1,  4);
    dRegIntoZmm(r15, 1,  8);
    dRegIntoZmm(r15, 1, 12);
    PrintOutRegisterInHex xmm(1);
    PrintOutRegisterInHex zmm(1);

    bRegFromZmm(r15, 1, 1);
    PrintOutRegisterInHex r15;


    bFromX(1, 0)->outNL;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    bFromZ(1, 0)->outNL;

    dRegFromZmm(r14, 1, 3);
    PrintOutRegisterInHex r14;

    wRegFromZmm(r14, 1, 3);
    PrintOutRegisterInHex r14;


    bFromX(1, 0)->outNL;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    bFromZ(1, 1)->outNL;
    bFromZ(1, 2)->outNL;

    wFromX(1, 0)->outNL;
    wFromZ(1, 1)->outNL;
    wFromZ(1, 2)->outNL;

    dFromX(1, 0)->outNL;
    dFromZ(1, 1)->outNL;
    dFromZ(1, 2)->outNL;

    qFromX(1, 0)->outNL;
    qFromZ(1, 1)->outNL;
    dFromZ(1, 2)->outNL;

    K( offset => 1 << 5)->dFromPointInZ(zmm(1))->outNL;

    Mov       r15, 2;
    Kmovq k7, r15;
    LoadZmm 2, map {0xff} 1..64;
    PrintOutRegisterInHex zmm2;
    Vmovdqu8 zmmM (2, 7), zmm(1);
    Vmovdqu8 zmmMZ(3, 7), zmm(1);
    PrintOutRegisterInHex zmm1, zmm2, zmm3;

    ok Assemble eq => <<END;
    xmm1: 1234 5678 1234 5678  1234 5678 .... 7878
    zmm1: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - 1234 5678 1234 5678  1234 5678 .... 7878
     r15: .... .... 1234 5678
  b at offset 0 in xmm1: .... .... .... ..78
  b at offset 0 in zmm1: .... .... .... ..78
     r14: .... .... 3456 78..
     r14: .... .... 3456 78..
  b at offset 0 in xmm1: .... .... .... ..78
  b at offset 1 in zmm1: .... .... .... ..78
  b at offset 2 in zmm1: .... .... .... ...0
  w at offset 0 in xmm1: .... .... .... 7878
  w at offset 1 in zmm1: .... .... .... ..78
  w at offset 2 in zmm1: .... .... .... ...0
  d at offset 0 in xmm1: .... .... .... 7878
  d at offset 1 in zmm1: .... .... 78.. ..78
  d at offset 2 in zmm1: .... .... 5678 ....
  q at offset 0 in xmm1: 1234 5678 .... 7878
  q at offset 1 in zmm1: 7812 3456 78.. ..78
  d at offset 2 in zmm1: .... .... 5678 ....
  d: .... .... .... ...0
    zmm2: .... .... .... ..-1  .... .... .... ..-1 - .... .... .... ..-1  .... .... .... ..-1 + .... .... .... ..-1  .... .... .... ..-1 - .... .... .... ..-1  .... .... .... ..-1
    zmm1: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - 1234 5678 1234 5678  1234 5678 .... 7878
    zmm2: .... .... .... ..-1  .... .... .... ..-1 - .... .... .... ..-1  .... .... .... ..-1 + .... .... .... ..-1  .... .... .... ..-1 - .... .... .... ..-1  FFFF FFFF FFFF 78FF
    zmm3: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... 78..
  END

wFromX($xmm, $offset)

Get the word from the numbered xmm register and return it in a variable.

     Parameter  Description
  1  $xmm       Numbered xmm
  2  $offset    Offset in bytes

Example:

    Mov r15, 0x12345678;
    bRegIntoZmm(r15, 1,  0);
    bRegIntoZmm(r15, 1,  1);
    dRegIntoZmm(r15, 1,  4);
    dRegIntoZmm(r15, 1,  8);
    dRegIntoZmm(r15, 1, 12);
    PrintOutRegisterInHex xmm(1);
    PrintOutRegisterInHex zmm(1);

    bRegFromZmm(r15, 1, 1);
    PrintOutRegisterInHex r15;

    bFromX(1, 0)->outNL;
    bFromZ(1, 0)->outNL;

    dRegFromZmm(r14, 1, 3);
    PrintOutRegisterInHex r14;

    wRegFromZmm(r14, 1, 3);
    PrintOutRegisterInHex r14;

    bFromX(1, 0)->outNL;
    bFromZ(1, 1)->outNL;
    bFromZ(1, 2)->outNL;


    wFromX(1, 0)->outNL;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    wFromZ(1, 1)->outNL;
    wFromZ(1, 2)->outNL;

    dFromX(1, 0)->outNL;
    dFromZ(1, 1)->outNL;
    dFromZ(1, 2)->outNL;

    qFromX(1, 0)->outNL;
    qFromZ(1, 1)->outNL;
    dFromZ(1, 2)->outNL;

    K( offset => 1 << 5)->dFromPointInZ(zmm(1))->outNL;

    Mov       r15, 2;
    Kmovq k7, r15;
    LoadZmm 2, map {0xff} 1..64;
    PrintOutRegisterInHex zmm2;
    Vmovdqu8 zmmM (2, 7), zmm(1);
    Vmovdqu8 zmmMZ(3, 7), zmm(1);
    PrintOutRegisterInHex zmm1, zmm2, zmm3;

    ok Assemble eq => <<END;
    xmm1: 1234 5678 1234 5678  1234 5678 .... 7878
    zmm1: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - 1234 5678 1234 5678  1234 5678 .... 7878
     r15: .... .... 1234 5678
  b at offset 0 in xmm1: .... .... .... ..78
  b at offset 0 in zmm1: .... .... .... ..78
     r14: .... .... 3456 78..
     r14: .... .... 3456 78..
  b at offset 0 in xmm1: .... .... .... ..78
  b at offset 1 in zmm1: .... .... .... ..78
  b at offset 2 in zmm1: .... .... .... ...0
  w at offset 0 in xmm1: .... .... .... 7878
  w at offset 1 in zmm1: .... .... .... ..78
  w at offset 2 in zmm1: .... .... .... ...0
  d at offset 0 in xmm1: .... .... .... 7878
  d at offset 1 in zmm1: .... .... 78.. ..78
  d at offset 2 in zmm1: .... .... 5678 ....
  q at offset 0 in xmm1: 1234 5678 .... 7878
  q at offset 1 in zmm1: 7812 3456 78.. ..78
  d at offset 2 in zmm1: .... .... 5678 ....
  d: .... .... .... ...0
    zmm2: .... .... .... ..-1  .... .... .... ..-1 - .... .... .... ..-1  .... .... .... ..-1 + .... .... .... ..-1  .... .... .... ..-1 - .... .... .... ..-1  .... .... .... ..-1
    zmm1: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - 1234 5678 1234 5678  1234 5678 .... 7878
    zmm2: .... .... .... ..-1  .... .... .... ..-1 - .... .... .... ..-1  .... .... .... ..-1 + .... .... .... ..-1  .... .... .... ..-1 - .... .... .... ..-1  FFFF FFFF FFFF 78FF
    zmm3: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... 78..
  END

dFromX($xmm, $offset)

Get the double word from the numbered xmm register and return it in a variable.

     Parameter  Description
  1  $xmm       Numbered xmm
  2  $offset    Offset in bytes

Example:

    Mov r15, 0x12345678;
    bRegIntoZmm(r15, 1,  0);
    bRegIntoZmm(r15, 1,  1);
    dRegIntoZmm(r15, 1,  4);
    dRegIntoZmm(r15, 1,  8);
    dRegIntoZmm(r15, 1, 12);
    PrintOutRegisterInHex xmm(1);
    PrintOutRegisterInHex zmm(1);

    bRegFromZmm(r15, 1, 1);
    PrintOutRegisterInHex r15;

    bFromX(1, 0)->outNL;
    bFromZ(1, 0)->outNL;

    dRegFromZmm(r14, 1, 3);
    PrintOutRegisterInHex r14;

    wRegFromZmm(r14, 1, 3);
    PrintOutRegisterInHex r14;

    bFromX(1, 0)->outNL;
    bFromZ(1, 1)->outNL;
    bFromZ(1, 2)->outNL;

    wFromX(1, 0)->outNL;
    wFromZ(1, 1)->outNL;
    wFromZ(1, 2)->outNL;


    dFromX(1, 0)->outNL;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    dFromZ(1, 1)->outNL;
    dFromZ(1, 2)->outNL;

    qFromX(1, 0)->outNL;
    qFromZ(1, 1)->outNL;
    dFromZ(1, 2)->outNL;

    K( offset => 1 << 5)->dFromPointInZ(zmm(1))->outNL;

    Mov       r15, 2;
    Kmovq k7, r15;
    LoadZmm 2, map {0xff} 1..64;
    PrintOutRegisterInHex zmm2;
    Vmovdqu8 zmmM (2, 7), zmm(1);
    Vmovdqu8 zmmMZ(3, 7), zmm(1);
    PrintOutRegisterInHex zmm1, zmm2, zmm3;

    ok Assemble eq => <<END;
    xmm1: 1234 5678 1234 5678  1234 5678 .... 7878
    zmm1: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - 1234 5678 1234 5678  1234 5678 .... 7878
     r15: .... .... 1234 5678
  b at offset 0 in xmm1: .... .... .... ..78
  b at offset 0 in zmm1: .... .... .... ..78
     r14: .... .... 3456 78..
     r14: .... .... 3456 78..
  b at offset 0 in xmm1: .... .... .... ..78
  b at offset 1 in zmm1: .... .... .... ..78
  b at offset 2 in zmm1: .... .... .... ...0
  w at offset 0 in xmm1: .... .... .... 7878
  w at offset 1 in zmm1: .... .... .... ..78
  w at offset 2 in zmm1: .... .... .... ...0
  d at offset 0 in xmm1: .... .... .... 7878
  d at offset 1 in zmm1: .... .... 78.. ..78
  d at offset 2 in zmm1: .... .... 5678 ....
  q at offset 0 in xmm1: 1234 5678 .... 7878
  q at offset 1 in zmm1: 7812 3456 78.. ..78
  d at offset 2 in zmm1: .... .... 5678 ....
  d: .... .... .... ...0
    zmm2: .... .... .... ..-1  .... .... .... ..-1 - .... .... .... ..-1  .... .... .... ..-1 + .... .... .... ..-1  .... .... .... ..-1 - .... .... .... ..-1  .... .... .... ..-1
    zmm1: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - 1234 5678 1234 5678  1234 5678 .... 7878
    zmm2: .... .... .... ..-1  .... .... .... ..-1 - .... .... .... ..-1  .... .... .... ..-1 + .... .... .... ..-1  .... .... .... ..-1 - .... .... .... ..-1  FFFF FFFF FFFF 78FF
    zmm3: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... 78..
  END

qFromX($xmm, $offset)

Get the quad word from the numbered xmm register and return it in a variable.

     Parameter  Description
  1  $xmm       Numbered xmm
  2  $offset    Offset in bytes

Example:

    Mov r15, 0x12345678;
    bRegIntoZmm(r15, 1,  0);
    bRegIntoZmm(r15, 1,  1);
    dRegIntoZmm(r15, 1,  4);
    dRegIntoZmm(r15, 1,  8);
    dRegIntoZmm(r15, 1, 12);
    PrintOutRegisterInHex xmm(1);
    PrintOutRegisterInHex zmm(1);

    bRegFromZmm(r15, 1, 1);
    PrintOutRegisterInHex r15;

    bFromX(1, 0)->outNL;
    bFromZ(1, 0)->outNL;

    dRegFromZmm(r14, 1, 3);
    PrintOutRegisterInHex r14;

    wRegFromZmm(r14, 1, 3);
    PrintOutRegisterInHex r14;

    bFromX(1, 0)->outNL;
    bFromZ(1, 1)->outNL;
    bFromZ(1, 2)->outNL;

    wFromX(1, 0)->outNL;
    wFromZ(1, 1)->outNL;
    wFromZ(1, 2)->outNL;

    dFromX(1, 0)->outNL;
    dFromZ(1, 1)->outNL;
    dFromZ(1, 2)->outNL;


    qFromX(1, 0)->outNL;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    qFromZ(1, 1)->outNL;
    dFromZ(1, 2)->outNL;

    K( offset => 1 << 5)->dFromPointInZ(zmm(1))->outNL;

    Mov       r15, 2;
    Kmovq k7, r15;
    LoadZmm 2, map {0xff} 1..64;
    PrintOutRegisterInHex zmm2;
    Vmovdqu8 zmmM (2, 7), zmm(1);
    Vmovdqu8 zmmMZ(3, 7), zmm(1);
    PrintOutRegisterInHex zmm1, zmm2, zmm3;

    ok Assemble eq => <<END;
    xmm1: 1234 5678 1234 5678  1234 5678 .... 7878
    zmm1: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - 1234 5678 1234 5678  1234 5678 .... 7878
     r15: .... .... 1234 5678
  b at offset 0 in xmm1: .... .... .... ..78
  b at offset 0 in zmm1: .... .... .... ..78
     r14: .... .... 3456 78..
     r14: .... .... 3456 78..
  b at offset 0 in xmm1: .... .... .... ..78
  b at offset 1 in zmm1: .... .... .... ..78
  b at offset 2 in zmm1: .... .... .... ...0
  w at offset 0 in xmm1: .... .... .... 7878
  w at offset 1 in zmm1: .... .... .... ..78
  w at offset 2 in zmm1: .... .... .... ...0
  d at offset 0 in xmm1: .... .... .... 7878
  d at offset 1 in zmm1: .... .... 78.. ..78
  d at offset 2 in zmm1: .... .... 5678 ....
  q at offset 0 in xmm1: 1234 5678 .... 7878
  q at offset 1 in zmm1: 7812 3456 78.. ..78
  d at offset 2 in zmm1: .... .... 5678 ....
  d: .... .... .... ...0
    zmm2: .... .... .... ..-1  .... .... .... ..-1 - .... .... .... ..-1  .... .... .... ..-1 + .... .... .... ..-1  .... .... .... ..-1 - .... .... .... ..-1  .... .... .... ..-1
    zmm1: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - 1234 5678 1234 5678  1234 5678 .... 7878
    zmm2: .... .... .... ..-1  .... .... .... ..-1 - .... .... .... ..-1  .... .... .... ..-1 + .... .... .... ..-1  .... .... .... ..-1 - .... .... .... ..-1  FFFF FFFF FFFF 78FF
    zmm3: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... 78..
  END

bFromZ($zmm, $offset, %options)

Get the byte from the numbered zmm register and return it in a variable.

     Parameter  Description
  1  $zmm       Numbered zmm
  2  $offset    Offset in bytes
  3  %options   Options

Example:

    Mov r15, 0x12345678;
    bRegIntoZmm(r15, 1,  0);
    bRegIntoZmm(r15, 1,  1);
    dRegIntoZmm(r15, 1,  4);
    dRegIntoZmm(r15, 1,  8);
    dRegIntoZmm(r15, 1, 12);
    PrintOutRegisterInHex xmm(1);
    PrintOutRegisterInHex zmm(1);

    bRegFromZmm(r15, 1, 1);
    PrintOutRegisterInHex r15;

    bFromX(1, 0)->outNL;

    bFromZ(1, 0)->outNL;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲


    dRegFromZmm(r14, 1, 3);
    PrintOutRegisterInHex r14;

    wRegFromZmm(r14, 1, 3);
    PrintOutRegisterInHex r14;

    bFromX(1, 0)->outNL;

    bFromZ(1, 1)->outNL;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲


    bFromZ(1, 2)->outNL;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲


    wFromX(1, 0)->outNL;
    wFromZ(1, 1)->outNL;
    wFromZ(1, 2)->outNL;

    dFromX(1, 0)->outNL;
    dFromZ(1, 1)->outNL;
    dFromZ(1, 2)->outNL;

    qFromX(1, 0)->outNL;
    qFromZ(1, 1)->outNL;
    dFromZ(1, 2)->outNL;

    K( offset => 1 << 5)->dFromPointInZ(zmm(1))->outNL;

    Mov       r15, 2;
    Kmovq k7, r15;
    LoadZmm 2, map {0xff} 1..64;
    PrintOutRegisterInHex zmm2;
    Vmovdqu8 zmmM (2, 7), zmm(1);
    Vmovdqu8 zmmMZ(3, 7), zmm(1);
    PrintOutRegisterInHex zmm1, zmm2, zmm3;

    ok Assemble eq => <<END;
    xmm1: 1234 5678 1234 5678  1234 5678 .... 7878
    zmm1: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - 1234 5678 1234 5678  1234 5678 .... 7878
     r15: .... .... 1234 5678
  b at offset 0 in xmm1: .... .... .... ..78
  b at offset 0 in zmm1: .... .... .... ..78
     r14: .... .... 3456 78..
     r14: .... .... 3456 78..
  b at offset 0 in xmm1: .... .... .... ..78
  b at offset 1 in zmm1: .... .... .... ..78
  b at offset 2 in zmm1: .... .... .... ...0
  w at offset 0 in xmm1: .... .... .... 7878
  w at offset 1 in zmm1: .... .... .... ..78
  w at offset 2 in zmm1: .... .... .... ...0
  d at offset 0 in xmm1: .... .... .... 7878
  d at offset 1 in zmm1: .... .... 78.. ..78
  d at offset 2 in zmm1: .... .... 5678 ....
  q at offset 0 in xmm1: 1234 5678 .... 7878
  q at offset 1 in zmm1: 7812 3456 78.. ..78
  d at offset 2 in zmm1: .... .... 5678 ....
  d: .... .... .... ...0
    zmm2: .... .... .... ..-1  .... .... .... ..-1 - .... .... .... ..-1  .... .... .... ..-1 + .... .... .... ..-1  .... .... .... ..-1 - .... .... .... ..-1  .... .... .... ..-1
    zmm1: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - 1234 5678 1234 5678  1234 5678 .... 7878
    zmm2: .... .... .... ..-1  .... .... .... ..-1 - .... .... .... ..-1  .... .... .... ..-1 + .... .... .... ..-1  .... .... .... ..-1 - .... .... .... ..-1  FFFF FFFF FFFF 78FF
    zmm3: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... 78..
  END

wFromZ($zmm, $offset, %options)

Get the word from the numbered zmm register and return it in a variable.

     Parameter  Description
  1  $zmm       Numbered zmm
  2  $offset    Offset in bytes
  3  %options   Options

Example:

    Mov r15, 0x12345678;
    bRegIntoZmm(r15, 1,  0);
    bRegIntoZmm(r15, 1,  1);
    dRegIntoZmm(r15, 1,  4);
    dRegIntoZmm(r15, 1,  8);
    dRegIntoZmm(r15, 1, 12);
    PrintOutRegisterInHex xmm(1);
    PrintOutRegisterInHex zmm(1);

    bRegFromZmm(r15, 1, 1);
    PrintOutRegisterInHex r15;

    bFromX(1, 0)->outNL;
    bFromZ(1, 0)->outNL;

    dRegFromZmm(r14, 1, 3);
    PrintOutRegisterInHex r14;

    wRegFromZmm(r14, 1, 3);
    PrintOutRegisterInHex r14;

    bFromX(1, 0)->outNL;
    bFromZ(1, 1)->outNL;
    bFromZ(1, 2)->outNL;

    wFromX(1, 0)->outNL;

    wFromZ(1, 1)->outNL;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲


    wFromZ(1, 2)->outNL;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲


    dFromX(1, 0)->outNL;
    dFromZ(1, 1)->outNL;
    dFromZ(1, 2)->outNL;

    qFromX(1, 0)->outNL;
    qFromZ(1, 1)->outNL;
    dFromZ(1, 2)->outNL;

    K( offset => 1 << 5)->dFromPointInZ(zmm(1))->outNL;

    Mov       r15, 2;
    Kmovq k7, r15;
    LoadZmm 2, map {0xff} 1..64;
    PrintOutRegisterInHex zmm2;
    Vmovdqu8 zmmM (2, 7), zmm(1);
    Vmovdqu8 zmmMZ(3, 7), zmm(1);
    PrintOutRegisterInHex zmm1, zmm2, zmm3;

    ok Assemble eq => <<END;
    xmm1: 1234 5678 1234 5678  1234 5678 .... 7878
    zmm1: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - 1234 5678 1234 5678  1234 5678 .... 7878
     r15: .... .... 1234 5678
  b at offset 0 in xmm1: .... .... .... ..78
  b at offset 0 in zmm1: .... .... .... ..78
     r14: .... .... 3456 78..
     r14: .... .... 3456 78..
  b at offset 0 in xmm1: .... .... .... ..78
  b at offset 1 in zmm1: .... .... .... ..78
  b at offset 2 in zmm1: .... .... .... ...0
  w at offset 0 in xmm1: .... .... .... 7878
  w at offset 1 in zmm1: .... .... .... ..78
  w at offset 2 in zmm1: .... .... .... ...0
  d at offset 0 in xmm1: .... .... .... 7878
  d at offset 1 in zmm1: .... .... 78.. ..78
  d at offset 2 in zmm1: .... .... 5678 ....
  q at offset 0 in xmm1: 1234 5678 .... 7878
  q at offset 1 in zmm1: 7812 3456 78.. ..78
  d at offset 2 in zmm1: .... .... 5678 ....
  d: .... .... .... ...0
    zmm2: .... .... .... ..-1  .... .... .... ..-1 - .... .... .... ..-1  .... .... .... ..-1 + .... .... .... ..-1  .... .... .... ..-1 - .... .... .... ..-1  .... .... .... ..-1
    zmm1: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - 1234 5678 1234 5678  1234 5678 .... 7878
    zmm2: .... .... .... ..-1  .... .... .... ..-1 - .... .... .... ..-1  .... .... .... ..-1 + .... .... .... ..-1  .... .... .... ..-1 - .... .... .... ..-1  FFFF FFFF FFFF 78FF
    zmm3: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... 78..
  END

dFromZ($zmm, $offset, %options)

Get the double word from the numbered zmm register and return it in a variable.

     Parameter  Description
  1  $zmm       Numbered zmm
  2  $offset    Offset in bytes
  3  %options   Options

Example:

    Mov r15, 0x12345678;
    bRegIntoZmm(r15, 1,  0);
    bRegIntoZmm(r15, 1,  1);
    dRegIntoZmm(r15, 1,  4);
    dRegIntoZmm(r15, 1,  8);
    dRegIntoZmm(r15, 1, 12);
    PrintOutRegisterInHex xmm(1);
    PrintOutRegisterInHex zmm(1);

    bRegFromZmm(r15, 1, 1);
    PrintOutRegisterInHex r15;

    bFromX(1, 0)->outNL;
    bFromZ(1, 0)->outNL;

    dRegFromZmm(r14, 1, 3);
    PrintOutRegisterInHex r14;

    wRegFromZmm(r14, 1, 3);
    PrintOutRegisterInHex r14;

    bFromX(1, 0)->outNL;
    bFromZ(1, 1)->outNL;
    bFromZ(1, 2)->outNL;

    wFromX(1, 0)->outNL;
    wFromZ(1, 1)->outNL;
    wFromZ(1, 2)->outNL;

    dFromX(1, 0)->outNL;

    dFromZ(1, 1)->outNL;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲


    dFromZ(1, 2)->outNL;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲


    qFromX(1, 0)->outNL;
    qFromZ(1, 1)->outNL;

    dFromZ(1, 2)->outNL;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲


    K( offset => 1 << 5)->dFromPointInZ(zmm(1))->outNL;

    Mov       r15, 2;
    Kmovq k7, r15;
    LoadZmm 2, map {0xff} 1..64;
    PrintOutRegisterInHex zmm2;
    Vmovdqu8 zmmM (2, 7), zmm(1);
    Vmovdqu8 zmmMZ(3, 7), zmm(1);
    PrintOutRegisterInHex zmm1, zmm2, zmm3;

    ok Assemble eq => <<END;
    xmm1: 1234 5678 1234 5678  1234 5678 .... 7878
    zmm1: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - 1234 5678 1234 5678  1234 5678 .... 7878
     r15: .... .... 1234 5678
  b at offset 0 in xmm1: .... .... .... ..78
  b at offset 0 in zmm1: .... .... .... ..78
     r14: .... .... 3456 78..
     r14: .... .... 3456 78..
  b at offset 0 in xmm1: .... .... .... ..78
  b at offset 1 in zmm1: .... .... .... ..78
  b at offset 2 in zmm1: .... .... .... ...0
  w at offset 0 in xmm1: .... .... .... 7878
  w at offset 1 in zmm1: .... .... .... ..78
  w at offset 2 in zmm1: .... .... .... ...0
  d at offset 0 in xmm1: .... .... .... 7878
  d at offset 1 in zmm1: .... .... 78.. ..78
  d at offset 2 in zmm1: .... .... 5678 ....
  q at offset 0 in xmm1: 1234 5678 .... 7878
  q at offset 1 in zmm1: 7812 3456 78.. ..78
  d at offset 2 in zmm1: .... .... 5678 ....
  d: .... .... .... ...0
    zmm2: .... .... .... ..-1  .... .... .... ..-1 - .... .... .... ..-1  .... .... .... ..-1 + .... .... .... ..-1  .... .... .... ..-1 - .... .... .... ..-1  .... .... .... ..-1
    zmm1: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - 1234 5678 1234 5678  1234 5678 .... 7878
    zmm2: .... .... .... ..-1  .... .... .... ..-1 - .... .... .... ..-1  .... .... .... ..-1 + .... .... .... ..-1  .... .... .... ..-1 - .... .... .... ..-1  FFFF FFFF FFFF 78FF
    zmm3: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... 78..
  END

qFromZ($zmm, $offset, %options)

Get the quad word from the numbered zmm register and return it in a variable.

     Parameter  Description
  1  $zmm       Numbered zmm
  2  $offset    Offset in bytes
  3  %options   Options

Example:

    Mov r15, 0x12345678;
    bRegIntoZmm(r15, 1,  0);
    bRegIntoZmm(r15, 1,  1);
    dRegIntoZmm(r15, 1,  4);
    dRegIntoZmm(r15, 1,  8);
    dRegIntoZmm(r15, 1, 12);
    PrintOutRegisterInHex xmm(1);
    PrintOutRegisterInHex zmm(1);

    bRegFromZmm(r15, 1, 1);
    PrintOutRegisterInHex r15;

    bFromX(1, 0)->outNL;
    bFromZ(1, 0)->outNL;

    dRegFromZmm(r14, 1, 3);
    PrintOutRegisterInHex r14;

    wRegFromZmm(r14, 1, 3);
    PrintOutRegisterInHex r14;

    bFromX(1, 0)->outNL;
    bFromZ(1, 1)->outNL;
    bFromZ(1, 2)->outNL;

    wFromX(1, 0)->outNL;
    wFromZ(1, 1)->outNL;
    wFromZ(1, 2)->outNL;

    dFromX(1, 0)->outNL;
    dFromZ(1, 1)->outNL;
    dFromZ(1, 2)->outNL;

    qFromX(1, 0)->outNL;

    qFromZ(1, 1)->outNL;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    dFromZ(1, 2)->outNL;

    K( offset => 1 << 5)->dFromPointInZ(zmm(1))->outNL;

    Mov       r15, 2;
    Kmovq k7, r15;
    LoadZmm 2, map {0xff} 1..64;
    PrintOutRegisterInHex zmm2;
    Vmovdqu8 zmmM (2, 7), zmm(1);
    Vmovdqu8 zmmMZ(3, 7), zmm(1);
    PrintOutRegisterInHex zmm1, zmm2, zmm3;

    ok Assemble eq => <<END;
    xmm1: 1234 5678 1234 5678  1234 5678 .... 7878
    zmm1: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - 1234 5678 1234 5678  1234 5678 .... 7878
     r15: .... .... 1234 5678
  b at offset 0 in xmm1: .... .... .... ..78
  b at offset 0 in zmm1: .... .... .... ..78
     r14: .... .... 3456 78..
     r14: .... .... 3456 78..
  b at offset 0 in xmm1: .... .... .... ..78
  b at offset 1 in zmm1: .... .... .... ..78
  b at offset 2 in zmm1: .... .... .... ...0
  w at offset 0 in xmm1: .... .... .... 7878
  w at offset 1 in zmm1: .... .... .... ..78
  w at offset 2 in zmm1: .... .... .... ...0
  d at offset 0 in xmm1: .... .... .... 7878
  d at offset 1 in zmm1: .... .... 78.. ..78
  d at offset 2 in zmm1: .... .... 5678 ....
  q at offset 0 in xmm1: 1234 5678 .... 7878
  q at offset 1 in zmm1: 7812 3456 78.. ..78
  d at offset 2 in zmm1: .... .... 5678 ....
  d: .... .... .... ...0
    zmm2: .... .... .... ..-1  .... .... .... ..-1 - .... .... .... ..-1  .... .... .... ..-1 + .... .... .... ..-1  .... .... .... ..-1 - .... .... .... ..-1  .... .... .... ..-1
    zmm1: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - 1234 5678 1234 5678  1234 5678 .... 7878
    zmm2: .... .... .... ..-1  .... .... .... ..-1 - .... .... .... ..-1  .... .... .... ..-1 + .... .... .... ..-1  .... .... .... ..-1 - .... .... .... ..-1  FFFF FFFF FFFF 78FF
    zmm3: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... 78..
  END

Mask

Operations on mask registers

SetMaskRegister($mask, $start, $length)

Set the mask register to ones starting at the specified position for the specified length and zeroes elsewhere.

     Parameter  Description
  1  $mask      Number of mask register to set
  2  $start     Register containing start position or 0 for position 0
  3  $length    Register containing end position

Example:

    Mov rax, 8;
    Mov rsi, -1;

    Inc rsi; SetMaskRegister(0, rax, rsi); PrintOutRegisterInHex k0;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲


    Inc rsi; SetMaskRegister(1, rax, rsi); PrintOutRegisterInHex k1;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲


    Inc rsi; SetMaskRegister(2, rax, rsi); PrintOutRegisterInHex k2;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲


    Inc rsi; SetMaskRegister(3, rax, rsi); PrintOutRegisterInHex k3;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲


    Inc rsi; SetMaskRegister(4, rax, rsi); PrintOutRegisterInHex k4;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲


    Inc rsi; SetMaskRegister(5, rax, rsi); PrintOutRegisterInHex k5;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲


    Inc rsi; SetMaskRegister(6, rax, rsi); PrintOutRegisterInHex k6;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲


    Inc rsi; SetMaskRegister(7, rax, rsi); PrintOutRegisterInHex k7;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲


    ok Assemble eq => <<END;
      k0: .... .... .... ...0
      k1: .... .... .... .1..
      k2: .... .... .... .3..
      k3: .... .... .... .7..
      k4: .... .... .... .F..
      k5: .... .... .... 1F..
      k6: .... .... .... 3F..
      k7: .... .... .... 7F..
  END

LoadBitsIntoMaskRegister($mask, $prefix, @values)

Load a bit string specification into a mask register in two clocks.

     Parameter  Description
  1  $mask      Number of mask register to load
  2  $prefix    Prefix bits
  3  @values    +n 1 bits -n 0 bits

Example:

    for (0..7)
     {ClearRegisters "k$_";
      K($_,$_)->setMaskBit("k$_");
      PrintOutRegisterInHex "k$_";
     }

    ClearRegisters k7;

    LoadBitsIntoMaskRegister(7, '1010', -4, +4, -2, +2, -1, +1, -1, +1);  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    PrintOutRegisterInHex "k7";

    ok Assemble(debug => 0, eq => <<END, avx512=>1);
      k0: .... .... .... ...1
      k1: .... .... .... ...2
      k2: .... .... .... ...4
      k3: .... .... .... ...8
      k4: .... .... .... ..10
      k5: .... .... .... ..20
      k6: .... .... .... ..40
      k7: .... .... .... ..80
      k7: .... .... ...A .F35
  END

At a point

Load data into a zmm register at the indoicated point and retrieve data fromn a zmm regisiter at the indicated ppint.

InsertZeroIntoRegisterAtPoint($point, $in)

Insert a zero into the specified register at the point indicated by another general purpose or mask register moving the higher bits one position to the left.

     Parameter  Description
  1  $point     Register with a single 1 at the insertion point
  2  $in        Register to be inserted into.

Example:

    Mov r15, 0x100;                                                               # Given a register with a single one in it indicating the desired position,
    Mov r14, 0xFFDC;                                                              # Insert a zero into the register at that position shifting the bits above that position up left one to make space for the new zero.
    Mov r13, 0xF03F;
    PrintOutRegisterInHex         r14, r15;

    InsertZeroIntoRegisterAtPoint r15, r14;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    PrintOutRegisterInHex r14;
    Or r14, r15;                                                                  # Replace the inserted zero with a one
    PrintOutRegisterInHex r14;
    InsertOneIntoRegisterAtPoint r15, r13;
    PrintOutRegisterInHex r13;
    ok Assemble(debug => 0, eq => <<END, avx512=>0);
     r14: .... .... .... FFDC
     r15: .... .... .... .1..
     r14: .... .... ...1 FEDC
     r14: .... .... ...1 FFDC
     r13: .... .... ...1 E13F
  END

InsertOneIntoRegisterAtPoint($point, $in)

Insert a one into the specified register at the point indicated by another register.

     Parameter  Description
  1  $point     Register with a single 1 at the insertion point
  2  $in        Register to be inserted into.

Example:

    Mov r15, 0x100;                                                               # Given a register with a single one in it indicating the desired position,
    Mov r14, 0xFFDC;                                                              # Insert a zero into the register at that position shifting the bits above that position up left one to make space for the new zero.
    Mov r13, 0xF03F;
    PrintOutRegisterInHex         r14, r15;
    InsertZeroIntoRegisterAtPoint r15, r14;
    PrintOutRegisterInHex r14;
    Or r14, r15;                                                                  # Replace the inserted zero with a one
    PrintOutRegisterInHex r14;

    InsertOneIntoRegisterAtPoint r15, r13;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    PrintOutRegisterInHex r13;
    ok Assemble(debug => 0, eq => <<END, avx512=>0);
     r14: .... .... .... FFDC
     r15: .... .... .... .1..
     r14: .... .... ...1 FEDC
     r14: .... .... ...1 FFDC
     r13: .... .... ...1 E13F
  END

Comparison codes

The codes used to specify what sort of comparison to perform

Structured Programming

Structured programming constructs

If

If statements

If($jump, $then, $else)

If statement.

     Parameter  Description
  1  $jump      Jump op code of variable
  2  $then      Then - required
  3  $else      Else - optional

Example:

    my $n0 = K(zero => 0);

    If $n0 == 0,  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    Then
     {PrintOutStringNL "zero == 0";
     },
    Ef {$n0 == 1}
    Then
     {PrintOutStringNL "zero == 1";
     },
    Else
     {PrintOutStringNL "zero == 2";
     };

    my $n1 = K(one => 1);

    If $n1 == 0,  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    Then
     {PrintOutStringNL "one == 0";
     },
    Ef {$n1 == 1}
    Then
     {PrintOutStringNL "one == 1";
     },
    Else
     {PrintOutStringNL "one == 2";
     };

    my $n2 = K(two => 2);

    If $n2 == 0,  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    Then
     {PrintOutStringNL "two == 0";
     },
    Ef {$n2 == 1}
    Then
     {PrintOutStringNL "two == 1";
     },
    Else
     {PrintOutStringNL "two == 2";
     };

    ok Assemble eq => <<END, avx512=>0;
  zero == 0
  one == 1
  two == 2
  END

    my $a = K(key => 1);

    If $a > 0,  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    Then {Mov rax, 1},
    Else {Mov rax, 2};
    PrintOutRegisterInHex rax;

    ok Assemble eq=><<END, avx512=>1;
     rax: .... .... .... ...1
  END

Then($block)

Then block for an If statement.

     Parameter  Description
  1  $block     Then block

Example:

    my $n0 = K(zero => 0);
    If $n0 == 0,

    Then  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

     {PrintOutStringNL "zero == 0";
     },
    Ef {$n0 == 1}

    Then  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

     {PrintOutStringNL "zero == 1";
     },
    Else
     {PrintOutStringNL "zero == 2";
     };

    my $n1 = K(one => 1);
    If $n1 == 0,

    Then  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

     {PrintOutStringNL "one == 0";
     },
    Ef {$n1 == 1}

    Then  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

     {PrintOutStringNL "one == 1";
     },
    Else
     {PrintOutStringNL "one == 2";
     };

    my $n2 = K(two => 2);
    If $n2 == 0,

    Then  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

     {PrintOutStringNL "two == 0";
     },
    Ef {$n2 == 1}

    Then  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

     {PrintOutStringNL "two == 1";
     },
    Else
     {PrintOutStringNL "two == 2";
     };

    ok Assemble eq => <<END, avx512=>0;
  zero == 0
  one == 1
  two == 2
  END

    my $a = K(key => 1);
    If $a > 0,

    Then {Mov rax, 1},  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    Else {Mov rax, 2};
    PrintOutRegisterInHex rax;

    ok Assemble eq=><<END, avx512=>1;
     rax: .... .... .... ...1
  END

    PrintCString  ($stdout, V(str => Rs("abc\0def")));
    PrintCStringNL($stdout, V(str => Rs("ABC\0DEF")));
    ok Assemble eq => <<END;
  abcABC
  END

    my $a = V(a => 3);  $a->outNL;
    my $b = K(b => 2);  $b->outNL;
    my $c = $a +  $b; $c->outNL;
    my $d = $c -  $a; $d->outNL;
    my $g = $a *  $b; $g->outNL;
    my $h = $g /  $b; $h->outNL;
    my $i = $a %  $b; $i->outNL;

    If ($a == 3,

    Then  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

     {PrintOutStringNL "a == 3"
     },
    Else
     {PrintOutStringNL "a != 3"
     });

    ++$a; $a->outNL;
    --$a; $a->outNL;

    ok Assemble eq => <<END, avx512=>0;
  a: .... .... .... ...3
  b: .... .... .... ...2
  (a add b): .... .... .... ...5
  ((a add b) sub a): .... .... .... ...2
  (a times b): .... .... .... ...6
  ((a times b) / b): .... .... .... ...3
  (a % b): .... .... .... ...1
  a == 3
  a: .... .... .... ...4
  a: .... .... .... ...3
  END

Else($block)

Else block for an If statement.

     Parameter  Description
  1  $block     Else block

Example:

    my $n0 = K(zero => 0);
    If $n0 == 0,
    Then
     {PrintOutStringNL "zero == 0";
     },
    Ef {$n0 == 1}
    Then
     {PrintOutStringNL "zero == 1";
     },

    Else  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

     {PrintOutStringNL "zero == 2";
     };

    my $n1 = K(one => 1);
    If $n1 == 0,
    Then
     {PrintOutStringNL "one == 0";
     },
    Ef {$n1 == 1}
    Then
     {PrintOutStringNL "one == 1";
     },

    Else  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

     {PrintOutStringNL "one == 2";
     };

    my $n2 = K(two => 2);
    If $n2 == 0,
    Then
     {PrintOutStringNL "two == 0";
     },
    Ef {$n2 == 1}
    Then
     {PrintOutStringNL "two == 1";
     },

    Else  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

     {PrintOutStringNL "two == 2";
     };

    ok Assemble eq => <<END, avx512=>0;
  zero == 0
  one == 1
  two == 2
  END

    my $a = K(key => 1);
    If $a > 0,
    Then {Mov rax, 1},

    Else {Mov rax, 2};  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    PrintOutRegisterInHex rax;

    ok Assemble eq=><<END, avx512=>1;
     rax: .... .... .... ...1
  END

    PrintCString  ($stdout, V(str => Rs("abc\0def")));
    PrintCStringNL($stdout, V(str => Rs("ABC\0DEF")));
    ok Assemble eq => <<END;
  abcABC
  END

    my $a = V(a => 3);  $a->outNL;
    my $b = K(b => 2);  $b->outNL;
    my $c = $a +  $b; $c->outNL;
    my $d = $c -  $a; $d->outNL;
    my $g = $a *  $b; $g->outNL;
    my $h = $g /  $b; $h->outNL;
    my $i = $a %  $b; $i->outNL;

    If ($a == 3,
    Then
     {PrintOutStringNL "a == 3"
     },

    Else  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

     {PrintOutStringNL "a != 3"
     });

    ++$a; $a->outNL;
    --$a; $a->outNL;

    ok Assemble eq => <<END, avx512=>0;
  a: .... .... .... ...3
  b: .... .... .... ...2
  (a add b): .... .... .... ...5
  ((a add b) sub a): .... .... .... ...2
  (a times b): .... .... .... ...6
  ((a times b) / b): .... .... .... ...3
  (a % b): .... .... .... ...1
  a == 3
  a: .... .... .... ...4
  a: .... .... .... ...3
  END

ifOr($conditions, $Then, $Else)

Execute then or else block based on a multiplicity of OR conditions executed until one succeeds.

     Parameter    Description
  1  $conditions  Array of conditions
  2  $Then        Then sub
  3  $Else        Else sub

Example:

    my $a = K key => 1;
    my $b = K key => 1;


    ifOr [sub{$a==$a}, sub{$a==$a}],  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    Then
     {PrintOutStringNL "AAAA11";
     },
    Else
     {PrintOutStringNL "AAAA22";
     };


    ifOr [sub{$a==$a}, sub{$a!=$a}],  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    Then
     {PrintOutStringNL "BBBB11";
     },
     Else
     {PrintOutStringNL "BBBB22";
     };


    ifOr [sub{$a!=$a}, sub{$a==$a}],  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    Then
     {PrintOutStringNL "CCCC11";
     },
     Else
     {PrintOutStringNL "CCCC22";
     };


    ifOr [sub{$a!=$b}, sub{$a!=$b}],  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    Then
     {PrintOutStringNL "DDDD11";
     },
     Else
     {PrintOutStringNL "DDDD22";
     };

    ok Assemble eq => <<END, avx512=>1;
  AAAA11
  BBBB11
  CCCC11
  DDDD22
  END

ifAnd($conditions, $Then, $Else)

Execute then or else block based on a multiplicity of AND conditions executed until one fails.

     Parameter    Description
  1  $conditions  Array of conditions
  2  $Then        Then sub
  3  $Else        Else sub

Example:

  #latest:

Ef($condition, $then, $else)

Else if block for an If statement.

     Parameter   Description
  1  $condition  Condition
  2  $then       Then block
  3  $else       Else block

Example:

    my $n0 = K(zero => 0);
    If $n0 == 0,
    Then
     {PrintOutStringNL "zero == 0";
     },

    Ef {$n0 == 1}  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    Then
     {PrintOutStringNL "zero == 1";
     },
    Else
     {PrintOutStringNL "zero == 2";
     };

    my $n1 = K(one => 1);
    If $n1 == 0,
    Then
     {PrintOutStringNL "one == 0";
     },

    Ef {$n1 == 1}  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    Then
     {PrintOutStringNL "one == 1";
     },
    Else
     {PrintOutStringNL "one == 2";
     };

    my $n2 = K(two => 2);
    If $n2 == 0,
    Then
     {PrintOutStringNL "two == 0";
     },

    Ef {$n2 == 1}  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    Then
     {PrintOutStringNL "two == 1";
     },
    Else
     {PrintOutStringNL "two == 2";
     };

    ok Assemble eq => <<END, avx512=>0;
  zero == 0
  one == 1
  two == 2
  END

Via flags

If depending on the flags register.

IfEq($then, $else)

If equal execute the then block else the else block.

     Parameter  Description
  1  $then      Then - required
  2  $else      Else - optional

Example:

    my $cmp = sub
     {my ($a, $b) = @_;

      for my $op(qw(eq ne lt le gt ge))
       {Mov rax, $a;
        Cmp rax, $b;
        my $Op = ucfirst $op;
        eval qq(If$Op Then {PrintOutStringNL("$a $op $b")}, Else {PrintOutStringNL("$a NOT $op $b")});
        $@ and confess $@;
       }
     };
    &$cmp(1,1);
    &$cmp(1,2);
    &$cmp(3,2);
    Assemble eq => <<END, avx512=>0;
  1 eq 1
  1 NOT ne 1
  1 NOT lt 1
  1 le 1
  1 NOT gt 1
  1 ge 1
  1 NOT eq 2
  1 ne 2
  1 lt 2
  1 le 2
  1 NOT gt 2
  1 NOT ge 2
  3 NOT eq 2
  3 ne 2
  3 NOT lt 2
  3 NOT le 2
  3 gt 2
  3 ge 2
  END

IfNe($then, $else)

If not equal execute the then block else the else block.

     Parameter  Description
  1  $then      Then - required
  2  $else      Else - optional

Example:

    my $cmp = sub
     {my ($a, $b) = @_;

      for my $op(qw(eq ne lt le gt ge))
       {Mov rax, $a;
        Cmp rax, $b;
        my $Op = ucfirst $op;
        eval qq(If$Op Then {PrintOutStringNL("$a $op $b")}, Else {PrintOutStringNL("$a NOT $op $b")});
        $@ and confess $@;
       }
     };
    &$cmp(1,1);
    &$cmp(1,2);
    &$cmp(3,2);
    Assemble eq => <<END, avx512=>0;
  1 eq 1
  1 NOT ne 1
  1 NOT lt 1
  1 le 1
  1 NOT gt 1
  1 ge 1
  1 NOT eq 2
  1 ne 2
  1 lt 2
  1 le 2
  1 NOT gt 2
  1 NOT ge 2
  3 NOT eq 2
  3 ne 2
  3 NOT lt 2
  3 NOT le 2
  3 gt 2
  3 ge 2
  END

IfNz($then, $else)

If the zero flag is not set then execute the then block else the else block.

     Parameter  Description
  1  $then      Then - required
  2  $else      Else - optional

Example:

    Mov rax, 0;
    Test rax,rax;

    IfNz  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    Then
     {PrintOutRegisterInHex rax;
     },
    Else
     {PrintOutRegisterInHex rbx;
     };
    Mov rax, 1;
    Test rax,rax;

    IfNz  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    Then
     {PrintOutRegisterInHex rcx;
     },
    Else
     {PrintOutRegisterInHex rdx;
     };

    ok Assemble(avx512=>0) =~ m(rbx.*rcx)s;

IfZ($then, $else)

If the zero flag is set then execute the then block else the else block.

     Parameter  Description
  1  $then      Then - required
  2  $else      Else - optional

Example:

    SetZF;
    PrintOutZF;
    ClearZF;
    PrintOutZF;
    SetZF;
    PrintOutZF;
    SetZF;
    PrintOutZF;
    ClearZF;
    PrintOutZF;

    SetZF;

    IfZ  Then {PrintOutStringNL "Zero"},     Else {PrintOutStringNL "NOT zero"};  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    ClearZF;
    IfNz Then {PrintOutStringNL "NOT zero"}, Else {PrintOutStringNL "Zero"};

    Mov r15, 5;
    Shr r15, 1; IfC  Then {PrintOutStringNL "Carry"}   , Else {PrintOutStringNL "NO carry"};
    Shr r15, 1; IfC  Then {PrintOutStringNL "Carry"}   , Else {PrintOutStringNL "NO carry"};
    Shr r15, 1; IfNc Then {PrintOutStringNL "NO carry"}, Else {PrintOutStringNL "Carry"};
    Shr r15, 1; IfNc Then {PrintOutStringNL "NO carry"}, Else {PrintOutStringNL "Carry"};

    ok Assemble eq => <<END, avx512=>0;
  ZF=1
  ZF=0
  ZF=1
  ZF=1
  ZF=0
  Zero
  NOT zero
  Carry
  NO carry
  Carry
  NO carry
  END

IfC($then, $else)

If the carry flag is set then execute the then block else the else block.

     Parameter  Description
  1  $then      Then - required
  2  $else      Else - optional

Example:

    SetZF;
    PrintOutZF;
    ClearZF;
    PrintOutZF;
    SetZF;
    PrintOutZF;
    SetZF;
    PrintOutZF;
    ClearZF;
    PrintOutZF;

    SetZF;
    IfZ  Then {PrintOutStringNL "Zero"},     Else {PrintOutStringNL "NOT zero"};
    ClearZF;
    IfNz Then {PrintOutStringNL "NOT zero"}, Else {PrintOutStringNL "Zero"};

    Mov r15, 5;

    Shr r15, 1; IfC  Then {PrintOutStringNL "Carry"}   , Else {PrintOutStringNL "NO carry"};  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲


    Shr r15, 1; IfC  Then {PrintOutStringNL "Carry"}   , Else {PrintOutStringNL "NO carry"};  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    Shr r15, 1; IfNc Then {PrintOutStringNL "NO carry"}, Else {PrintOutStringNL "Carry"};
    Shr r15, 1; IfNc Then {PrintOutStringNL "NO carry"}, Else {PrintOutStringNL "Carry"};

    ok Assemble eq => <<END, avx512=>0;
  ZF=1
  ZF=0
  ZF=1
  ZF=1
  ZF=0
  Zero
  NOT zero
  Carry
  NO carry
  Carry
  NO carry
  END

IfNc($then, $else)

If the carry flag is not set then execute the then block else the else block.

     Parameter  Description
  1  $then      Then - required
  2  $else      Else - optional

Example:

    SetZF;
    PrintOutZF;
    ClearZF;
    PrintOutZF;
    SetZF;
    PrintOutZF;
    SetZF;
    PrintOutZF;
    ClearZF;
    PrintOutZF;

    SetZF;
    IfZ  Then {PrintOutStringNL "Zero"},     Else {PrintOutStringNL "NOT zero"};
    ClearZF;
    IfNz Then {PrintOutStringNL "NOT zero"}, Else {PrintOutStringNL "Zero"};

    Mov r15, 5;
    Shr r15, 1; IfC  Then {PrintOutStringNL "Carry"}   , Else {PrintOutStringNL "NO carry"};
    Shr r15, 1; IfC  Then {PrintOutStringNL "Carry"}   , Else {PrintOutStringNL "NO carry"};

    Shr r15, 1; IfNc Then {PrintOutStringNL "NO carry"}, Else {PrintOutStringNL "Carry"};  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲


    Shr r15, 1; IfNc Then {PrintOutStringNL "NO carry"}, Else {PrintOutStringNL "Carry"};  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲


    ok Assemble eq => <<END, avx512=>0;
  ZF=1
  ZF=0
  ZF=1
  ZF=1
  ZF=0
  Zero
  NOT zero
  Carry
  NO carry
  Carry
  NO carry
  END

IfLt($then, $else)

If less than execute the then block else the else block.

     Parameter  Description
  1  $then      Then - required
  2  $else      Else - optional

Example:

    my $cmp = sub
     {my ($a, $b) = @_;

      for my $op(qw(eq ne lt le gt ge))
       {Mov rax, $a;
        Cmp rax, $b;
        my $Op = ucfirst $op;
        eval qq(If$Op Then {PrintOutStringNL("$a $op $b")}, Else {PrintOutStringNL("$a NOT $op $b")});
        $@ and confess $@;
       }
     };
    &$cmp(1,1);
    &$cmp(1,2);
    &$cmp(3,2);
    Assemble eq => <<END, avx512=>0;
  1 eq 1
  1 NOT ne 1
  1 NOT lt 1
  1 le 1
  1 NOT gt 1
  1 ge 1
  1 NOT eq 2
  1 ne 2
  1 lt 2
  1 le 2
  1 NOT gt 2
  1 NOT ge 2
  3 NOT eq 2
  3 ne 2
  3 NOT lt 2
  3 NOT le 2
  3 gt 2
  3 ge 2
  END

IfLe($then, $else)

If less than or equal execute the then block else the else block.

     Parameter  Description
  1  $then      Then - required
  2  $else      Else - optional

Example:

    my $cmp = sub
     {my ($a, $b) = @_;

      for my $op(qw(eq ne lt le gt ge))
       {Mov rax, $a;
        Cmp rax, $b;
        my $Op = ucfirst $op;
        eval qq(If$Op Then {PrintOutStringNL("$a $op $b")}, Else {PrintOutStringNL("$a NOT $op $b")});
        $@ and confess $@;
       }
     };
    &$cmp(1,1);
    &$cmp(1,2);
    &$cmp(3,2);
    Assemble eq => <<END, avx512=>0;
  1 eq 1
  1 NOT ne 1
  1 NOT lt 1
  1 le 1
  1 NOT gt 1
  1 ge 1
  1 NOT eq 2
  1 ne 2
  1 lt 2
  1 le 2
  1 NOT gt 2
  1 NOT ge 2
  3 NOT eq 2
  3 ne 2
  3 NOT lt 2
  3 NOT le 2
  3 gt 2
  3 ge 2
  END

IfGt($then, $else)

If greater than execute the then block else the else block.

     Parameter  Description
  1  $then      Then - required
  2  $else      Else - optional

Example:

    my $cmp = sub
     {my ($a, $b) = @_;

      for my $op(qw(eq ne lt le gt ge))
       {Mov rax, $a;
        Cmp rax, $b;
        my $Op = ucfirst $op;
        eval qq(If$Op Then {PrintOutStringNL("$a $op $b")}, Else {PrintOutStringNL("$a NOT $op $b")});
        $@ and confess $@;
       }
     };
    &$cmp(1,1);
    &$cmp(1,2);
    &$cmp(3,2);
    Assemble eq => <<END, avx512=>0;
  1 eq 1
  1 NOT ne 1
  1 NOT lt 1
  1 le 1
  1 NOT gt 1
  1 ge 1
  1 NOT eq 2
  1 ne 2
  1 lt 2
  1 le 2
  1 NOT gt 2
  1 NOT ge 2
  3 NOT eq 2
  3 ne 2
  3 NOT lt 2
  3 NOT le 2
  3 gt 2
  3 ge 2
  END

IfGe($then, $else)

If greater than or equal execute the then block else the else block.

     Parameter  Description
  1  $then      Then - required
  2  $else      Else - optional

Example:

    my $cmp = sub
     {my ($a, $b) = @_;

      for my $op(qw(eq ne lt le gt ge))
       {Mov rax, $a;
        Cmp rax, $b;
        my $Op = ucfirst $op;
        eval qq(If$Op Then {PrintOutStringNL("$a $op $b")}, Else {PrintOutStringNL("$a NOT $op $b")});
        $@ and confess $@;
       }
     };
    &$cmp(1,1);
    &$cmp(1,2);
    &$cmp(3,2);
    Assemble eq => <<END, avx512=>0;
  1 eq 1
  1 NOT ne 1
  1 NOT lt 1
  1 le 1
  1 NOT gt 1
  1 ge 1
  1 NOT eq 2
  1 ne 2
  1 lt 2
  1 le 2
  1 NOT gt 2
  1 NOT ge 2
  3 NOT eq 2
  3 ne 2
  3 NOT lt 2
  3 NOT le 2
  3 gt 2
  3 ge 2
  END

Boolean Blocks

Perform blocks depending on boolean conditions

Pass($block)

Pass block for an OrBlock.

     Parameter  Description
  1  $block     Block

Example:

    Mov rax, 1;
    OrBlock
     {my ($pass, $end, $start) = @_;
      Cmp rax, 1;
      Je  $pass;
      Cmp rax, 2;
      Je  $pass;
      PrintOutStringNL "Fail";
     }

    Pass  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

     {my ($end, $pass, $start) = @_;

      PrintOutStringNL "Pass";  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

     };

    ok Assemble eq => <<END, avx512=>0;

  Pass  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

  END

Fail($block)

Fail block for an AndBlock.

     Parameter  Description
  1  $block     Block

Example:

    Mov rax, 1; Mov rdx, 2;
    AndBlock
     {my ($fail, $end, $start) = @_;
      Cmp rax, 1;
      Jne $fail;
      Cmp rdx, 2;
      Jne $fail;
      PrintOutStringNL "Pass";
     }

    Fail  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

     {my ($end, $fail, $start) = @_;

      PrintOutStringNL "Fail";  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

     };

    ok Assemble eq => <<END, avx512=>0;
  Pass
  END

Block($code)

Execute a block of code with labels supplied for the start and end of this code.

     Parameter  Description
  1  $code      Block of code

Example:

  #latest:

AndBlock($test, $fail)

Short circuit and: execute a block of code to test conditions which, if all of them pass, allows the first block to continue successfully else if one of the conditions fails we execute the optional fail block.

     Parameter  Description
  1  $test      Block
  2  $fail      Optional failure block

Example:

    Mov rax, 1; Mov rdx, 2;

    AndBlock  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

     {my ($fail, $end, $start) = @_;
      Cmp rax, 1;
      Jne $fail;
      Cmp rdx, 2;
      Jne $fail;
      PrintOutStringNL "Pass";
     }
    Fail
     {my ($end, $fail, $start) = @_;
      PrintOutStringNL "Fail";
     };

    ok Assemble eq => <<END, avx512=>0;
  Pass
  END

OrBlock($test, $pass)

Short circuit or: execute a block of code to test conditions which, if one of them is met, leads on to the execution of the pass block, if all of the tests fail we continue withe the test block.

     Parameter  Description
  1  $test      Tests
  2  $pass      Optional block to execute on success

Example:

    Mov rax, 1;

    OrBlock  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

     {my ($pass, $end, $start) = @_;
      Cmp rax, 1;
      Je  $pass;
      Cmp rax, 2;
      Je  $pass;
      PrintOutStringNL "Fail";
     }
    Pass
     {my ($end, $pass, $start) = @_;
      PrintOutStringNL "Pass";
     };

    ok Assemble eq => <<END, avx512=>0;
  Pass
  END

Iteration

Iterate with for loops

For($block, $register, $limit, $increment)

For - iterate the block as long as register is less than limit incrementing by increment each time. Nota Bene: The register is not explicitly set to zero as you might want to start at some other number.

     Parameter   Description
  1  $block      Block
  2  $register   Register
  3  $limit      Limit on loop
  4  $increment  Increment on each iteration

Example:

    For  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

     {my ($start, $end, $next) = @_;
      Cmp rax, 3;
      Jge $end;
      PrintOutRegisterInHex rax;
     } rax, 16, 1;

    ok Assemble eq => <<END, avx512=>0;
     rax: .... .... .... ...0
     rax: .... .... .... ...1
     rax: .... .... .... ...2
  END

ToZero($block, $register)

Iterate a block the number of times specified in the register which is decremented to zero.

     Parameter  Description
  1  $block     Block
  2  $register  Limit register

Example:

    Mov rax, 3;

    ToZero  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

     {PrintOutStringNL "AAAA";
     }  rax;
    ok Assemble eq => <<END, clocks=>4374;
  AAAA
  AAAA
  AAAA
  END

ForIn($full, $last, $register, $limitRegister, $increment)

For - iterate the full block as long as register plus increment is less than than limit incrementing by increment each time then perform the last block with the remainder which might be of length zero.

     Parameter       Description
  1  $full           Block for full block
  2  $last           Block for last block
  3  $register       Register
  4  $limitRegister  Register containing upper limit of loop
  5  $increment      Increment on each iteration

Example:

    my $remainder = r15, my $offset = r14;

    Mov $offset, 0;
    Mov $remainder, 10;


    ForIn  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

     {PrintOutStringNL "AAAA";
      PrintOutRegisterInHex $offset, $remainder;
     }
    Then
     {PrintOutStringNL "BBBB";
      PrintOutRegisterInHex $offset, $remainder;
     }, $offset, $remainder, 4;

    ok Assemble eq => <<END;
  AAAA
     r14: .... .... .... ...0
     r15: .... .... .... ...A
  AAAA
     r14: .... .... .... ...4
     r15: .... .... .... ...A
  BBBB
     r14: .... .... .... ...8
     r15: .... .... .... ...2
  END

uptoNTimes($code, $register, $limit)

Execute a block of code up to a constant number of times controlled by the named register.

     Parameter  Description
  1  $code      Block of code
  2  $register  Register controlling loop
  3  $limit     Constant limit

Example:

    uptoNTimes  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

     {my ($end, $start) = @_;
      PrintOutRegisterInHex rax;
     } rax, 3;

    ok Assemble eq => <<END;
     rax: .... .... .... ...3
     rax: .... .... .... ...2
     rax: .... .... .... ...1
  END

ForEver($block)

Iterate for ever.

     Parameter  Description
  1  $block     Block to iterate

Example:

    my $e = q(readChar);


    ForEver  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

     {my ($start, $end) = @_;
      ReadChar;
      Cmp rax, 0xa;
      Jle $end;
      PrintOutRaxAsChar;
      PrintOutRaxAsCharNL;
     };
    PrintOutNL;

    Assemble keep => $e;

    my $r = qx(echo "ABCDCBA" | ./$e);
    is_deeply $r, <<END;
  AA
  BB
  CC
  DD
  CC
  BB
  AA

  END
    unlink $e;

Subroutine

Create and call subroutines with the option of placing them into an area that can be writtento a file and reloaded and executed by another process.

Subroutine($block, %options)

Create a subroutine that can be called in assembler code.

     Parameter  Description
  1  $block     Block of code as a sub
  2  %options   Options

Example:

    my $g = V g => 3;

    my $s = Subroutine  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

     {my ($p, $s, $sub) = @_;
      my $g = $$p{g};
      $g->copy($g - 1);
      $g->outNL;
      If $g > 0,
      Then
       {$sub->call(parameters=>{g => $g});
       };
     } parameters=>[qw(g)], name => 'ref';

    $s->call(parameters=>{g => $g});

    ok Assemble eq => <<END;
  g: .... .... .... ...2
  g: .... .... .... ...1
  g: .... .... .... ...0
  END

    package InnerStructure                                                        # Test passing structures into a subroutine
     {use Data::Table::Text qw(:all);
      sub new($)                                                                  # Create a new structure
       {my ($value) = @_;                                                         # Value for structure variable
        describe(value => Nasm::X86::V(var => $value))
       };
      sub describe(%)                                                             # Describe the components of a structure
       {my (%options) = @_;                                                       # Options
        genHash(__PACKAGE__,
          value => $options{value},
         );
       }
     }

    package OuterStructure
     {use Data::Table::Text qw(:all);
      sub new($$)                                                                 # Create a new structure
       {my ($valueOuter, $valueInner) = @_;                                       # Value for structure variable
        describe
         (value => Nasm::X86::V(var => $valueOuter),
          inner => InnerStructure::new($valueInner),
         )
       };
      sub describe(%)                                                             # Describe the components of a structure
       {my (%options) = @_;                                                       # Options
        genHash(__PACKAGE__,
          value => $options{value},
          inner => $options{inner},
         );
       }
     }

    my $t = OuterStructure::new(42, 4);


    my $s = Subroutine  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

     {my ($parameters, $structures, $sub) = @_;                                   # Variable parameters, structure variables, structure copies, subroutine description

      $$structures{test}->value->setReg(rax);
      Mov r15, 84;
      $$structures{test}->value->getReg(r15);
      Mov r15, 8;
      $$structures{test}->inner->value->getReg(r15);

      $$parameters{p}->setReg(rdx);
     } parameters=>[qw(p)], structures => {test => $t}, name => 'test';

    my $T = OuterStructure::new(42, 4);
    my $V = V parameter => 21;

    $s->call(parameters=>{p => $V}, structures=>{test => $T});

    PrintOutRaxInDecNL;
    Mov rax, rdx;
    PrintOutRaxInDecNL;
    $t->value->outInDecNL;
    $t->inner->value->outInDecNL;
    $T->value->outInDecNL;
    $T->inner->value->outInDecNL;
    ok Assemble eq => <<END, avx512=>0;
  42
  21
  var: 42
  var: 4
  var: 84
  var: 8
  END


    my $s = Subroutine                                                              # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲



    my $t = Subroutine                                                              # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

Nasm::X86::Area::writeLibraryHeader($area, $subs)

Load a hash of subroutine names and offsets into an area

     Parameter  Description
  1  $area      Area to load into
  2  $subs      Hash of subroutine names to offsets

Example:

    my $a = CreateArea;

    my $u = $a->CreateTree(stringTree=>1);
    $u->putKeyString(constantString("ab"), K key => 1);
    $u->putKeyString(constantString("ac"), K key => 3);
    $u->putKeyString(constantString("𝕒𝕒"), K key => 4);

    my %s = (ab => 2, 𝕒𝕒 =>8, 𝗮𝗮𝗮=>12, 𝝰𝝰𝝰𝝰=>16);                                 # Subroutine names and offsets

    $a->writeLibraryHeader({%s});
    my ($inter, $subroutines) = $a->readLibraryHeader($u);

    $inter->dump("TT");

    ok Assemble eq => <<END, clocks=>4374;
  TT
  At:  1C0                    length:    2,  data:  200,  nodes:  240,  first:   40, root, leaf
    Index:    0    1
    Keys :    1    4
    Data :    2    8
  end
  END

    my $a = CreateArea;
    my $t = $a->CreateTree;

    K(loop => 16)->for(sub
     {my ($i, $start, $next, $end) = @_;
      my $T = $a->CreateTree;
      $t->put($i, $T);
      $t->size->outNL;
     });

    K(loop => 16)->for(sub
     {my ($i, $start, $next, $end) = @_;
      $t->popSubTree;
      $t->size->outNL;
     });

    ok Assemble eq => <<END, avx512=>1;
  size of tree: .... .... .... ...1
  size of tree: .... .... .... ...2
  size of tree: .... .... .... ...3
  size of tree: .... .... .... ...4
  size of tree: .... .... .... ...5
  size of tree: .... .... .... ...6
  size of tree: .... .... .... ...7
  size of tree: .... .... .... ...8
  size of tree: .... .... .... ...9
  size of tree: .... .... .... ...A
  size of tree: .... .... .... ...B
  size of tree: .... .... .... ...C
  size of tree: .... .... .... ...D
  size of tree: .... .... .... ...E
  size of tree: .... .... .... ...F
  size of tree: .... .... .... ..10
  size of tree: .... .... .... ...F
  size of tree: .... .... .... ...E
  size of tree: .... .... .... ...D
  size of tree: .... .... .... ...C
  size of tree: .... .... .... ...B
  size of tree: .... .... .... ...A
  size of tree: .... .... .... ...9
  size of tree: .... .... .... ...8
  size of tree: .... .... .... ...7
  size of tree: .... .... .... ...6
  size of tree: .... .... .... ...5
  size of tree: .... .... .... ...4
  size of tree: .... .... .... ...3
  size of tree: .... .... .... ...2
  size of tree: .... .... .... ...1
  size of tree: .... .... .... ...0
  END

    my $a = CreateArea;
    my $t = $a->CreateTree;
    my $T = $a->CreateTree;
    $t->push($T);
    $a->dump("AA");
    $t->popSubTree;
    $a->dump("BB");

    ok Assemble eq => <<END, avx512=>1;
  AA
  Area     Size:     4096    Used:      384
  .... .... .... ...0 | __10 ____ ____ ____  80.1 ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | C0__ ____ ____ ____  .1__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  .1__ .1__ __.1 ____
  BB
  Area     Size:     4096    Used:      384
  .... .... .... ...0 | __10 ____ ____ ____  80.1 ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  .1__ .1__ __.1 ____
  END

Nasm::X86::Subroutine::call($sub, %options)

Call a sub optionally passing it parameters.

     Parameter  Description
  1  $sub       Subroutine descriptor
  2  %options   Options

Example:

   my $h = genHash("AAAA",
     a => V(a =>  1),
     b => V(b =>  2),
     c => V(c =>  3),
     d => V(d =>  4),
     e => V(e =>  5),
     f => V(f =>  6),
     g => V(g =>  7),
     h => V(h =>  8),
     i => V(i =>  9),
     j => V(j => 10),
     k => V(k => 11),
     l => V(l => 12));

   my $i = genHash("AAAA",
     a => V(a => 0x011),
     b => V(b => 0x022),
     c => V(c => 0x033),
     d => V(d => 0x044),
     e => V(e => 0x055),
     f => V(f => 0x066),
     g => V(g => 0x077),
     h => V(h => 0x088),
     i => V(i => 0x099),
     j => V(j => 0x111),
     k => V(k => 0x222),
     l => V(l => 0x333));

    my $s = Subroutine
     {my ($p, $s, $sub) = @_;
      my $h = $$s{h};
      my $a = $$p{a};
      $$h{a}->outNL;
      $$h{b}->outNL;
      $$h{c}->outNL;
      $$h{d}->outNL;
      $$h{e}->outNL;
      $$h{f}->outNL;
      $$h{g}->outNL;
      $$h{h}->outNL;
      $$h{i}->outNL;
      $$h{j}->outNL;
      $$h{k}->outNL;
      $$h{l}->outNL;
      $$p{b}->outNL;
     } name => "s", structures => {h => $h}, parameters=>[qw(a b)];

    $s->call(structures => {h => $i}, parameters=>{a=>V(key => 1), b=>V(key => 0x111)});
    $s->call(structures => {h => $h}, parameters=>{a=>V(key => 2), b=>V(key => 0x222)});

    Assemble eq=><<END, clocks=>9151, label => 'aa';
  a: .... .... .... ..11
  b: .... .... .... ..22
  c: .... .... .... ..33
  d: .... .... .... ..44
  e: .... .... .... ..55
  f: .... .... .... ..66
  g: .... .... .... ..77
  h: .... .... .... ..88
  i: .... .... .... ..99
  j: .... .... .... .111
  k: .... .... .... .222
  l: .... .... .... .333
  b: .... .... .... .111
  a: .... .... .... ...1
  b: .... .... .... ...2
  c: .... .... .... ...3
  d: .... .... .... ...4
  e: .... .... .... ...5
  f: .... .... .... ...6
  g: .... .... .... ...7
  h: .... .... .... ...8
  i: .... .... .... ...9
  j: .... .... .... ...A
  k: .... .... .... ...B
  l: .... .... .... ...C
  b: .... .... .... .222
  END


   my $h = genHash("AAAA",
     a => V(a =>  1),
     b => V(b =>  2),
     c => V(c =>  3),
     d => V(d =>  4),
     e => V(e =>  5),
     f => V(f =>  6),
     g => V(g =>  7),
     h => V(h =>  8),
     i => V(i =>  9),
     j => V(j => 10),
     k => V(k => 11),
     l => V(l => 12));

    my $s = Subroutine
     {my ($p, $s, $sub) = @_;
      my $h = $$s{h};
      my $a = $$p{a};
      $$h{a}->outNL;
      $$h{b}->outNL;
      $$h{c}->outNL;
      $$h{d}->outNL;
      $$h{e}->outNL;
      $$h{f}->outNL;
      $$h{g}->outNL;
      $$h{h}->outNL;
      $$h{i}->outNL;
      $$h{j}->outNL;
      $$h{k}->outNL;
      $$h{l}->outNL;
      If $a > 0,
      Then
       {$sub->call(structures => {h => $h}, parameters=>{a=>V(key => 0), b=>V(key => 0x111)});
       };
     } name => "s", structures => {h => $h}, parameters=>[qw(a b)];

    $s->call(structures => {h => $h}, parameters=>{a=>V(key => 2), b=>V(key => 0x222)});

    Assemble eq=><<END, clocks=>17609, label => 'aaa';
  a: .... .... .... ...1
  b: .... .... .... ...2
  c: .... .... .... ...3
  d: .... .... .... ...4
  e: .... .... .... ...5
  f: .... .... .... ...6
  g: .... .... .... ...7
  h: .... .... .... ...8
  i: .... .... .... ...9
  j: .... .... .... ...A
  k: .... .... .... ...B
  l: .... .... .... ...C
  a: .... .... .... ...1
  b: .... .... .... ...2
  c: .... .... .... ...3
  d: .... .... .... ...4
  e: .... .... .... ...5
  f: .... .... .... ...6
  g: .... .... .... ...7
  h: .... .... .... ...8
  i: .... .... .... ...9
  j: .... .... .... ...A
  k: .... .... .... ...B
  l: .... .... .... ...C
  END

Nasm::X86::Subroutine::inline($sub, %options)

Call a sub by in-lining it, optionally passing it parameters.

     Parameter  Description
  1  $sub       Subroutine descriptor
  2  %options   Options

Example:

    my $s = Subroutine                                                            # Load and print rax
     {my ($p, $s, $sub) = @_;
      $$p{ppp}->outNL;
     } name => "s", parameters=>[qw(ppp)];

    $s->call  (parameters => {ppp => V ppp => 0x99});                             # Call   378
    $s->inline(parameters => {ppp => V ppp => 0xaa});                             # Inline 364

    Assemble eq=><<END, avx512=>1;
  ppp: .... .... .... ..99
  ppp: .... .... .... ..AA
  END

Trace back

Generate a subroutine calll trace back

PrintOutTraceBack($message)

Print sub routine track back on stdout and then exit with a message.

     Parameter  Description
  1  $message   Reason why we are printing the trace back and then stopping

Example:

    my $d = V depth => 3;                                                         # Create a variable on the stack

    my $s = Subroutine
     {my ($p, $s, $sub) = @_;                                                     # Parameters, structures, subroutine descriptor
      $$p{depth}->outNL;
      my $d = $$p{depth}->copy($$p{depth} - 1);                                   # Modify the variable referenced by the parameter

      If $d > 0,
      Then
       {$sub->call(parameters => {depth => $d});                                  # Recurse
       };

     } parameters =>[qw(depth)], name => 'ref';

    $s->call(parameters=>{depth => $d});

    $d->outNL;
    ok Assemble eq => <<END, avx512=>0;
  depth: .... .... .... ...3
  depth: .... .... .... ...2
  depth: .... .... .... ...1
  depth: .... .... .... ...0
  END

OnSegv()

Request a trace back followed by exit on a segv signal.

Example:

    OnSegv();                                                                     # Request a trace back followed by exit on a segv signal.  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲


    my $t = Subroutine                                                            # Subroutine that will cause an error to occur to force a trace back to be printed
     {Mov r15, 0;
      Mov r15, "[r15]";                                                           # Try to read an unmapped memory location
     } [qw(in)], name => 'sub that causes a segv';                                # The name that will appear in the trace back

    $t->call(K(in, 42));

    ok Assemble(debug => 0, keep2 => 'signal', avx512=>0, eq => <<END, avx512=>0);# Cannot use the emulator because it does not understand signals

  Subroutine trace back, depth:  1
  0000 0000 0000 002A    sub that causes a segv

  END

Comments

Inserts comments into the generated assember code.

Comment(@comment)

Insert a comment into the assembly code.

     Parameter  Description
  1  @comment   Text of comment

Example:

    Comment "Print a string from memory";  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    my $s = "Hello World";
    Mov rax, Rs($s);
    Mov rdi, length $s;
    PrintOutMemory;
    Exit(0);

    ok Assemble(avx512=>0) =~ m(Hello World);

Print

Print the values of registers and memory interspersed with constant strings. The print commands do not overwrite the free registers as doing so would make debugging difficult.

Strings

Print constant and variable strings

PrintOutNL()

Print a new line to stderr.

Example:

    Mov rax, 0x666;
    PrintOutRightInDec rax,  8;

    PrintOutNL;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲


    ok Assemble avx512=>0, eq=><<END;
      1638
  END

    my $q = Rs('abababab');
    Mov(rax, "[$q]");
    PrintOutString "rax: ";
    PrintOutRaxInHex;

    PrintOutNL;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    Xor rax, rax;
    PrintOutString "rax: ";
    PrintOutRaxInHex;

    PrintOutNL;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲


    ok Assemble avx512=>0, eq=><<END;
  rax: 6261 6261 6261 6261
  rax: .... .... .... ...0
  END

PrintOutString(@string)

Print a constant string to stdout.

     Parameter  Description
  1  @string    String

Example:

    Mov rax, 0x666;
    PrintOutRightInDec rax,  8;
    PrintOutNL;

    ok Assemble avx512=>0, eq=><<END;
      1638
  END

    my $q = Rs('abababab');
    Mov(rax, "[$q]");

    PrintOutString "rax: ";  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    PrintOutRaxInHex;
    PrintOutNL;
    Xor rax, rax;

    PrintOutString "rax: ";  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    PrintOutRaxInHex;
    PrintOutNL;

    ok Assemble avx512=>0, eq=><<END;
  rax: 6261 6261 6261 6261
  rax: .... .... .... ...0
  END

PrintOutStringNL(@string)

Print a constant string to stdout followed by a new line.

     Parameter  Description
  1  @string    String

Example:

    PrintOutStringNL "Hello World";  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲


    PrintOutStringNL "Hello
World";  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    PrintErrStringNL "Hello World";

    ok Assemble eq => <<END, avx512=>0, label=>'t1';
  Hello World
  Hello
  World
  END

PrintOutSpace($spaces)

Print a constant number of spaces to stdout.

     Parameter  Description
  1  $spaces    Number of spaces if not one.

Example:

    Mov rax, 42;
    Mov rbx, 21;
    PrintOutRaxInDec;

    PrintOutSpace;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    PrintOutRaxInDecNL;

    PrintOutRax_InHex;

    PrintOutSpace;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    PrintOutRax_InHexNL;

    PrintOutRegisterInHex rbx;
    PrintOutNL;

    PrintOutRightInBin K(key => 17), K width => 16;

    PrintOutSpace;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    PrintOutRightInDec K(key => 17), K width => 2;

    PrintOutSpace;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    PrintOutRightInHex K(key => 17), K width => 2;
    PrintOutNL;

    ok Assemble eq => <<END;
  42 42
  ____ ____ ____ __2A ____ ____ ____ __2A
     rbx: .... .... .... ..15

             10001 17 11
  END

Registers

Print selected registers in a variety of formats.

PrintOutRaxInHex()

Write the content of register rax in hexadecimal in big endian notation to stout.

Example:

    Mov rax, 0x666;
    PrintOutRightInDec rax,  8;
    PrintOutNL;

    ok Assemble avx512=>0, eq=><<END;
      1638
  END

    my $q = Rs('abababab');
    Mov(rax, "[$q]");
    PrintOutString "rax: ";

    PrintOutRaxInHex;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    PrintOutNL;
    Xor rax, rax;
    PrintOutString "rax: ";

    PrintOutRaxInHex;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    PrintOutNL;

    ok Assemble avx512=>0, eq=><<END;
  rax: 6261 6261 6261 6261
  rax: .... .... .... ...0
  END

PrintOutRaxInHexNL()

Write the content of register rax in hexadecimal in big endian notation to stdout followed by a new line.

Example:

    my $s = Rb(0..255);

    Vmovdqu64 xmm1, "[$s]";
    PrintOutRegisterInHex xmm1;
    PrintOutRegisterInHex xmm1;

    Vmovdqu64 ymm1, "[$s]";
    PrintOutRegisterInHex ymm1;
    PrintOutRegisterInHex ymm1;

    Vmovdqu64 zmm1, "[$s]";
    PrintOutRegisterInHex zmm1;
    PrintOutRegisterInHex zmm1;

    ok Assemble eq =><<END;
    xmm1: .F.E .D.C .B.A .9.8  .7.6 .5.4 .3.2 .1..
    xmm1: .F.E .D.C .B.A .9.8  .7.6 .5.4 .3.2 .1..
    ymm1: 1F1E 1D1C 1B1A 1918  1716 1514 1312 1110 - .F.E .D.C .B.A .9.8  .7.6 .5.4 .3.2 .1..
    ymm1: 1F1E 1D1C 1B1A 1918  1716 1514 1312 1110 - .F.E .D.C .B.A .9.8  .7.6 .5.4 .3.2 .1..
    zmm1: 3F3E 3D3C 3B3A 3938  3736 3534 3332 3130 - 2F2E 2D2C 2B2A 2928  2726 2524 2322 2120 + 1F1E 1D1C 1B1A 1918  1716 1514 1312 1110 - .F.E .D.C .B.A .9.8  .7.6 .5.4 .3.2 .1..
    zmm1: 3F3E 3D3C 3B3A 3938  3736 3534 3332 3130 - 2F2E 2D2C 2B2A 2928  2726 2524 2322 2120 + 1F1E 1D1C 1B1A 1918  1716 1514 1312 1110 - .F.E .D.C .B.A .9.8  .7.6 .5.4 .3.2 .1..
  END

PrintOutRax_InHex()

Write the content of register rax in hexadecimal in big endian notation to stout.

Example:

    Mov rax, 42;
    Mov rbx, 21;
    PrintOutRaxInDec;
    PrintOutSpace;
    PrintOutRaxInDecNL;


    PrintOutRax_InHex;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    PrintOutSpace;
    PrintOutRax_InHexNL;

    PrintOutRegisterInHex rbx;
    PrintOutNL;

    PrintOutRightInBin K(key => 17), K width => 16;
    PrintOutSpace;
    PrintOutRightInDec K(key => 17), K width => 2;
    PrintOutSpace;
    PrintOutRightInHex K(key => 17), K width => 2;
    PrintOutNL;

    ok Assemble eq => <<END;
  42 42
  ____ ____ ____ __2A ____ ____ ____ __2A
     rbx: .... .... .... ..15

             10001 17 11
  END

PrintOutRax_InHexNL()

Write the content of register rax in hexadecimal in big endian notation to stdout followed by a new line.

Example:

    Mov rax, 42;
    Mov rbx, 21;
    PrintOutRaxInDec;
    PrintOutSpace;
    PrintOutRaxInDecNL;

    PrintOutRax_InHex;
    PrintOutSpace;

    PrintOutRax_InHexNL;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲


    PrintOutRegisterInHex rbx;
    PrintOutNL;

    PrintOutRightInBin K(key => 17), K width => 16;
    PrintOutSpace;
    PrintOutRightInDec K(key => 17), K width => 2;
    PrintOutSpace;
    PrintOutRightInHex K(key => 17), K width => 2;
    PrintOutNL;

    ok Assemble eq => <<END;
  42 42
  ____ ____ ____ __2A ____ ____ ____ __2A
     rbx: .... .... .... ..15

             10001 17 11
  END

PrintOutRaxInReverseInHex()

Write the content of register rax to stderr in hexadecimal in little endian notation.

Example:

    Mov rax, 0x07654321;
    Shl rax, 32;
    Or  rax, 0x07654321;
    PushR rax;

    PrintOutRaxInHex;
    PrintOutNL;

    PrintOutRaxInReverseInHex;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    PrintOutNL;

    Mov rax, rsp;
    Mov rdi, 8;
    PrintOutMemoryInHex;
    PrintOutNL;
    PopR rax;

    Mov rax, 4096;
    PushR rax;
    Mov rax, rsp;
    Mov rdi, 8;
    PrintOutMemoryInHex;
    PrintOutNL;
    PopR rax;

    ok Assemble eq => <<END, avx512=>0;
  .765 4321 .765 4321
  2143 65.7 2143 65.7
  2143 65.7 2143 65.7
  ..10 .... .... ....
  END

PrintOutOneRegisterInHex($r)

Print the named register as a hex string on stdout.

     Parameter  Description
  1  $r         Register to print

Example:

    Mov rax, 0x22;
    Mov rbx, 0x33;

    PrintOutOneRegisterInHex   rax;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    PrintOutOneRegisterInHexNL rbx;

    ok Assemble eq => <<END;
  .... .... .... ..22.... .... .... ..33
  END

    Mov rax, 0x61;
    PrintOutRaxAsChar;
    Mov rax, 0x62;
    PrintOutRaxAsCharNL;

    ok Assemble eq => <<END;
  ab
  END

PrintOutOneRegisterInHexNL($r)

Print the named register as a hex string on stdout followed by new line.

     Parameter  Description
  1  $r         Register to print

Example:

    Mov rax, 0x22;
    Mov rbx, 0x33;
    PrintOutOneRegisterInHex   rax;

    PrintOutOneRegisterInHexNL rbx;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲


    ok Assemble eq => <<END;
  .... .... .... ..22.... .... .... ..33
  END

    Mov rax, 0x61;
    PrintOutRaxAsChar;
    Mov rax, 0x62;
    PrintOutRaxAsCharNL;

    ok Assemble eq => <<END;
  ab
  END

PrintOutRegisterInHex(@r)

Print the named registers as hex strings on stdout.

     Parameter  Description
  1  @r         Names of the registers to print

Example:

    Mov rax, 42;
    Mov rbx, 21;
    PrintOutRaxInDec;
    PrintOutSpace;
    PrintOutRaxInDecNL;

    PrintOutRax_InHex;
    PrintOutSpace;
    PrintOutRax_InHexNL;


    PrintOutRegisterInHex rbx;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    PrintOutNL;

    PrintOutRightInBin K(key => 17), K width => 16;
    PrintOutSpace;
    PrintOutRightInDec K(key => 17), K width => 2;
    PrintOutSpace;
    PrintOutRightInHex K(key => 17), K width => 2;
    PrintOutNL;

    ok Assemble eq => <<END;
  42 42
  ____ ____ ____ __2A ____ ____ ____ __2A
     rbx: .... .... .... ..15

             10001 17 11
  END

PrintOutRegistersInHex()

Print the general purpose registers in hex.

Example:

    my $q = Rs('abababab');
    Mov r10, 0x10;
    Mov r11, 0x11;
    Mov r12, 0x12;
    Mov r13, 0x13;
    Mov r14, 0x14;
    Mov r15, 0x15;
    Mov  r8, 0x08;
    Mov  r9, 0x09;
    Mov rax, 1;
    Mov rbx, 2;
    Mov rcx, 3;
    Mov rdi, 4;
    Mov rdx, 5;
    Mov rsi, 6;

    PrintOutRegistersInHex;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲


    my $r = Assemble avx512=>0, eq=><<END;
  rfl: .... .... .... .2.2
  r10: .... .... .... ..10
  r11: .... .... .... .2.6
  r12: .... .... .... ..12
  r13: .... .... .... ..13
  r14: .... .... .... ..14
  r15: .... .... .... ..15
   r8: .... .... .... ...8
   r9: .... .... .... ...9
  rax: .... .... .... ...1
  rbx: .... .... .... ...2
  rcx: .... .... ..40 197F
  rdi: .... .... .... ...4
  rdx: .... .... .... ...5
  rsi: .... .... .... ...6
  END

Zero Flag

Print zero flag

PrintOutZF()

Print the zero flag without disturbing it on stdout.

Example:

    SetZF;

    PrintOutZF;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    ClearZF;

    PrintOutZF;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    SetZF;

    PrintOutZF;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    SetZF;

    PrintOutZF;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    ClearZF;

    PrintOutZF;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲


    SetZF;
    IfZ  Then {PrintOutStringNL "Zero"},     Else {PrintOutStringNL "NOT zero"};
    ClearZF;
    IfNz Then {PrintOutStringNL "NOT zero"}, Else {PrintOutStringNL "Zero"};

    Mov r15, 5;
    Shr r15, 1; IfC  Then {PrintOutStringNL "Carry"}   , Else {PrintOutStringNL "NO carry"};
    Shr r15, 1; IfC  Then {PrintOutStringNL "Carry"}   , Else {PrintOutStringNL "NO carry"};
    Shr r15, 1; IfNc Then {PrintOutStringNL "NO carry"}, Else {PrintOutStringNL "Carry"};
    Shr r15, 1; IfNc Then {PrintOutStringNL "NO carry"}, Else {PrintOutStringNL "Carry"};

    ok Assemble eq => <<END, avx512=>0;
  ZF=1
  ZF=0
  ZF=1
  ZF=1
  ZF=0
  Zero
  NOT zero
  Carry
  NO carry
  Carry
  NO carry
  END

Hexadecimal

Print numbers in hexadecimal right justified in a field

PrintOutRightInHex($number, $width)

Write the specified variable in hexadecimal right justified in a field of specified width on stdout.

     Parameter  Description
  1  $number    Number as a variable
  2  $width     Width of output field as a variable

Example:

    Mov rax, 42;
    Mov rbx, 21;
    PrintOutRaxInDec;
    PrintOutSpace;
    PrintOutRaxInDecNL;

    PrintOutRax_InHex;
    PrintOutSpace;
    PrintOutRax_InHexNL;

    PrintOutRegisterInHex rbx;
    PrintOutNL;

    PrintOutRightInBin K(key => 17), K width => 16;
    PrintOutSpace;
    PrintOutRightInDec K(key => 17), K width => 2;
    PrintOutSpace;

    PrintOutRightInHex K(key => 17), K width => 2;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    PrintOutNL;

    ok Assemble eq => <<END;
  42 42
  ____ ____ ____ __2A ____ ____ ____ __2A
     rbx: .... .... .... ..15

             10001 17 11
  END

PrintOutRightInHexNL($number, $width)

Write the specified variable in hexadecimal right justified in a field of specified width on stdout followed by a new line.

     Parameter  Description
  1  $number    Number as a variable
  2  $width     Width of output field as a variable

Example:

    my $N = K number => 0x12345678;

    for my $i(reverse 1..16)

     {PrintOutRightInHexNL $N, $i;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

     }
    ok Assemble eq => <<END;
          12345678
         12345678
        12345678
       12345678
      12345678
     12345678
    12345678
   12345678
  12345678
  2345678
  345678
  45678
  5678
  678
  78
  8
  END

    Mov rax, 0x2a;
    PrintOutRightInDecNL rax, 16;

    PrintOutRightInHexNL rax, 16;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    PrintOutRightInBinNL rax, 16;

    ok Assemble eq => <<END, avx512=>1;
                42
                2A
            101010
  END

Binary

Print numbers in binary right justified in a field

PrintOutRightInBin($number, $width)

Write the specified variable in binary right justified in a field of specified width on stdout.

     Parameter  Description
  1  $number    Number as a variable
  2  $width     Width of output field as a variable

Example:

    Mov rax, 42;
    Mov rbx, 21;
    PrintOutRaxInDec;
    PrintOutSpace;
    PrintOutRaxInDecNL;

    PrintOutRax_InHex;
    PrintOutSpace;
    PrintOutRax_InHexNL;

    PrintOutRegisterInHex rbx;
    PrintOutNL;


    PrintOutRightInBin K(key => 17), K width => 16;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    PrintOutSpace;
    PrintOutRightInDec K(key => 17), K width => 2;
    PrintOutSpace;
    PrintOutRightInHex K(key => 17), K width => 2;
    PrintOutNL;

    ok Assemble eq => <<END;
  42 42
  ____ ____ ____ __2A ____ ____ ____ __2A
     rbx: .... .... .... ..15

             10001 17 11
  END

PrintOutRightInBinNL($number, $width)

Write the specified variable in binary right justified in a field of specified width on stdout followed by a new line.

     Parameter  Description
  1  $number    Number as a variable
  2  $width     Width of output field as a variable

Example:

    K(count => 64)->for(sub
     {my ($index, $start, $next, $end) = @_;

      PrintOutRightInBinNL K(number => 0x99), K(max => 64) - $index;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

     });
    ok Assemble(avx512=>0, eq => <<END);
                                                          10011001
                                                         10011001
                                                        10011001
                                                       10011001
                                                      10011001
                                                     10011001
                                                    10011001
                                                   10011001
                                                  10011001
                                                 10011001
                                                10011001
                                               10011001
                                              10011001
                                             10011001
                                            10011001
                                           10011001
                                          10011001
                                         10011001
                                        10011001
                                       10011001
                                      10011001
                                     10011001
                                    10011001
                                   10011001
                                  10011001
                                 10011001
                                10011001
                               10011001
                              10011001
                             10011001
                            10011001
                           10011001
                          10011001
                         10011001
                        10011001
                       10011001
                      10011001
                     10011001
                    10011001
                   10011001
                  10011001
                 10011001
                10011001
               10011001
              10011001
             10011001
            10011001
           10011001
          10011001
         10011001
        10011001
       10011001
      10011001
     10011001
    10011001
   10011001
  10011001
  0011001
  011001
  11001
  1001
  001
  01
  1
  END

    Mov rax, 0x2a;
    PrintOutRightInDecNL rax, 16;
    PrintOutRightInHexNL rax, 16;

    PrintOutRightInBinNL rax, 16;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲


    ok Assemble eq => <<END, avx512=>1;
                42
                2A
            101010
  END

Decimal

Print numbers in decimal right justified in fields of specified width.

PrintOutRaxInDec()

Print rax in decimal on stdout.

Example:

    Mov rax, 42;
    Mov rbx, 21;

    PrintOutRaxInDec;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    PrintOutSpace;
    PrintOutRaxInDecNL;

    PrintOutRax_InHex;
    PrintOutSpace;
    PrintOutRax_InHexNL;

    PrintOutRegisterInHex rbx;
    PrintOutNL;

    PrintOutRightInBin K(key => 17), K width => 16;
    PrintOutSpace;
    PrintOutRightInDec K(key => 17), K width => 2;
    PrintOutSpace;
    PrintOutRightInHex K(key => 17), K width => 2;
    PrintOutNL;

    ok Assemble eq => <<END;
  42 42
  ____ ____ ____ __2A ____ ____ ____ __2A
     rbx: .... .... .... ..15

             10001 17 11
  END

PrintOutRaxInDecNL()

Print rax in decimal on stdout followed by a new line.

Example:

    Mov rax, 42;
    Mov rbx, 21;
    PrintOutRaxInDec;
    PrintOutSpace;

    PrintOutRaxInDecNL;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲


    PrintOutRax_InHex;
    PrintOutSpace;
    PrintOutRax_InHexNL;

    PrintOutRegisterInHex rbx;
    PrintOutNL;

    PrintOutRightInBin K(key => 17), K width => 16;
    PrintOutSpace;
    PrintOutRightInDec K(key => 17), K width => 2;
    PrintOutSpace;
    PrintOutRightInHex K(key => 17), K width => 2;
    PrintOutNL;

    ok Assemble eq => <<END;
  42 42
  ____ ____ ____ __2A ____ ____ ____ __2A
     rbx: .... .... .... ..15

             10001 17 11
  END

PrintOutRightInDec($number, $width)

Print a variable or register in decimal right justified in a field of the specified width on stdout.

     Parameter  Description
  1  $number    Number as a variable or a register
  2  $width     Width as a variable or constant

Example:

    Mov rax, 42;
    Mov rbx, 21;
    PrintOutRaxInDec;
    PrintOutSpace;
    PrintOutRaxInDecNL;

    PrintOutRax_InHex;
    PrintOutSpace;
    PrintOutRax_InHexNL;

    PrintOutRegisterInHex rbx;
    PrintOutNL;

    PrintOutRightInBin K(key => 17), K width => 16;
    PrintOutSpace;

    PrintOutRightInDec K(key => 17), K width => 2;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    PrintOutSpace;
    PrintOutRightInHex K(key => 17), K width => 2;
    PrintOutNL;

    ok Assemble eq => <<END;
  42 42
  ____ ____ ____ __2A ____ ____ ____ __2A
     rbx: .... .... .... ..15

             10001 17 11
  END

PrintOutRightInDecNL($number, $width)

Print a variable or register in decimal right justified in a field of the specified width on stdout followed by a new line.

     Parameter  Description
  1  $number    Number as a variable or a register
  2  $width     Width as a variable or constant

Example:

    Mov rax, 0x2a;

    PrintOutRightInDecNL rax, 16;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    PrintOutRightInHexNL rax, 16;
    PrintOutRightInBinNL rax, 16;

    ok Assemble eq => <<END, avx512=>1;
                42
                2A
            101010
  END

Text

Print the contents of a register as text.

PrintOutRaxAsText()

Print rax as text on stdout.

Example:

    Mov rax, 0x636261;

    PrintOutRaxAsText;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    Mov rax, 0x64636261;
    PrintOutRaxAsTextNL;

    ok Assemble eq => <<END;
  abcabcd
  END

PrintOutRaxAsTextNL()

Print rax as text on stdout followed by a new line.

Example:

    Mov rax, 0x636261;
    PrintOutRaxAsText;
    Mov rax, 0x64636261;

    PrintOutRaxAsTextNL;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲


    ok Assemble eq => <<END;
  abcabcd
  END

    my $t = Rs('abcdefghi');
    Mov rax, $t;
    Mov rax, "[rax]";

    PrintOutRaxAsTextNL;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    ok Assemble eq => <<END, avx512=>0;
  abcdefgh
  END
  }

  #latest:
  if (1) {                                                                         ;
    my $e = q(parameters);

    (V string => "[rbp+8]")->outInDecNL;
    (V string => "[rbp+16]")->outCStringNL;
    (V string => "[rbp+24]")->outCStringNL;
    (V string => "[rbp+32]")->outCStringNL;
    (V string => "[rbp+40]")->outCStringNL;
    (V string => "[rbp+48]")->outInDecNL;

    (V string => "[rbp+8]")->for(sub
     {my ($index, $start, $next, $end) = @_;
      $index->setReg(rax);
      Inc rax;
      PrintOutRaxInDec;
      Inc rax;
      PrintOutString " : ";
      Shl rax, 3;
      (V string => "[rbp+rax]")->outCStringNL;
     });

    Assemble keep => $e;

    is_deeply scalar(qx(./$e AaAaAaAaAa BbCcDdEe 123456789)), <<END;
  string: 4
  ./parameters
  AaAaAaAaAa
  BbCcDdEe
  123456789
  string: 0
  1 : ./parameters
  2 : AaAaAaAaAa
  3 : BbCcDdEe
  4 : 123456789
  END

    unlink $e;

    K( loop => 16)->for(sub
     {my ($index, $start, $next, $end) = @_;
      $index->setReg(rax);
      Add rax, 0xb0;   Shl rax, 16;
      Mov  ax, 0x9d9d; Shl rax, 8;
      Mov  al, 0xf0;
      PrintOutRaxAsText;
     });
    PrintOutNL;

    ok Assemble eq => <<END, avx512 => 0;
  𝝰𝝱𝝲𝝳𝝴𝝵𝝶𝝷𝝸𝝹𝝺𝝻𝝼𝝽𝝾𝝿
  END

PrintOutRaxAsChar()

Print the character in rax on stdout.

Example:

    my $e = q(readChar);

    ForEver
     {my ($start, $end) = @_;
      ReadChar;
      Cmp rax, 0xa;
      Jle $end;

      PrintOutRaxAsChar;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

      PrintOutRaxAsCharNL;
     };
    PrintOutNL;

    Assemble keep => $e;

    my $r = qx(echo "ABCDCBA" | ./$e);
    is_deeply $r, <<END;
  AA
  BB
  CC
  DD
  CC
  BB
  AA

  END
    unlink $e;

PrintOutRaxAsCharNL()

Print the character in rax on stdout followed by a new line.

Example:

    my $e = q(readChar);

    ForEver
     {my ($start, $end) = @_;
      ReadChar;
      Cmp rax, 0xa;
      Jle $end;
      PrintOutRaxAsChar;

      PrintOutRaxAsCharNL;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

     };
    PrintOutNL;

    Assemble keep => $e;

    my $r = qx(echo "ABCDCBA" | ./$e);
    is_deeply $r, <<END;
  AA
  BB
  CC
  DD
  CC
  BB
  AA

  END
    unlink $e;

Variables

Variable definitions and operations

Definitions

Variable definitions

Nasm::X86::Variable::at($variable)

Return a "[register expression]" to address the data in the variable in the current stack frame.

     Parameter  Description
  1  $variable  Variable descriptor

Example:

  if (1)
   {my $v = V var => 2;
    Mov rax, $v->at;
    PrintOutRegisterInHex rax;
    ok Assemble eq=><<END, avx512=>1;
     rax: .... .... .... ...2
  END
   }

  if (1)
   {my $a = V(key => 0x123);
    is_deeply $a->at,           "[rbp-8*(2)]";
    is_deeply $a->addressExpr, "[rbp-8*(2)]";

    ok !$a->isRef;

    Mov rax, -1;
    Kmovq k1, rax;
    PrintOutRegisterInHex k1;

    K(key => 2)->clearBit(rax);
    PrintOutRegisterInHex rax;

    K(key => 2)->setBit(rax);
    PrintOutRegisterInHex rax;

    K(key => 3)->clearMaskBit(k1);
    PrintOutRegisterInHex k1;

    K(key => 3)->setMaskBit(k1);
    PrintOutRegisterInHex k1;

    K(key => 0)->clearMaskBit(k1);
    PrintOutRegisterInHex k1;

    ClearRegisters k1;
    K(key => 7)->setMaskFirst(k1);
    PrintOutRegisterInHex k1;

    K(key => 3)->spaces($stdout);
    PrintOutRegisterInHex k1;

    my $N = K size => 4096;
    my $A = $N->allocateMemory;
    $A->clearMemory($N);
    ClearMemory($A, $N);

    $A->setReg(rax);
    Mov "dword[rax]",   0x61626364;
    Mov "dword[rax+4]", 0x65666768;

    ($A+8)->copyMemory($A, K key => 8);

    $A->printOutMemory  (K(key => 16));
    $A->printOutMemoryNL(K(key => 16));

    K(K => Rd(0..63))->loadZmm(1);
    PrintOutRegisterInHex zmm1;

    ok Assemble eq => <<END;
      k1: .... .... .... ..-1
     rax: FFFF FFFF FFFF FFFB
     rax: .... .... .... ..-1
      k1: FFFF FFFF FFFF FFF7
      k1: .... .... .... ..-1
      k1: FFFF FFFF FFFF FFFE
      k1: .... .... .... ..7F
         k1: .... .... .... ..7F
  dcbahgfedcbahgfedcbahgfedcbahgfe
    zmm1: .... ...F .... ...E  .... ...D .... ...C - .... ...B .... ...A  .... ...9 .... ...8 + .... ...7 .... ...6  .... ...5 .... ...4 - .... ...3 .... ...2  .... ...1 .... ....
  END
   }

K($name, $expr)

Define a constant variable.

     Parameter  Description
  1  $name      Name of variable
  2  $expr      Initializing expression

Example:

    my $a = K abc => 0x123;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    $a->out;
    PrintOutNL;

    $a->outInDec; PrintOutNL; $a->outInDecNL;
    $a->outRightInBin(16); PrintOutNL; $a->outRightInBinNL(16);
    $a->outRightInDec(16); PrintOutNL; $a->outRightInDecNL;
    $a->outRightInHex(16); PrintOutNL; $a->outRightInHexNL;

    PrintOutString 'a';

    K(key => 2)->outSpaces;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    PrintOutStringNL 'b';

    ok Assemble eq => <<END, avx512=>1;
  abc: .... .... .... .123
  abc: 291
  abc: 291
         100100011
         100100011
               291
               291
               123

  a  b
  END

    my $s = Subroutine
     {my ($p) = @_;
      $$p{v}->copy($$p{v} + $$p{k} + $$p{g} + 1);
     } name => 'add', parameters=>[qw(v k g)];

    my $v = V(v => 1);

    my $k = K(k => 2);  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    my $g = V(g => 3);
    $s->call(parameters=>{v=>$v, k=>$k, g=>$g});
    $v->outNL;

    ok Assemble eq => <<END, avx512=>0;
  v: .... .... .... ...7
  END

    my $g = V g => 0;
    my $s = Subroutine
     {my ($p) = @_;

      $$p{g}->copy(K value => 1);  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

     } name => 'ref2', parameters=>[qw(g)];

    my $t = Subroutine
     {my ($p) = @_;
      $s->call(parameters=>{g=>$$p{g}});
     } name => 'ref', parameters=>[qw(g)];

    $t->call(parameters=>{g=>$g});
    $g->outNL;

    ok Assemble eq => <<END, avx512=>0;
  g: .... .... .... ...1
  END

    PrintCString  ($stdout, V(str => Rs("abc\0def")));
    PrintCStringNL($stdout, V(str => Rs("ABC\0DEF")));
    ok Assemble eq => <<END;
  abcABC
  END

    my $a = V(a => 3);  $a->outNL;

    my $b = K(b => 2);  $b->outNL;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    my $c = $a +  $b; $c->outNL;
    my $d = $c -  $a; $d->outNL;
    my $g = $a *  $b; $g->outNL;
    my $h = $g /  $b; $h->outNL;
    my $i = $a %  $b; $i->outNL;

    If ($a == 3,
    Then
     {PrintOutStringNL "a == 3"
     },
    Else
     {PrintOutStringNL "a != 3"
     });

    ++$a; $a->outNL;
    --$a; $a->outNL;

    ok Assemble eq => <<END, avx512=>0;
  a: .... .... .... ...3
  b: .... .... .... ...2
  (a add b): .... .... .... ...5
  ((a add b) sub a): .... .... .... ...2
  (a times b): .... .... .... ...6
  ((a times b) / b): .... .... .... ...3
  (a % b): .... .... .... ...1
  a == 3
  a: .... .... .... ...4
  a: .... .... .... ...3
  END

V($name, $expr)

Define a variable.

     Parameter  Description
  1  $name      Name of variable
  2  $expr      Initializing expression

Example:

    my $a = K abc => 0x123;
    $a->out;
    PrintOutNL;

    $a->outInDec; PrintOutNL; $a->outInDecNL;
    $a->outRightInBin(16); PrintOutNL; $a->outRightInBinNL(16);
    $a->outRightInDec(16); PrintOutNL; $a->outRightInDecNL;
    $a->outRightInHex(16); PrintOutNL; $a->outRightInHexNL;

    PrintOutString 'a';
    K(key => 2)->outSpaces;
    PrintOutStringNL 'b';

    ok Assemble eq => <<END, avx512=>1;
  abc: .... .... .... .123
  abc: 291
  abc: 291
         100100011
         100100011
               291
               291
               123

  a  b
  END

    my $s = Subroutine
     {my ($p) = @_;
      $$p{v}->copy($$p{v} + $$p{k} + $$p{g} + 1);
     } name => 'add', parameters=>[qw(v k g)];


    my $v = V(v => 1);  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    my $k = K(k => 2);

    my $g = V(g => 3);  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    $s->call(parameters=>{v=>$v, k=>$k, g=>$g});
    $v->outNL;

    ok Assemble eq => <<END, avx512=>0;
  v: .... .... .... ...7
  END


    my $g = V g => 0;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    my $s = Subroutine
     {my ($p) = @_;
      $$p{g}->copy(K value => 1);
     } name => 'ref2', parameters=>[qw(g)];

    my $t = Subroutine
     {my ($p) = @_;
      $s->call(parameters=>{g=>$$p{g}});
     } name => 'ref', parameters=>[qw(g)];

    $t->call(parameters=>{g=>$g});
    $g->outNL;

    ok Assemble eq => <<END, avx512=>0;
  g: .... .... .... ...1
  END


    PrintCString  ($stdout, V(str => Rs("abc\0def")));  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲


    PrintCStringNL($stdout, V(str => Rs("ABC\0DEF")));  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    ok Assemble eq => <<END;
  abcABC
  END


    my $a = V(a => 3);  $a->outNL;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    my $b = K(b => 2);  $b->outNL;
    my $c = $a +  $b; $c->outNL;
    my $d = $c -  $a; $d->outNL;
    my $g = $a *  $b; $g->outNL;
    my $h = $g /  $b; $h->outNL;
    my $i = $a %  $b; $i->outNL;

    If ($a == 3,
    Then
     {PrintOutStringNL "a == 3"
     },
    Else
     {PrintOutStringNL "a != 3"
     });

    ++$a; $a->outNL;
    --$a; $a->outNL;

    ok Assemble eq => <<END, avx512=>0;
  a: .... .... .... ...3
  b: .... .... .... ...2
  (a add b): .... .... .... ...5
  ((a add b) sub a): .... .... .... ...2
  (a times b): .... .... .... ...6
  ((a times b) / b): .... .... .... ...3
  (a % b): .... .... .... ...1
  a == 3
  a: .... .... .... ...4
  a: .... .... .... ...3
  END

Print the values of variables or the memory addressed by them

Nasm::X86::Variable::out($left, $title1, $title2)

Dump the value of a variable on stdout.

     Parameter  Description
  1  $left      Left variable
  2  $title1    Optional leading title
  3  $title2    Optional trailing title

Example:

    my $a = V(a => 1);
    my $b = V(b => 2);
    my $c = $a + $b;
    Mov r15, 22;
    $a->getReg(r15);
    $b->copy($a);
    $b = $b + 1;
    $b->setReg(14);
    $a->outNL;
    $b->outNL;
    $c->out;
    PrintOutNL;
    PrintOutRegisterInHex r14, r15;

    ok Assemble eq => <<END, avx512=>0;
  a: .... .... .... ..16
  (b add 1): .... .... .... ..17
  (a add b): .... .... .... ...3
     r14: .... .... .... ..17
     r15: .... .... .... ..16
  END

    my $a = K abc => 0x123;
    $a->out;
    PrintOutNL;

    $a->outInDec; PrintOutNL; $a->outInDecNL;
    $a->outRightInBin(16); PrintOutNL; $a->outRightInBinNL(16);
    $a->outRightInDec(16); PrintOutNL; $a->outRightInDecNL;
    $a->outRightInHex(16); PrintOutNL; $a->outRightInHexNL;

    PrintOutString 'a';
    K(key => 2)->outSpaces;
    PrintOutStringNL 'b';

    ok Assemble eq => <<END, avx512=>1;
  abc: .... .... .... .123
  abc: 291
  abc: 291
         100100011
         100100011
               291
               291
               123

  a  b
  END

Nasm::X86::Variable::outNL($left, $title1, $title2)

Dump the value of a variable on stdout and append a new line.

     Parameter  Description
  1  $left      Left variable
  2  $title1    Optional leading title
  3  $title2    Optional trailing title

Example:

    my $a = V a => 0x1111;
    $a->outNL('');
    $a->outRightInBinNL;
    $a->outRightInDecNL;
    $a->outRightInHexNL;
    ok Assemble eq => <<END;
  .... .... .... 1111
     1000100010001
              4369

  END

    my $a = V(a => 1);
    my $b = V(b => 2);
    my $c = $a + $b;
    Mov r15, 22;
    $a->getReg(r15);
    $b->copy($a);
    $b = $b + 1;
    $b->setReg(14);
    $a->outNL;
    $b->outNL;
    $c->out;
    PrintOutNL;
    PrintOutRegisterInHex r14, r15;

    ok Assemble eq => <<END, avx512=>0;
  a: .... .... .... ..16
  (b add 1): .... .... .... ..17
  (a add b): .... .... .... ...3
     r14: .... .... .... ..17
     r15: .... .... .... ..16
  END

Decimal representation

Print out a variable as a decimal number

Nasm::X86::Variable::outInDec($number, $title1, $title2)

Dump the value of a variable on stdout in decimal.

     Parameter  Description
  1  $number    Number as variable
  2  $title1    Optional leading title
  3  $title2    Optional trailing title

Example:

    my $a = K abc => 0x123;
    $a->out;
    PrintOutNL;

    $a->outInDec; PrintOutNL; $a->outInDecNL;
    $a->outRightInBin(16); PrintOutNL; $a->outRightInBinNL(16);
    $a->outRightInDec(16); PrintOutNL; $a->outRightInDecNL;
    $a->outRightInHex(16); PrintOutNL; $a->outRightInHexNL;

    PrintOutString 'a';
    K(key => 2)->outSpaces;
    PrintOutStringNL 'b';

    ok Assemble eq => <<END, avx512=>1;
  abc: .... .... .... .123
  abc: 291
  abc: 291
         100100011
         100100011
               291
               291
               123

  a  b
  END

Nasm::X86::Variable::outInDecNL($number, $title1, $title2)

Dump the value of a variable on stdout in decimal followed by a new line.

     Parameter  Description
  1  $number    Number as variable
  2  $title1    Optional leading title
  3  $title2    Optional trailing title

Example:

    my $a = K abc => 0x123;
    $a->out;
    PrintOutNL;

    $a->outInDec; PrintOutNL; $a->outInDecNL;
    $a->outRightInBin(16); PrintOutNL; $a->outRightInBinNL(16);
    $a->outRightInDec(16); PrintOutNL; $a->outRightInDecNL;
    $a->outRightInHex(16); PrintOutNL; $a->outRightInHexNL;

    PrintOutString 'a';
    K(key => 2)->outSpaces;
    PrintOutStringNL 'b';

    ok Assemble eq => <<END, avx512=>1;
  abc: .... .... .... .123
  abc: 291
  abc: 291
         100100011
         100100011
               291
               291
               123

  a  b
  END

    my $e = q(parameters);

    (V string => "[rbp+8]")->outInDecNL;
    (V string => "[rbp+16]")->outCStringNL;
    (V string => "[rbp+24]")->outCStringNL;
    (V string => "[rbp+32]")->outCStringNL;
    (V string => "[rbp+40]")->outCStringNL;
    (V string => "[rbp+48]")->outInDecNL;

    (V string => "[rbp+8]")->for(sub
     {my ($index, $start, $next, $end) = @_;
      $index->setReg(rax);
      Inc rax;
      PrintOutRaxInDec;
      Inc rax;
      PrintOutString " : ";
      Shl rax, 3;
      (V string => "[rbp+rax]")->outCStringNL;
     });

    Assemble keep => $e;

    is_deeply scalar(qx(./$e AaAaAaAaAa BbCcDdEe 123456789)), <<END;
  string: 4
  ./parameters
  AaAaAaAaAa
  BbCcDdEe
  123456789
  string: 0
  1 : ./parameters
  2 : AaAaAaAaAa
  3 : BbCcDdEe
  4 : 123456789
  END

    unlink $e;

Decimal representation right justified

Print out a variable as a decimal number right adjusted in a field of specified width

Nasm::X86::Variable::outRightInDec($number, $width)

Dump the value of a variable on stdout as a decimal number right adjusted in a field of specified width.

     Parameter  Description
  1  $number    Number
  2  $width     Width

Example:

    my $a = K abc => 0x123;
    $a->out;
    PrintOutNL;

    $a->outInDec; PrintOutNL; $a->outInDecNL;
    $a->outRightInBin(16); PrintOutNL; $a->outRightInBinNL(16);
    $a->outRightInDec(16); PrintOutNL; $a->outRightInDecNL;
    $a->outRightInHex(16); PrintOutNL; $a->outRightInHexNL;

    PrintOutString 'a';
    K(key => 2)->outSpaces;
    PrintOutStringNL 'b';

    ok Assemble eq => <<END, avx512=>1;
  abc: .... .... .... .123
  abc: 291
  abc: 291
         100100011
         100100011
               291
               291
               123

  a  b
  END

Nasm::X86::Variable::outRightInDecNL($number, $width)

Dump the value of a variable on stdout as a decimal number right adjusted in a field of specified width followed by a new line.

     Parameter  Description
  1  $number    Number
  2  $width     Width

Example:

    my $a = K abc => 0x123;
    $a->out;
    PrintOutNL;

    $a->outInDec; PrintOutNL; $a->outInDecNL;
    $a->outRightInBin(16); PrintOutNL; $a->outRightInBinNL(16);
    $a->outRightInDec(16); PrintOutNL; $a->outRightInDecNL;
    $a->outRightInHex(16); PrintOutNL; $a->outRightInHexNL;

    PrintOutString 'a';
    K(key => 2)->outSpaces;
    PrintOutStringNL 'b';

    ok Assemble eq => <<END, avx512=>1;
  abc: .... .... .... .123
  abc: 291
  abc: 291
         100100011
         100100011
               291
               291
               123

  a  b
  END

Hexadecimal representation, right justified

Print number variables in hexadecimal right justified in fields of specified width.

Nasm::X86::Variable::outRightInHex($number, $width)

Write the specified variable number in hexadecimal right justified in a field of specified width to stdout.

     Parameter  Description
  1  $number    Number to print as a variable
  2  $width     Width of output field

Example:

    my $a = K abc => 0x123;
    $a->out;
    PrintOutNL;

    $a->outInDec; PrintOutNL; $a->outInDecNL;
    $a->outRightInBin(16); PrintOutNL; $a->outRightInBinNL(16);
    $a->outRightInDec(16); PrintOutNL; $a->outRightInDecNL;
    $a->outRightInHex(16); PrintOutNL; $a->outRightInHexNL;

    PrintOutString 'a';
    K(key => 2)->outSpaces;
    PrintOutStringNL 'b';

    ok Assemble eq => <<END, avx512=>1;
  abc: .... .... .... .123
  abc: 291
  abc: 291
         100100011
         100100011
               291
               291
               123

  a  b
  END

Nasm::X86::Variable::outRightInHexNL($number, $width)

Write the specified variable number in hexadecimal right justified in a field of specified width to stdout followed by a new line.

     Parameter  Description
  1  $number    Number to print as a variable
  2  $width     Width of output field

Example:

    my $a = K abc => 0x123;
    $a->out;
    PrintOutNL;

    $a->outInDec; PrintOutNL; $a->outInDecNL;
    $a->outRightInBin(16); PrintOutNL; $a->outRightInBinNL(16);
    $a->outRightInDec(16); PrintOutNL; $a->outRightInDecNL;
    $a->outRightInHex(16); PrintOutNL; $a->outRightInHexNL;

    PrintOutString 'a';
    K(key => 2)->outSpaces;
    PrintOutStringNL 'b';

    ok Assemble eq => <<END, avx512=>1;
  abc: .... .... .... .123
  abc: 291
  abc: 291
         100100011
         100100011
               291
               291
               123

  a  b
  END

Binary representation, right justified

Print number variables in binary right justified in fields of specified width.

Nasm::X86::Variable::outRightInBin($number, $width)

Write the specified variable number in binary right justified in a field of specified width to stdout.

     Parameter  Description
  1  $number    Number to print as a variable
  2  $width     Width of output field

Example:

    my $a = K abc => 0x123;
    $a->out;
    PrintOutNL;

    $a->outInDec; PrintOutNL; $a->outInDecNL;
    $a->outRightInBin(16); PrintOutNL; $a->outRightInBinNL(16);
    $a->outRightInDec(16); PrintOutNL; $a->outRightInDecNL;
    $a->outRightInHex(16); PrintOutNL; $a->outRightInHexNL;

    PrintOutString 'a';
    K(key => 2)->outSpaces;
    PrintOutStringNL 'b';

    ok Assemble eq => <<END, avx512=>1;
  abc: .... .... .... .123
  abc: 291
  abc: 291
         100100011
         100100011
               291
               291
               123

  a  b
  END

Nasm::X86::Variable::outRightInBinNL($number, $width)

Write the specified variable number in binary right justified in a field of specified width to stdout followed by a new line.

     Parameter  Description
  1  $number    Number to print as a variable
  2  $width     Width of output field

Example:

    my $a = K abc => 0x123;
    $a->out;
    PrintOutNL;

    $a->outInDec; PrintOutNL; $a->outInDecNL;
    $a->outRightInBin(16); PrintOutNL; $a->outRightInBinNL(16);
    $a->outRightInDec(16); PrintOutNL; $a->outRightInDecNL;
    $a->outRightInHex(16); PrintOutNL; $a->outRightInHexNL;

    PrintOutString 'a';
    K(key => 2)->outSpaces;
    PrintOutStringNL 'b';

    ok Assemble eq => <<END, avx512=>1;
  abc: .... .... .... .123
  abc: 291
  abc: 291
         100100011
         100100011
               291
               291
               123

  a  b
  END

Spaces

Print out a variable number of spaces.

Nasm::X86::Variable::spaces($count, $channel)

Print the specified number of spaces to the specified channel.

     Parameter  Description
  1  $count     Number of spaces
  2  $channel   Channel

Example:

  if (1)
   {my $a = V(key => 0x123);
    is_deeply $a->at,           "[rbp-8*(2)]";
    is_deeply $a->addressExpr, "[rbp-8*(2)]";

    ok !$a->isRef;

    Mov rax, -1;
    Kmovq k1, rax;
    PrintOutRegisterInHex k1;

    K(key => 2)->clearBit(rax);
    PrintOutRegisterInHex rax;

    K(key => 2)->setBit(rax);
    PrintOutRegisterInHex rax;

    K(key => 3)->clearMaskBit(k1);
    PrintOutRegisterInHex k1;

    K(key => 3)->setMaskBit(k1);
    PrintOutRegisterInHex k1;

    K(key => 0)->clearMaskBit(k1);
    PrintOutRegisterInHex k1;

    ClearRegisters k1;
    K(key => 7)->setMaskFirst(k1);
    PrintOutRegisterInHex k1;

    K(key => 3)->spaces($stdout);
    PrintOutRegisterInHex k1;

    my $N = K size => 4096;
    my $A = $N->allocateMemory;
    $A->clearMemory($N);
    ClearMemory($A, $N);

    $A->setReg(rax);
    Mov "dword[rax]",   0x61626364;
    Mov "dword[rax+4]", 0x65666768;

    ($A+8)->copyMemory($A, K key => 8);

    $A->printOutMemory  (K(key => 16));
    $A->printOutMemoryNL(K(key => 16));

    K(K => Rd(0..63))->loadZmm(1);
    PrintOutRegisterInHex zmm1;

    ok Assemble eq => <<END;
      k1: .... .... .... ..-1
     rax: FFFF FFFF FFFF FFFB
     rax: .... .... .... ..-1
      k1: FFFF FFFF FFFF FFF7
      k1: .... .... .... ..-1
      k1: FFFF FFFF FFFF FFFE
      k1: .... .... .... ..7F
         k1: .... .... .... ..7F
  dcbahgfedcbahgfedcbahgfedcbahgfe
    zmm1: .... ...F .... ...E  .... ...D .... ...C - .... ...B .... ...A  .... ...9 .... ...8 + .... ...7 .... ...6  .... ...5 .... ...4 - .... ...3 .... ...2  .... ...1 .... ....
  END
   }

Nasm::X86::Variable::outSpaces($count)

Print the specified number of spaces to stdout.

     Parameter  Description
  1  $count     Number of spaces

Example:

    my $a = K abc => 0x123;
    $a->out;
    PrintOutNL;

    $a->outInDec; PrintOutNL; $a->outInDecNL;
    $a->outRightInBin(16); PrintOutNL; $a->outRightInBinNL(16);
    $a->outRightInDec(16); PrintOutNL; $a->outRightInDecNL;
    $a->outRightInHex(16); PrintOutNL; $a->outRightInHexNL;

    PrintOutString 'a';
    K(key => 2)->outSpaces;
    PrintOutStringNL 'b';

    ok Assemble eq => <<END, avx512=>1;
  abc: .... .... .... .123
  abc: 291
  abc: 291
         100100011
         100100011
               291
               291
               123

  a  b
  END

C style zero terminated strings

Print out C style zero terminated strings.

Nasm::X86::Variable::outCString($string)

Print a zero terminated C style string addressed by a variable on stdout.

     Parameter  Description
  1  $string    String

Example:

    my $s = Rutf8 '𝝰𝝱𝝲𝝳';
    V(address => $s)->outCString; PrintOutNL;
    V(address => $s)->outCStringNL;

    ok Assemble(debug => 0, trace => 0, eq => <<END, avx512=>0);
  𝝰𝝱𝝲𝝳
  𝝰𝝱𝝲𝝳
  END

Nasm::X86::Variable::outCStringNL($string)

Print a zero terminated C style string addressed by a variable on stdout followed by a new line.

     Parameter  Description
  1  $string    String

Example:

    my $s = Rutf8 '𝝰𝝱𝝲𝝳';
    V(address => $s)->outCString; PrintOutNL;
    V(address => $s)->outCStringNL;

    ok Assemble(debug => 0, trace => 0, eq => <<END, avx512=>0);
  𝝰𝝱𝝲𝝳
  𝝰𝝱𝝲𝝳
  END

    my $e = q(parameters);

    (V string => "[rbp+8]")->outInDecNL;
    (V string => "[rbp+16]")->outCStringNL;
    (V string => "[rbp+24]")->outCStringNL;
    (V string => "[rbp+32]")->outCStringNL;
    (V string => "[rbp+40]")->outCStringNL;
    (V string => "[rbp+48]")->outInDecNL;

    (V string => "[rbp+8]")->for(sub
     {my ($index, $start, $next, $end) = @_;
      $index->setReg(rax);
      Inc rax;
      PrintOutRaxInDec;
      Inc rax;
      PrintOutString " : ";
      Shl rax, 3;
      (V string => "[rbp+rax]")->outCStringNL;
     });

    Assemble keep => $e;

    is_deeply scalar(qx(./$e AaAaAaAaAa BbCcDdEe 123456789)), <<END;
  string: 4
  ./parameters
  AaAaAaAaAa
  BbCcDdEe
  123456789
  string: 0
  1 : ./parameters
  2 : AaAaAaAaAa
  3 : BbCcDdEe
  4 : 123456789
  END

    unlink $e;

Addressing

Create references to variables and dereference variables

Nasm::X86::Variable::address($source)

Create a variable that contains the address of another variable.

     Parameter  Description
  1  $source    Source variable

Example:

            V(a => 2);
            V(a => 1);
    my $a = V(a => 0)->address;
    ($a+ 0)->dereference->outNL;
    ($a+ 8)->dereference->outNL;
    ($a+16)->dereference->outNL;
    ($a+16)->update(K key => 3);
    ($a+16)->dereference->outNL;
    ok Assemble eq => <<END;
  deref (addr a add 0): .... .... .... ...0
  deref (addr a add 8): .... .... .... ...1
  deref (addr a add 16): .... .... .... ...2
  deref (addr a add 16): .... .... .... ...3
  END

Nasm::X86::Variable::dereference($address)

Create a variable that contains the contents of the variable addressed by the specified variable.

     Parameter  Description
  1  $address   Source variable

Example:

            V(a => 2);
            V(a => 1);
    my $a = V(a => 0)->address;
    ($a+ 0)->dereference->outNL;
    ($a+ 8)->dereference->outNL;
    ($a+16)->dereference->outNL;
    ($a+16)->update(K key => 3);
    ($a+16)->dereference->outNL;
    ok Assemble eq => <<END;
  deref (addr a add 0): .... .... .... ...0
  deref (addr a add 8): .... .... .... ...1
  deref (addr a add 16): .... .... .... ...2
  deref (addr a add 16): .... .... .... ...3
  END

Nasm::X86::Variable::update($address, $content)

Update the content of the addressed variable with the content of the specified variable.

     Parameter  Description
  1  $address   Source variable
  2  $content   Content

Example:

            V(a => 2);
            V(a => 1);
    my $a = V(a => 0)->address;
    ($a+ 0)->dereference->outNL;
    ($a+ 8)->dereference->outNL;
    ($a+16)->dereference->outNL;
    ($a+16)->update(K key => 3);
    ($a+16)->dereference->outNL;
    ok Assemble eq => <<END;
  deref (addr a add 0): .... .... .... ...0
  deref (addr a add 8): .... .... .... ...1
  deref (addr a add 16): .... .... .... ...2
  deref (addr a add 16): .... .... .... ...3
  END

constantString($string)

Return the address and length of a constant string as two variables.

     Parameter  Description
  1  $string    Constant utf8 string

Example:

    my ($t, $l) = constantString("Hello World");  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    $t->printOutMemoryNL($l);

    ok Assemble eq => <<END, avx512=>1;
  Hello World
  END

Operations

Variable operations

Nasm::X86::Variable::addressExpr($left, $offset)

Create a register expression to address an offset form a variable.

     Parameter  Description
  1  $left      Left variable
  2  $offset    Optional offset

Example:

  if (1)
   {my $a = V(key => 0x123);
    is_deeply $a->at,           "[rbp-8*(2)]";
    is_deeply $a->addressExpr, "[rbp-8*(2)]";

    ok !$a->isRef;

    Mov rax, -1;
    Kmovq k1, rax;
    PrintOutRegisterInHex k1;

    K(key => 2)->clearBit(rax);
    PrintOutRegisterInHex rax;

    K(key => 2)->setBit(rax);
    PrintOutRegisterInHex rax;

    K(key => 3)->clearMaskBit(k1);
    PrintOutRegisterInHex k1;

    K(key => 3)->setMaskBit(k1);
    PrintOutRegisterInHex k1;

    K(key => 0)->clearMaskBit(k1);
    PrintOutRegisterInHex k1;

    ClearRegisters k1;
    K(key => 7)->setMaskFirst(k1);
    PrintOutRegisterInHex k1;

    K(key => 3)->spaces($stdout);
    PrintOutRegisterInHex k1;

    my $N = K size => 4096;
    my $A = $N->allocateMemory;
    $A->clearMemory($N);
    ClearMemory($A, $N);

    $A->setReg(rax);
    Mov "dword[rax]",   0x61626364;
    Mov "dword[rax+4]", 0x65666768;

    ($A+8)->copyMemory($A, K key => 8);

    $A->printOutMemory  (K(key => 16));
    $A->printOutMemoryNL(K(key => 16));

    K(K => Rd(0..63))->loadZmm(1);
    PrintOutRegisterInHex zmm1;

    ok Assemble eq => <<END;
      k1: .... .... .... ..-1
     rax: FFFF FFFF FFFF FFFB
     rax: .... .... .... ..-1
      k1: FFFF FFFF FFFF FFF7
      k1: .... .... .... ..-1
      k1: FFFF FFFF FFFF FFFE
      k1: .... .... .... ..7F
         k1: .... .... .... ..7F
  dcbahgfedcbahgfedcbahgfedcbahgfe
    zmm1: .... ...F .... ...E  .... ...D .... ...C - .... ...B .... ...A  .... ...9 .... ...8 + .... ...7 .... ...6  .... ...5 .... ...4 - .... ...3 .... ...2  .... ...1 .... ....
  END
   }

Nasm::X86::Variable::clone($variable, $name)

Clone a variable to make a new variable.

     Parameter  Description
  1  $variable  Variable to clone
  2  $name      New name for variable

Example:

    my $a = V('a', 1);
    my $b = $a->clone('a');

    $_->outNL for $a, $b;

    ok Assemble(debug => 0, trace => 0, eq => <<END, avx512=>0);
  a: .... .... .... ...1
  a: .... .... .... ...1
  END

Nasm::X86::Variable::copy($left, $right)

Copy one variable into another.

     Parameter  Description
  1  $left      Left variable
  2  $right     Right variable

Example:

    my $a = V(a => 1);
    my $b = V(b => 2);
    my $c = $a + $b;
    Mov r15, 22;
    $a->getReg(r15);
    $b->copy($a);
    $b = $b + 1;
    $b->setReg(14);
    $a->outNL;
    $b->outNL;
    $c->out;
    PrintOutNL;
    PrintOutRegisterInHex r14, r15;

    ok Assemble eq => <<END, avx512=>0;
  a: .... .... .... ..16
  (b add 1): .... .... .... ..17
  (a add b): .... .... .... ...3
     r14: .... .... .... ..17
     r15: .... .... .... ..16
  END

    my $a = K abc => 0x123;
    $a->out;
    PrintOutNL;

    $a->outInDec; PrintOutNL; $a->outInDecNL;
    $a->outRightInBin(16); PrintOutNL; $a->outRightInBinNL(16);
    $a->outRightInDec(16); PrintOutNL; $a->outRightInDecNL;
    $a->outRightInHex(16); PrintOutNL; $a->outRightInHexNL;

    PrintOutString 'a';
    K(key => 2)->outSpaces;
    PrintOutStringNL 'b';

    ok Assemble eq => <<END, avx512=>1;
  abc: .... .... .... .123
  abc: 291
  abc: 291
         100100011
         100100011
               291
               291
               123

  a  b
  END

    my $s = Subroutine
     {my ($p) = @_;
      $$p{v}->copy($$p{v} + $$p{k} + $$p{g} + 1);
     } name => 'add', parameters=>[qw(v k g)];

    my $v = V(v => 1);
    my $k = K(k => 2);
    my $g = V(g => 3);
    $s->call(parameters=>{v=>$v, k=>$k, g=>$g});
    $v->outNL;

    ok Assemble eq => <<END, avx512=>0;
  v: .... .... .... ...7
  END

    my $g = V g => 0;
    my $s = Subroutine
     {my ($p) = @_;
      $$p{g}->copy(K value => 1);
     } name => 'ref2', parameters=>[qw(g)];

    my $t = Subroutine
     {my ($p) = @_;
      $s->call(parameters=>{g=>$$p{g}});
     } name => 'ref', parameters=>[qw(g)];

    $t->call(parameters=>{g=>$g});
    $g->outNL;

    ok Assemble eq => <<END, avx512=>0;
  g: .... .... .... ...1
  END

    my $a = V('a', 1);
    my $r = R('r')->copyRef($a);
    my $R = R('R')->copyRef($r);

    $a->outNL;
    $r->outNL;
    $R->outNL;

    $a->copy(2);

    $a->outNL;
    $r->outNL;
    $R->outNL;

    $r->copy(3);

    $a->outNL;
    $r->outNL;
    $R->outNL;

    $R->copy(4);

    $a->outNL;
    $r->outNL;
    $R->outNL;

    ok Assemble(debug => 0, trace => 0, eq => <<END, avx512=>0);
  a: .... .... .... ...1
  r: .... .... .... ...1
  R: .... .... .... ...1
  a: .... .... .... ...2
  r: .... .... .... ...2
  R: .... .... .... ...2
  a: .... .... .... ...3
  r: .... .... .... ...3
  R: .... .... .... ...3
  a: .... .... .... ...4
  r: .... .... .... ...4
  R: .... .... .... ...4
  END

Nasm::X86::Variable::copyRef($left, $right)

Copy a reference to a variable.

     Parameter  Description
  1  $left      Left variable
  2  $right     Right variable

Example:

    my $a = V('a', 1);
    my $r = R('r')->copyRef($a);
    my $R = R('R')->copyRef($r);

    $a->outNL;
    $r->outNL;
    $R->outNL;

    $a->copy(2);

    $a->outNL;
    $r->outNL;
    $R->outNL;

    $r->copy(3);

    $a->outNL;
    $r->outNL;
    $R->outNL;

    $R->copy(4);

    $a->outNL;
    $r->outNL;
    $R->outNL;

    ok Assemble(debug => 0, trace => 0, eq => <<END, avx512=>0);
  a: .... .... .... ...1
  r: .... .... .... ...1
  R: .... .... .... ...1
  a: .... .... .... ...2
  r: .... .... .... ...2
  R: .... .... .... ...2
  a: .... .... .... ...3
  r: .... .... .... ...3
  R: .... .... .... ...3
  a: .... .... .... ...4
  r: .... .... .... ...4
  R: .... .... .... ...4
  END

Nasm::X86::Variable::copyZF($var)

Copy the current state of the zero flag into a variable.

     Parameter  Description
  1  $var       Variable

Example:

    Mov r15, 1;
    my $z = V(zf => undef);
    Cmp r15, 1; $z->copyZF;         $z->outNL;
    Cmp r15, 2; $z->copyZF;         $z->outNL;
    Cmp r15, 1; $z->copyZFInverted; $z->outNL;
    Cmp r15, 2; $z->copyZFInverted; $z->outNL;

    ok Assemble eq => <<END, avx512=>0;
  zf: .... .... .... ...1
  zf: .... .... .... ...0
  zf: .... .... .... ...0
  zf: .... .... .... ...1
  END

Nasm::X86::Variable::copyZFInverted($var)

Copy the opposite of the current state of the zero flag into a variable.

     Parameter  Description
  1  $var       Variable

Example:

    Mov r15, 1;
    my $z = V(zf => undef);
    Cmp r15, 1; $z->copyZF;         $z->outNL;
    Cmp r15, 2; $z->copyZF;         $z->outNL;
    Cmp r15, 1; $z->copyZFInverted; $z->outNL;
    Cmp r15, 2; $z->copyZFInverted; $z->outNL;

    ok Assemble eq => <<END, avx512=>0;
  zf: .... .... .... ...1
  zf: .... .... .... ...0
  zf: .... .... .... ...0
  zf: .... .... .... ...1
  END

Nasm::X86::Variable::isRef($variable)

Check whether the specified variable is a reference to another variable.

     Parameter  Description
  1  $variable  Variable

Example:

  if (1)
   {my $a = V(key => 0x123);
    is_deeply $a->at,           "[rbp-8*(2)]";
    is_deeply $a->addressExpr, "[rbp-8*(2)]";

    ok !$a->isRef;

    Mov rax, -1;
    Kmovq k1, rax;
    PrintOutRegisterInHex k1;

    K(key => 2)->clearBit(rax);
    PrintOutRegisterInHex rax;

    K(key => 2)->setBit(rax);
    PrintOutRegisterInHex rax;

    K(key => 3)->clearMaskBit(k1);
    PrintOutRegisterInHex k1;

    K(key => 3)->setMaskBit(k1);
    PrintOutRegisterInHex k1;

    K(key => 0)->clearMaskBit(k1);
    PrintOutRegisterInHex k1;

    ClearRegisters k1;
    K(key => 7)->setMaskFirst(k1);
    PrintOutRegisterInHex k1;

    K(key => 3)->spaces($stdout);
    PrintOutRegisterInHex k1;

    my $N = K size => 4096;
    my $A = $N->allocateMemory;
    $A->clearMemory($N);
    ClearMemory($A, $N);

    $A->setReg(rax);
    Mov "dword[rax]",   0x61626364;
    Mov "dword[rax+4]", 0x65666768;

    ($A+8)->copyMemory($A, K key => 8);

    $A->printOutMemory  (K(key => 16));
    $A->printOutMemoryNL(K(key => 16));

    K(K => Rd(0..63))->loadZmm(1);
    PrintOutRegisterInHex zmm1;

    ok Assemble eq => <<END;
      k1: .... .... .... ..-1
     rax: FFFF FFFF FFFF FFFB
     rax: .... .... .... ..-1
      k1: FFFF FFFF FFFF FFF7
      k1: .... .... .... ..-1
      k1: FFFF FFFF FFFF FFFE
      k1: .... .... .... ..7F
         k1: .... .... .... ..7F
  dcbahgfedcbahgfedcbahgfedcbahgfe
    zmm1: .... ...F .... ...E  .... ...D .... ...C - .... ...B .... ...A  .... ...9 .... ...8 + .... ...7 .... ...6  .... ...5 .... ...4 - .... ...3 .... ...2  .... ...1 .... ....
  END
   }

Nasm::X86::Variable::setReg($variable, $register)

Set the named registers from the content of the variable.

     Parameter  Description
  1  $variable  Variable
  2  $register  Register to load

Example:

    my $a = V(a => 1);
    my $b = V(b => 2);
    my $c = $a + $b;
    Mov r15, 22;
    $a->getReg(r15);
    $b->copy($a);
    $b = $b + 1;
    $b->setReg(14);
    $a->outNL;
    $b->outNL;
    $c->out;
    PrintOutNL;
    PrintOutRegisterInHex r14, r15;

    ok Assemble eq => <<END, avx512=>0;
  a: .... .... .... ..16
  (b add 1): .... .... .... ..17
  (a add b): .... .... .... ...3
     r14: .... .... .... ..17
     r15: .... .... .... ..16
  END

Nasm::X86::Variable::getReg($variable, $register)

Load the variable from a register expression.

     Parameter  Description
  1  $variable  Variable
  2  $register  Register expression to load

Example:

    my $a = V(a => 1);
    my $b = V(b => 2);
    my $c = $a + $b;
    Mov r15, 22;
    $a->getReg(r15);
    $b->copy($a);
    $b = $b + 1;
    $b->setReg(14);
    $a->outNL;
    $b->outNL;
    $c->out;
    PrintOutNL;
    PrintOutRegisterInHex r14, r15;

    ok Assemble eq => <<END, avx512=>0;
  a: .... .... .... ..16
  (b add 1): .... .... .... ..17
  (a add b): .... .... .... ...3
     r14: .... .... .... ..17
     r15: .... .... .... ..16
  END

Nasm::X86::Variable::min($left, $right)

Minimum of two variables.

     Parameter  Description
  1  $left      Left variable
  2  $right     Right variable or constant

Example:

    my $a = V("a", 1);
    my $b = V("b", 2);
    my $c = $a->min($b);
    my $d = $a->max($b);
    $a->outNL;
    $b->outNL;
    $c->outNL;
    $d->outNL;

    ok Assemble(debug => 0, eq => <<END, avx512=>0);
  a: .... .... .... ...1
  b: .... .... .... ...2
  min: .... .... .... ...1
  max: .... .... .... ...2
  END

Nasm::X86::Variable::max($left, $right)

Maximum of two variables.

     Parameter  Description
  1  $left      Left variable
  2  $right     Right variable or constant

Example:

    my $a = V("a", 1);
    my $b = V("b", 2);
    my $c = $a->min($b);
    my $d = $a->max($b);
    $a->outNL;
    $b->outNL;
    $c->outNL;
    $d->outNL;

    ok Assemble(debug => 0, eq => <<END, avx512=>0);
  a: .... .... .... ...1
  b: .... .... .... ...2
  min: .... .... .... ...1
  max: .... .... .... ...2
  END

Nasm::X86::Variable::setMask($start, $length, $mask)

Set the mask register to ones starting at the specified position for the specified length and zeroes elsewhere.

     Parameter  Description
  1  $start     Variable containing start of mask
  2  $length    Variable containing length of mask
  3  $mask      Mask register

Example:

    my $start  = V("Start",  7);
    my $length = V("Length", 3);
    $start->setMask($length, k7);
    PrintOutRegisterInHex k7;

    ok Assemble(debug => 0, eq => <<END, avx512=>1);
      k7: .... .... .... .380
  END

    my $z = V('zero', 0);
    my $o = V('one',  1);
    my $t = V('two',  2);
    $z->setMask($o,       k7); PrintOutRegisterInHex k7;
    $z->setMask($t,       k6); PrintOutRegisterInHex k6;
    $z->setMask($o+$t,    k5); PrintOutRegisterInHex k5;
    $o->setMask($o,       k4); PrintOutRegisterInHex k4;
    $o->setMask($t,       k3); PrintOutRegisterInHex k3;
    $o->setMask($o+$t,    k2); PrintOutRegisterInHex k2;

    $t->setMask($o,       k1); PrintOutRegisterInHex k1;
    $t->setMask($t,       k0); PrintOutRegisterInHex k0;

    ok Assemble(debug => 0, eq => <<END, avx512=>1);
      k7: .... .... .... ...1
      k6: .... .... .... ...3
      k5: .... .... .... ...7
      k4: .... .... .... ...2
      k3: .... .... .... ...6
      k2: .... .... .... ...E
      k1: .... .... .... ...4
      k0: .... .... .... ...C
  END

Nasm::X86::Variable::setMaskFirst($length, $mask)

Set the first bits in the specified mask register.

     Parameter  Description
  1  $length    Variable containing length to set
  2  $mask      Mask register

Example:

  if (1)
   {my $a = V(key => 0x123);
    is_deeply $a->at,           "[rbp-8*(2)]";
    is_deeply $a->addressExpr, "[rbp-8*(2)]";

    ok !$a->isRef;

    Mov rax, -1;
    Kmovq k1, rax;
    PrintOutRegisterInHex k1;

    K(key => 2)->clearBit(rax);
    PrintOutRegisterInHex rax;

    K(key => 2)->setBit(rax);
    PrintOutRegisterInHex rax;

    K(key => 3)->clearMaskBit(k1);
    PrintOutRegisterInHex k1;

    K(key => 3)->setMaskBit(k1);
    PrintOutRegisterInHex k1;

    K(key => 0)->clearMaskBit(k1);
    PrintOutRegisterInHex k1;

    ClearRegisters k1;
    K(key => 7)->setMaskFirst(k1);
    PrintOutRegisterInHex k1;

    K(key => 3)->spaces($stdout);
    PrintOutRegisterInHex k1;

    my $N = K size => 4096;
    my $A = $N->allocateMemory;
    $A->clearMemory($N);
    ClearMemory($A, $N);

    $A->setReg(rax);
    Mov "dword[rax]",   0x61626364;
    Mov "dword[rax+4]", 0x65666768;

    ($A+8)->copyMemory($A, K key => 8);

    $A->printOutMemory  (K(key => 16));
    $A->printOutMemoryNL(K(key => 16));

    K(K => Rd(0..63))->loadZmm(1);
    PrintOutRegisterInHex zmm1;

    ok Assemble eq => <<END;
      k1: .... .... .... ..-1
     rax: FFFF FFFF FFFF FFFB
     rax: .... .... .... ..-1
      k1: FFFF FFFF FFFF FFF7
      k1: .... .... .... ..-1
      k1: FFFF FFFF FFFF FFFE
      k1: .... .... .... ..7F
         k1: .... .... .... ..7F
  dcbahgfedcbahgfedcbahgfedcbahgfe
    zmm1: .... ...F .... ...E  .... ...D .... ...C - .... ...B .... ...A  .... ...9 .... ...8 + .... ...7 .... ...6  .... ...5 .... ...4 - .... ...3 .... ...2  .... ...1 .... ....
  END
   }

Nasm::X86::Variable::setMaskBit($index, $mask)

Set a bit in the specified mask register retaining the other bits.

     Parameter  Description
  1  $index     Variable containing bit position to set
  2  $mask      Mask register

Example:

  if (1)
   {my $a = V(key => 0x123);
    is_deeply $a->at,           "[rbp-8*(2)]";
    is_deeply $a->addressExpr, "[rbp-8*(2)]";

    ok !$a->isRef;

    Mov rax, -1;
    Kmovq k1, rax;
    PrintOutRegisterInHex k1;

    K(key => 2)->clearBit(rax);
    PrintOutRegisterInHex rax;

    K(key => 2)->setBit(rax);
    PrintOutRegisterInHex rax;

    K(key => 3)->clearMaskBit(k1);
    PrintOutRegisterInHex k1;

    K(key => 3)->setMaskBit(k1);
    PrintOutRegisterInHex k1;

    K(key => 0)->clearMaskBit(k1);
    PrintOutRegisterInHex k1;

    ClearRegisters k1;
    K(key => 7)->setMaskFirst(k1);
    PrintOutRegisterInHex k1;

    K(key => 3)->spaces($stdout);
    PrintOutRegisterInHex k1;

    my $N = K size => 4096;
    my $A = $N->allocateMemory;
    $A->clearMemory($N);
    ClearMemory($A, $N);

    $A->setReg(rax);
    Mov "dword[rax]",   0x61626364;
    Mov "dword[rax+4]", 0x65666768;

    ($A+8)->copyMemory($A, K key => 8);

    $A->printOutMemory  (K(key => 16));
    $A->printOutMemoryNL(K(key => 16));

    K(K => Rd(0..63))->loadZmm(1);
    PrintOutRegisterInHex zmm1;

    ok Assemble eq => <<END;
      k1: .... .... .... ..-1
     rax: FFFF FFFF FFFF FFFB
     rax: .... .... .... ..-1
      k1: FFFF FFFF FFFF FFF7
      k1: .... .... .... ..-1
      k1: FFFF FFFF FFFF FFFE
      k1: .... .... .... ..7F
         k1: .... .... .... ..7F
  dcbahgfedcbahgfedcbahgfedcbahgfe
    zmm1: .... ...F .... ...E  .... ...D .... ...C - .... ...B .... ...A  .... ...9 .... ...8 + .... ...7 .... ...6  .... ...5 .... ...4 - .... ...3 .... ...2  .... ...1 .... ....
  END
   }

Nasm::X86::Variable::clearMaskBit($index, $mask)

Clear a bit in the specified mask register retaining the other bits.

     Parameter  Description
  1  $index     Variable containing bit position to clear
  2  $mask      Mask register

Example:

  if (1)
   {my $a = V(key => 0x123);
    is_deeply $a->at,           "[rbp-8*(2)]";
    is_deeply $a->addressExpr, "[rbp-8*(2)]";

    ok !$a->isRef;

    Mov rax, -1;
    Kmovq k1, rax;
    PrintOutRegisterInHex k1;

    K(key => 2)->clearBit(rax);
    PrintOutRegisterInHex rax;

    K(key => 2)->setBit(rax);
    PrintOutRegisterInHex rax;

    K(key => 3)->clearMaskBit(k1);
    PrintOutRegisterInHex k1;

    K(key => 3)->setMaskBit(k1);
    PrintOutRegisterInHex k1;

    K(key => 0)->clearMaskBit(k1);
    PrintOutRegisterInHex k1;

    ClearRegisters k1;
    K(key => 7)->setMaskFirst(k1);
    PrintOutRegisterInHex k1;

    K(key => 3)->spaces($stdout);
    PrintOutRegisterInHex k1;

    my $N = K size => 4096;
    my $A = $N->allocateMemory;
    $A->clearMemory($N);
    ClearMemory($A, $N);

    $A->setReg(rax);
    Mov "dword[rax]",   0x61626364;
    Mov "dword[rax+4]", 0x65666768;

    ($A+8)->copyMemory($A, K key => 8);

    $A->printOutMemory  (K(key => 16));
    $A->printOutMemoryNL(K(key => 16));

    K(K => Rd(0..63))->loadZmm(1);
    PrintOutRegisterInHex zmm1;

    ok Assemble eq => <<END;
      k1: .... .... .... ..-1
     rax: FFFF FFFF FFFF FFFB
     rax: .... .... .... ..-1
      k1: FFFF FFFF FFFF FFF7
      k1: .... .... .... ..-1
      k1: FFFF FFFF FFFF FFFE
      k1: .... .... .... ..7F
         k1: .... .... .... ..7F
  dcbahgfedcbahgfedcbahgfedcbahgfe
    zmm1: .... ...F .... ...E  .... ...D .... ...C - .... ...B .... ...A  .... ...9 .... ...8 + .... ...7 .... ...6  .... ...5 .... ...4 - .... ...3 .... ...2  .... ...1 .... ....
  END
   }

Nasm::X86::Variable::setBit($index, $mask)

Set a bit in the specified register retaining the other bits.

     Parameter  Description
  1  $index     Variable containing bit position to set
  2  $mask      Mask register

Example:

  if (1)
   {my $a = V(key => 0x123);
    is_deeply $a->at,           "[rbp-8*(2)]";
    is_deeply $a->addressExpr, "[rbp-8*(2)]";

    ok !$a->isRef;

    Mov rax, -1;
    Kmovq k1, rax;
    PrintOutRegisterInHex k1;

    K(key => 2)->clearBit(rax);
    PrintOutRegisterInHex rax;

    K(key => 2)->setBit(rax);
    PrintOutRegisterInHex rax;

    K(key => 3)->clearMaskBit(k1);
    PrintOutRegisterInHex k1;

    K(key => 3)->setMaskBit(k1);
    PrintOutRegisterInHex k1;

    K(key => 0)->clearMaskBit(k1);
    PrintOutRegisterInHex k1;

    ClearRegisters k1;
    K(key => 7)->setMaskFirst(k1);
    PrintOutRegisterInHex k1;

    K(key => 3)->spaces($stdout);
    PrintOutRegisterInHex k1;

    my $N = K size => 4096;
    my $A = $N->allocateMemory;
    $A->clearMemory($N);
    ClearMemory($A, $N);

    $A->setReg(rax);
    Mov "dword[rax]",   0x61626364;
    Mov "dword[rax+4]", 0x65666768;

    ($A+8)->copyMemory($A, K key => 8);

    $A->printOutMemory  (K(key => 16));
    $A->printOutMemoryNL(K(key => 16));

    K(K => Rd(0..63))->loadZmm(1);
    PrintOutRegisterInHex zmm1;

    ok Assemble eq => <<END;
      k1: .... .... .... ..-1
     rax: FFFF FFFF FFFF FFFB
     rax: .... .... .... ..-1
      k1: FFFF FFFF FFFF FFF7
      k1: .... .... .... ..-1
      k1: FFFF FFFF FFFF FFFE
      k1: .... .... .... ..7F
         k1: .... .... .... ..7F
  dcbahgfedcbahgfedcbahgfedcbahgfe
    zmm1: .... ...F .... ...E  .... ...D .... ...C - .... ...B .... ...A  .... ...9 .... ...8 + .... ...7 .... ...6  .... ...5 .... ...4 - .... ...3 .... ...2  .... ...1 .... ....
  END
   }

Nasm::X86::Variable::clearBit($index, $mask)

Clear a bit in the specified mask register retaining the other bits.

     Parameter  Description
  1  $index     Variable containing bit position to clear
  2  $mask      Mask register

Example:

  if (1)
   {my $a = V(key => 0x123);
    is_deeply $a->at,           "[rbp-8*(2)]";
    is_deeply $a->addressExpr, "[rbp-8*(2)]";

    ok !$a->isRef;

    Mov rax, -1;
    Kmovq k1, rax;
    PrintOutRegisterInHex k1;

    K(key => 2)->clearBit(rax);
    PrintOutRegisterInHex rax;

    K(key => 2)->setBit(rax);
    PrintOutRegisterInHex rax;

    K(key => 3)->clearMaskBit(k1);
    PrintOutRegisterInHex k1;

    K(key => 3)->setMaskBit(k1);
    PrintOutRegisterInHex k1;

    K(key => 0)->clearMaskBit(k1);
    PrintOutRegisterInHex k1;

    ClearRegisters k1;
    K(key => 7)->setMaskFirst(k1);
    PrintOutRegisterInHex k1;

    K(key => 3)->spaces($stdout);
    PrintOutRegisterInHex k1;

    my $N = K size => 4096;
    my $A = $N->allocateMemory;
    $A->clearMemory($N);
    ClearMemory($A, $N);

    $A->setReg(rax);
    Mov "dword[rax]",   0x61626364;
    Mov "dword[rax+4]", 0x65666768;

    ($A+8)->copyMemory($A, K key => 8);

    $A->printOutMemory  (K(key => 16));
    $A->printOutMemoryNL(K(key => 16));

    K(K => Rd(0..63))->loadZmm(1);
    PrintOutRegisterInHex zmm1;

    ok Assemble eq => <<END;
      k1: .... .... .... ..-1
     rax: FFFF FFFF FFFF FFFB
     rax: .... .... .... ..-1
      k1: FFFF FFFF FFFF FFF7
      k1: .... .... .... ..-1
      k1: FFFF FFFF FFFF FFFE
      k1: .... .... .... ..7F
         k1: .... .... .... ..7F
  dcbahgfedcbahgfedcbahgfedcbahgfe
    zmm1: .... ...F .... ...E  .... ...D .... ...C - .... ...B .... ...A  .... ...9 .... ...8 + .... ...7 .... ...6  .... ...5 .... ...4 - .... ...3 .... ...2  .... ...1 .... ....
  END
   }

Nasm::X86::Variable::setZmm($source, $zmm, $offset, $length)

Load bytes from the memory addressed by specified source variable into the numbered zmm register at the offset in the specified offset moving the number of bytes in the specified variable.

     Parameter  Description
  1  $source    Variable containing the address of the source
  2  $zmm       Number of zmm to load
  3  $offset    Variable containing offset in zmm to move to
  4  $length    Variable containing length of move

Example:

    my $s = Rb(0..128);
    my $source = V(Source=> $s);

    if (1)                                                                        # First block
     {$source->setZmm(0, K(key => 7), K length => 3);
     }

    if (1)                                                                        # Second block
     {$source->setZmm(0, K(key => 33), K key => 12);
     }

    PrintOutRegisterInHex zmm0;

    ok Assemble(debug => 0, eq => <<END, avx512=>1);
    zmm0: .... .... .... ...0  .... .... .... ...0 - .... ...B .A.9 .8.7  .6.5 .4.3 .2.1 .... + .... .... .... ...0  .... .... .... ...0 - .... .... .... .2.1  .... .... .... ...0
  END

Load mm registers

Load zmm registers fom variables and retrieve data from zmm registers into variables.

Nasm::X86::Variable::loadZmm($source, $zmm)

Load bytes from the memory addressed by the specified source variable into the numbered zmm register.

     Parameter  Description
  1  $source    Variable containing the address of the source
  2  $zmm       Number of zmm to get

Example:

  if (1)
   {my $a = V(key => 0x123);
    is_deeply $a->at,           "[rbp-8*(2)]";
    is_deeply $a->addressExpr, "[rbp-8*(2)]";

    ok !$a->isRef;

    Mov rax, -1;
    Kmovq k1, rax;
    PrintOutRegisterInHex k1;

    K(key => 2)->clearBit(rax);
    PrintOutRegisterInHex rax;

    K(key => 2)->setBit(rax);
    PrintOutRegisterInHex rax;

    K(key => 3)->clearMaskBit(k1);
    PrintOutRegisterInHex k1;

    K(key => 3)->setMaskBit(k1);
    PrintOutRegisterInHex k1;

    K(key => 0)->clearMaskBit(k1);
    PrintOutRegisterInHex k1;

    ClearRegisters k1;
    K(key => 7)->setMaskFirst(k1);
    PrintOutRegisterInHex k1;

    K(key => 3)->spaces($stdout);
    PrintOutRegisterInHex k1;

    my $N = K size => 4096;
    my $A = $N->allocateMemory;
    $A->clearMemory($N);
    ClearMemory($A, $N);

    $A->setReg(rax);
    Mov "dword[rax]",   0x61626364;
    Mov "dword[rax+4]", 0x65666768;

    ($A+8)->copyMemory($A, K key => 8);

    $A->printOutMemory  (K(key => 16));
    $A->printOutMemoryNL(K(key => 16));

    K(K => Rd(0..63))->loadZmm(1);
    PrintOutRegisterInHex zmm1;

    ok Assemble eq => <<END;
      k1: .... .... .... ..-1
     rax: FFFF FFFF FFFF FFFB
     rax: .... .... .... ..-1
      k1: FFFF FFFF FFFF FFF7
      k1: .... .... .... ..-1
      k1: FFFF FFFF FFFF FFFE
      k1: .... .... .... ..7F
         k1: .... .... .... ..7F
  dcbahgfedcbahgfedcbahgfedcbahgfe
    zmm1: .... ...F .... ...E  .... ...D .... ...C - .... ...B .... ...A  .... ...9 .... ...8 + .... ...7 .... ...6  .... ...5 .... ...4 - .... ...3 .... ...2  .... ...1 .... ....
  END
   }

Nasm::X86::Variable::bFromZ($variable, $zmm, $offset)

Get the byte from the numbered zmm register and put it in a variable.

     Parameter  Description
  1  $variable  Variable
  2  $zmm       Numbered zmm
  3  $offset    Offset in bytes

Example:

    Mov rax, 0x12345678;
    my $c = V("Content", rax);
    $c->bIntoX(1, 0);
    $c->bIntoX(1, 1);
    $c->wIntoX(1, 2);
    $c->dIntoX(1, 4);
    $c->qIntoX(1, 8);
    $c->bIntoZ(1, 16);
    $c->bIntoZ(1, 17);
    $c->dIntoZ(1, 20);
    $c->qIntoZ(1, 24);
    PrintOutRegisterInHex zmm1;

    my $q = V "var";

    $q->bFromZ(1, 16); $q->outNL;
    $q->bFromZ(1, 17); $q->outNL;
    $q->wFromZ(1, 18); $q->outNL;
    $q->dFromZ(1, 20); $q->outNL;
    $q->qFromZ(1, 20); $q->outNL;

    my $p = K key => 8;
    $p->dIntoPointInZ(1, K key => 0x22);
    $p->dFromPointInZ(1)->outNL;

    ok Assemble eq => <<END;
    zmm1: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... 1234 5678  1234 5678 .... 7878 - .... .... 1234 5678  1234 5678 5678 7878
  var: .... .... .... ..78
  var: .... .... .... ..78
  var: .... .... .... ...0
  var: .... .... 1234 5678
  var: 1234 5678 1234 5678
  d: .... .... .... ..22
  END

Nasm::X86::Variable::wFromZ($variable, $zmm, $offset)

Get the word from the numbered zmm register and put it in a variable.

     Parameter  Description
  1  $variable  Variable
  2  $zmm       Numbered zmm
  3  $offset    Offset in bytes

Example:

    Mov rax, 0x12345678;
    my $c = V("Content", rax);
    $c->bIntoX(1, 0);
    $c->bIntoX(1, 1);
    $c->wIntoX(1, 2);
    $c->dIntoX(1, 4);
    $c->qIntoX(1, 8);
    $c->bIntoZ(1, 16);
    $c->bIntoZ(1, 17);
    $c->dIntoZ(1, 20);
    $c->qIntoZ(1, 24);
    PrintOutRegisterInHex zmm1;

    my $q = V "var";

    $q->bFromZ(1, 16); $q->outNL;
    $q->bFromZ(1, 17); $q->outNL;
    $q->wFromZ(1, 18); $q->outNL;
    $q->dFromZ(1, 20); $q->outNL;
    $q->qFromZ(1, 20); $q->outNL;

    my $p = K key => 8;
    $p->dIntoPointInZ(1, K key => 0x22);
    $p->dFromPointInZ(1)->outNL;

    ok Assemble eq => <<END;
    zmm1: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... 1234 5678  1234 5678 .... 7878 - .... .... 1234 5678  1234 5678 5678 7878
  var: .... .... .... ..78
  var: .... .... .... ..78
  var: .... .... .... ...0
  var: .... .... 1234 5678
  var: 1234 5678 1234 5678
  d: .... .... .... ..22
  END

Nasm::X86::Variable::dFromZ($variable, $zmm, $offset)

Get the double word from the numbered zmm register and put it in a variable.

     Parameter  Description
  1  $variable  Variable
  2  $zmm       Numbered zmm
  3  $offset    Offset in bytes

Example:

    Mov rax, 0x12345678;
    my $c = V("Content", rax);
    $c->bIntoX(1, 0);
    $c->bIntoX(1, 1);
    $c->wIntoX(1, 2);
    $c->dIntoX(1, 4);
    $c->qIntoX(1, 8);
    $c->bIntoZ(1, 16);
    $c->bIntoZ(1, 17);
    $c->dIntoZ(1, 20);
    $c->qIntoZ(1, 24);
    PrintOutRegisterInHex zmm1;

    my $q = V "var";

    $q->bFromZ(1, 16); $q->outNL;
    $q->bFromZ(1, 17); $q->outNL;
    $q->wFromZ(1, 18); $q->outNL;
    $q->dFromZ(1, 20); $q->outNL;
    $q->qFromZ(1, 20); $q->outNL;

    my $p = K key => 8;
    $p->dIntoPointInZ(1, K key => 0x22);
    $p->dFromPointInZ(1)->outNL;

    ok Assemble eq => <<END;
    zmm1: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... 1234 5678  1234 5678 .... 7878 - .... .... 1234 5678  1234 5678 5678 7878
  var: .... .... .... ..78
  var: .... .... .... ..78
  var: .... .... .... ...0
  var: .... .... 1234 5678
  var: 1234 5678 1234 5678
  d: .... .... .... ..22
  END

Nasm::X86::Variable::qFromZ($variable, $zmm, $offset)

Get the quad word from the numbered zmm register and put it in a variable.

     Parameter  Description
  1  $variable  Variable
  2  $zmm       Numbered zmm
  3  $offset    Offset in bytes

Example:

    Mov rax, 0x12345678;
    my $c = V("Content", rax);
    $c->bIntoX(1, 0);
    $c->bIntoX(1, 1);
    $c->wIntoX(1, 2);
    $c->dIntoX(1, 4);
    $c->qIntoX(1, 8);
    $c->bIntoZ(1, 16);
    $c->bIntoZ(1, 17);
    $c->dIntoZ(1, 20);
    $c->qIntoZ(1, 24);
    PrintOutRegisterInHex zmm1;

    my $q = V "var";

    $q->bFromZ(1, 16); $q->outNL;
    $q->bFromZ(1, 17); $q->outNL;
    $q->wFromZ(1, 18); $q->outNL;
    $q->dFromZ(1, 20); $q->outNL;
    $q->qFromZ(1, 20); $q->outNL;

    my $p = K key => 8;
    $p->dIntoPointInZ(1, K key => 0x22);
    $p->dFromPointInZ(1)->outNL;

    ok Assemble eq => <<END;
    zmm1: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... 1234 5678  1234 5678 .... 7878 - .... .... 1234 5678  1234 5678 5678 7878
  var: .... .... .... ..78
  var: .... .... .... ..78
  var: .... .... .... ...0
  var: .... .... 1234 5678
  var: 1234 5678 1234 5678
  d: .... .... .... ..22
  END

Nasm::X86::Variable::bIntoX($content, $xmm, $offset)

Place the value of the content variable at the byte in the numbered xmm register.

     Parameter  Description
  1  $content   Variable with content
  2  $xmm       Numbered xmm
  3  $offset    Offset in bytes

Example:

    Mov rax, 0x12345678;
    my $c = V("Content", rax);
    $c->bIntoX(1, 0);
    $c->bIntoX(1, 1);
    $c->wIntoX(1, 2);
    $c->dIntoX(1, 4);
    $c->qIntoX(1, 8);
    $c->bIntoZ(1, 16);
    $c->bIntoZ(1, 17);
    $c->dIntoZ(1, 20);
    $c->qIntoZ(1, 24);
    PrintOutRegisterInHex zmm1;

    my $q = V "var";

    $q->bFromZ(1, 16); $q->outNL;
    $q->bFromZ(1, 17); $q->outNL;
    $q->wFromZ(1, 18); $q->outNL;
    $q->dFromZ(1, 20); $q->outNL;
    $q->qFromZ(1, 20); $q->outNL;

    my $p = K key => 8;
    $p->dIntoPointInZ(1, K key => 0x22);
    $p->dFromPointInZ(1)->outNL;

    ok Assemble eq => <<END;
    zmm1: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... 1234 5678  1234 5678 .... 7878 - .... .... 1234 5678  1234 5678 5678 7878
  var: .... .... .... ..78
  var: .... .... .... ..78
  var: .... .... .... ...0
  var: .... .... 1234 5678
  var: 1234 5678 1234 5678
  d: .... .... .... ..22
  END

Nasm::X86::Variable::wIntoX($content, $xmm, $offset)

Place the value of the content variable at the word in the numbered xmm register.

     Parameter  Description
  1  $content   Variable with content
  2  $xmm       Numbered xmm
  3  $offset    Offset in bytes

Example:

    Mov rax, 0x12345678;
    my $c = V("Content", rax);
    $c->bIntoX(1, 0);
    $c->bIntoX(1, 1);
    $c->wIntoX(1, 2);
    $c->dIntoX(1, 4);
    $c->qIntoX(1, 8);
    $c->bIntoZ(1, 16);
    $c->bIntoZ(1, 17);
    $c->dIntoZ(1, 20);
    $c->qIntoZ(1, 24);
    PrintOutRegisterInHex zmm1;

    my $q = V "var";

    $q->bFromZ(1, 16); $q->outNL;
    $q->bFromZ(1, 17); $q->outNL;
    $q->wFromZ(1, 18); $q->outNL;
    $q->dFromZ(1, 20); $q->outNL;
    $q->qFromZ(1, 20); $q->outNL;

    my $p = K key => 8;
    $p->dIntoPointInZ(1, K key => 0x22);
    $p->dFromPointInZ(1)->outNL;

    ok Assemble eq => <<END;
    zmm1: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... 1234 5678  1234 5678 .... 7878 - .... .... 1234 5678  1234 5678 5678 7878
  var: .... .... .... ..78
  var: .... .... .... ..78
  var: .... .... .... ...0
  var: .... .... 1234 5678
  var: 1234 5678 1234 5678
  d: .... .... .... ..22
  END

Nasm::X86::Variable::dIntoX($content, $xmm, $offset)

Place the value of the content variable at the double word in the numbered xmm register.

     Parameter  Description
  1  $content   Variable with content
  2  $xmm       Numbered xmm
  3  $offset    Offset in bytes

Example:

    Mov rax, 0x12345678;
    my $c = V("Content", rax);
    $c->bIntoX(1, 0);
    $c->bIntoX(1, 1);
    $c->wIntoX(1, 2);
    $c->dIntoX(1, 4);
    $c->qIntoX(1, 8);
    $c->bIntoZ(1, 16);
    $c->bIntoZ(1, 17);
    $c->dIntoZ(1, 20);
    $c->qIntoZ(1, 24);
    PrintOutRegisterInHex zmm1;

    my $q = V "var";

    $q->bFromZ(1, 16); $q->outNL;
    $q->bFromZ(1, 17); $q->outNL;
    $q->wFromZ(1, 18); $q->outNL;
    $q->dFromZ(1, 20); $q->outNL;
    $q->qFromZ(1, 20); $q->outNL;

    my $p = K key => 8;
    $p->dIntoPointInZ(1, K key => 0x22);
    $p->dFromPointInZ(1)->outNL;

    ok Assemble eq => <<END;
    zmm1: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... 1234 5678  1234 5678 .... 7878 - .... .... 1234 5678  1234 5678 5678 7878
  var: .... .... .... ..78
  var: .... .... .... ..78
  var: .... .... .... ...0
  var: .... .... 1234 5678
  var: 1234 5678 1234 5678
  d: .... .... .... ..22
  END

Nasm::X86::Variable::qIntoX($content, $xmm, $offset)

Place the value of the content variable at the quad word in the numbered xmm register.

     Parameter  Description
  1  $content   Variable with content
  2  $xmm       Numbered xmm
  3  $offset    Offset in bytes

Example:

    Mov rax, 0x12345678;
    my $c = V("Content", rax);
    $c->bIntoX(1, 0);
    $c->bIntoX(1, 1);
    $c->wIntoX(1, 2);
    $c->dIntoX(1, 4);
    $c->qIntoX(1, 8);
    $c->bIntoZ(1, 16);
    $c->bIntoZ(1, 17);
    $c->dIntoZ(1, 20);
    $c->qIntoZ(1, 24);
    PrintOutRegisterInHex zmm1;

    my $q = V "var";

    $q->bFromZ(1, 16); $q->outNL;
    $q->bFromZ(1, 17); $q->outNL;
    $q->wFromZ(1, 18); $q->outNL;
    $q->dFromZ(1, 20); $q->outNL;
    $q->qFromZ(1, 20); $q->outNL;

    my $p = K key => 8;
    $p->dIntoPointInZ(1, K key => 0x22);
    $p->dFromPointInZ(1)->outNL;

    ok Assemble eq => <<END;
    zmm1: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... 1234 5678  1234 5678 .... 7878 - .... .... 1234 5678  1234 5678 5678 7878
  var: .... .... .... ..78
  var: .... .... .... ..78
  var: .... .... .... ...0
  var: .... .... 1234 5678
  var: 1234 5678 1234 5678
  d: .... .... .... ..22
  END

Nasm::X86::Variable::bIntoZ($content, $zmm, $offset)

Place the value of the content variable at the byte in the numbered zmm register.

     Parameter  Description
  1  $content   Variable with content
  2  $zmm       Numbered zmm
  3  $offset    Offset in bytes

Example:

    my $s = Rb(0..8);
    my $c = V("Content",   "[$s]");
       $c->bIntoZ     (0, 4);
       $c->putWIntoZmm(0, 6);
       $c->dIntoZ(0, 10);
       $c->qIntoZ(0, 16);
    PrintOutRegisterInHex zmm0;
    bFromZ(zmm0, 12)->outNL;
    wFromZ(zmm0, 12)->outNL;
    dFromZ(zmm0, 12)->outNL;
    qFromZ(zmm0, 12)->outNL;

    ok Assemble(debug => 0, eq => <<END, avx512=>1);
    zmm0: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .7.6 .5.4 .3.2 .1.. - .... .3.2 .1.. ....  .1.. .... .... ....
  b at offset 12 in zmm0: .... .... .... ...2
  w at offset 12 in zmm0: .... .... .... .3.2
  d at offset 12 in zmm0: .... .... .... .3.2
  q at offset 12 in zmm0: .3.2 .1.. .... .3.2
  END

    Mov rax, 0x12345678;
    my $c = V("Content", rax);
    $c->bIntoX(1, 0);
    $c->bIntoX(1, 1);
    $c->wIntoX(1, 2);
    $c->dIntoX(1, 4);
    $c->qIntoX(1, 8);
    $c->bIntoZ(1, 16);
    $c->bIntoZ(1, 17);
    $c->dIntoZ(1, 20);
    $c->qIntoZ(1, 24);
    PrintOutRegisterInHex zmm1;

    my $q = V "var";

    $q->bFromZ(1, 16); $q->outNL;
    $q->bFromZ(1, 17); $q->outNL;
    $q->wFromZ(1, 18); $q->outNL;
    $q->dFromZ(1, 20); $q->outNL;
    $q->qFromZ(1, 20); $q->outNL;

    my $p = K key => 8;
    $p->dIntoPointInZ(1, K key => 0x22);
    $p->dFromPointInZ(1)->outNL;

    ok Assemble eq => <<END;
    zmm1: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... 1234 5678  1234 5678 .... 7878 - .... .... 1234 5678  1234 5678 5678 7878
  var: .... .... .... ..78
  var: .... .... .... ..78
  var: .... .... .... ...0
  var: .... .... 1234 5678
  var: 1234 5678 1234 5678
  d: .... .... .... ..22
  END

Nasm::X86::Variable::putWIntoZmm($content, $zmm, $offset)

Place the value of the content variable at the word in the numbered zmm register.

     Parameter  Description
  1  $content   Variable with content
  2  $zmm       Numbered zmm
  3  $offset    Offset in bytes

Example:

    my $s = Rb(0..8);
    my $c = V("Content",   "[$s]");
       $c->bIntoZ     (0, 4);
       $c->putWIntoZmm(0, 6);
       $c->dIntoZ(0, 10);
       $c->qIntoZ(0, 16);
    PrintOutRegisterInHex zmm0;
    bFromZ(zmm0, 12)->outNL;
    wFromZ(zmm0, 12)->outNL;
    dFromZ(zmm0, 12)->outNL;
    qFromZ(zmm0, 12)->outNL;

    ok Assemble(debug => 0, eq => <<END, avx512=>1);
    zmm0: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .7.6 .5.4 .3.2 .1.. - .... .3.2 .1.. ....  .1.. .... .... ....
  b at offset 12 in zmm0: .... .... .... ...2
  w at offset 12 in zmm0: .... .... .... .3.2
  d at offset 12 in zmm0: .... .... .... .3.2
  q at offset 12 in zmm0: .3.2 .1.. .... .3.2
  END

Nasm::X86::Variable::dIntoZ($content, $zmm, $offset)

Place the value of the content variable at the double word in the numbered zmm register.

     Parameter  Description
  1  $content   Variable with content
  2  $zmm       Numbered zmm
  3  $offset    Offset in bytes

Example:

    my $s = Rb(0..8);
    my $c = V("Content",   "[$s]");
       $c->bIntoZ     (0, 4);
       $c->putWIntoZmm(0, 6);
       $c->dIntoZ(0, 10);
       $c->qIntoZ(0, 16);
    PrintOutRegisterInHex zmm0;
    bFromZ(zmm0, 12)->outNL;
    wFromZ(zmm0, 12)->outNL;
    dFromZ(zmm0, 12)->outNL;
    qFromZ(zmm0, 12)->outNL;

    ok Assemble(debug => 0, eq => <<END, avx512=>1);
    zmm0: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .7.6 .5.4 .3.2 .1.. - .... .3.2 .1.. ....  .1.. .... .... ....
  b at offset 12 in zmm0: .... .... .... ...2
  w at offset 12 in zmm0: .... .... .... .3.2
  d at offset 12 in zmm0: .... .... .... .3.2
  q at offset 12 in zmm0: .3.2 .1.. .... .3.2
  END

    Mov rax, 0x12345678;
    my $c = V("Content", rax);
    $c->bIntoX(1, 0);
    $c->bIntoX(1, 1);
    $c->wIntoX(1, 2);
    $c->dIntoX(1, 4);
    $c->qIntoX(1, 8);
    $c->bIntoZ(1, 16);
    $c->bIntoZ(1, 17);
    $c->dIntoZ(1, 20);
    $c->qIntoZ(1, 24);
    PrintOutRegisterInHex zmm1;

    my $q = V "var";

    $q->bFromZ(1, 16); $q->outNL;
    $q->bFromZ(1, 17); $q->outNL;
    $q->wFromZ(1, 18); $q->outNL;
    $q->dFromZ(1, 20); $q->outNL;
    $q->qFromZ(1, 20); $q->outNL;

    my $p = K key => 8;
    $p->dIntoPointInZ(1, K key => 0x22);
    $p->dFromPointInZ(1)->outNL;

    ok Assemble eq => <<END;
    zmm1: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... 1234 5678  1234 5678 .... 7878 - .... .... 1234 5678  1234 5678 5678 7878
  var: .... .... .... ..78
  var: .... .... .... ..78
  var: .... .... .... ...0
  var: .... .... 1234 5678
  var: 1234 5678 1234 5678
  d: .... .... .... ..22
  END

Nasm::X86::Variable::qIntoZ($content, $zmm, $offset)

Place the value of the content variable at the quad word in the numbered zmm register.

     Parameter  Description
  1  $content   Variable with content
  2  $zmm       Numbered zmm
  3  $offset    Offset in bytes

Example:

    my $s = Rb(0..8);
    my $c = V("Content",   "[$s]");
       $c->bIntoZ     (0, 4);
       $c->putWIntoZmm(0, 6);
       $c->dIntoZ(0, 10);
       $c->qIntoZ(0, 16);
    PrintOutRegisterInHex zmm0;
    bFromZ(zmm0, 12)->outNL;
    wFromZ(zmm0, 12)->outNL;
    dFromZ(zmm0, 12)->outNL;
    qFromZ(zmm0, 12)->outNL;

    ok Assemble(debug => 0, eq => <<END, avx512=>1);
    zmm0: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .7.6 .5.4 .3.2 .1.. - .... .3.2 .1.. ....  .1.. .... .... ....
  b at offset 12 in zmm0: .... .... .... ...2
  w at offset 12 in zmm0: .... .... .... .3.2
  d at offset 12 in zmm0: .... .... .... .3.2
  q at offset 12 in zmm0: .3.2 .1.. .... .3.2
  END

    Mov rax, 0x12345678;
    my $c = V("Content", rax);
    $c->bIntoX(1, 0);
    $c->bIntoX(1, 1);
    $c->wIntoX(1, 2);
    $c->dIntoX(1, 4);
    $c->qIntoX(1, 8);
    $c->bIntoZ(1, 16);
    $c->bIntoZ(1, 17);
    $c->dIntoZ(1, 20);
    $c->qIntoZ(1, 24);
    PrintOutRegisterInHex zmm1;

    my $q = V "var";

    $q->bFromZ(1, 16); $q->outNL;
    $q->bFromZ(1, 17); $q->outNL;
    $q->wFromZ(1, 18); $q->outNL;
    $q->dFromZ(1, 20); $q->outNL;
    $q->qFromZ(1, 20); $q->outNL;

    my $p = K key => 8;
    $p->dIntoPointInZ(1, K key => 0x22);
    $p->dFromPointInZ(1)->outNL;

    ok Assemble eq => <<END;
    zmm1: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... 1234 5678  1234 5678 .... 7878 - .... .... 1234 5678  1234 5678 5678 7878
  var: .... .... .... ..78
  var: .... .... .... ..78
  var: .... .... .... ...0
  var: .... .... 1234 5678
  var: 1234 5678 1234 5678
  d: .... .... .... ..22
  END

At a point

Place data into mm registers and retrieve data from them at the indicated point.

Nasm::X86::Variable::dFromPointInZ($point, $zmm, %options)

Get the double word from the numbered zmm register at a point specified by the variable and return it in a variable.

     Parameter  Description
  1  $point     Point
  2  $zmm       Numbered zmm
  3  %options   Options

Example:

    Mov rax, 0x12345678;
    my $c = V("Content", rax);
    $c->bIntoX(1, 0);
    $c->bIntoX(1, 1);
    $c->wIntoX(1, 2);
    $c->dIntoX(1, 4);
    $c->qIntoX(1, 8);
    $c->bIntoZ(1, 16);
    $c->bIntoZ(1, 17);
    $c->dIntoZ(1, 20);
    $c->qIntoZ(1, 24);
    PrintOutRegisterInHex zmm1;

    my $q = V "var";

    $q->bFromZ(1, 16); $q->outNL;
    $q->bFromZ(1, 17); $q->outNL;
    $q->wFromZ(1, 18); $q->outNL;
    $q->dFromZ(1, 20); $q->outNL;
    $q->qFromZ(1, 20); $q->outNL;

    my $p = K key => 8;
    $p->dIntoPointInZ(1, K key => 0x22);
    $p->dFromPointInZ(1)->outNL;

    ok Assemble eq => <<END;
    zmm1: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... 1234 5678  1234 5678 .... 7878 - .... .... 1234 5678  1234 5678 5678 7878
  var: .... .... .... ..78
  var: .... .... .... ..78
  var: .... .... .... ...0
  var: .... .... 1234 5678
  var: 1234 5678 1234 5678
  d: .... .... .... ..22
  END

    my $tree = DescribeTree(length => 7);

    my $K = 31;

    K(K => Rd(0..15))->loadZmm($K);

    PrintOutRegisterInHex zmm $K;
    K( offset => 1 << 5)->dFromPointInZ($K)->outNL;

    ok Assemble eq => <<END, avx512=>1;
   zmm31: .... ...F .... ...E  .... ...D .... ...C - .... ...B .... ...A  .... ...9 .... ...8 + .... ...7 .... ...6  .... ...5 .... ...4 - .... ...3 .... ...2  .... ...1 .... ....
  d: .... .... .... ...5
  END

Nasm::X86::Variable::dIntoPointInZ($point, $zmm, $content)

Put the variable double word content into the numbered zmm register at a point specified by the variable.

     Parameter  Description
  1  $point     Point
  2  $zmm       Numbered zmm
  3  $content   Content to be inserted as a variable

Example:

    Mov rax, 0x12345678;
    my $c = V("Content", rax);
    $c->bIntoX(1, 0);
    $c->bIntoX(1, 1);
    $c->wIntoX(1, 2);
    $c->dIntoX(1, 4);
    $c->qIntoX(1, 8);
    $c->bIntoZ(1, 16);
    $c->bIntoZ(1, 17);
    $c->dIntoZ(1, 20);
    $c->qIntoZ(1, 24);
    PrintOutRegisterInHex zmm1;

    my $q = V "var";

    $q->bFromZ(1, 16); $q->outNL;
    $q->bFromZ(1, 17); $q->outNL;
    $q->wFromZ(1, 18); $q->outNL;
    $q->dFromZ(1, 20); $q->outNL;
    $q->qFromZ(1, 20); $q->outNL;

    my $p = K key => 8;
    $p->dIntoPointInZ(1, K key => 0x22);
    $p->dFromPointInZ(1)->outNL;

    ok Assemble eq => <<END;
    zmm1: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... 1234 5678  1234 5678 .... 7878 - .... .... 1234 5678  1234 5678 5678 7878
  var: .... .... .... ..78
  var: .... .... .... ..78
  var: .... .... .... ...0
  var: .... .... 1234 5678
  var: 1234 5678 1234 5678
  d: .... .... .... ..22
  END

Memory

Actions on memory described by variables

Nasm::X86::Variable::clearMemory($address, $size)

Clear the memory described in this variable.

     Parameter  Description
  1  $address   Address of memory to clear
  2  $size      Size of the memory to clear

Example:

  if (1)
   {my $a = V(key => 0x123);
    is_deeply $a->at,           "[rbp-8*(2)]";
    is_deeply $a->addressExpr, "[rbp-8*(2)]";

    ok !$a->isRef;

    Mov rax, -1;
    Kmovq k1, rax;
    PrintOutRegisterInHex k1;

    K(key => 2)->clearBit(rax);
    PrintOutRegisterInHex rax;

    K(key => 2)->setBit(rax);
    PrintOutRegisterInHex rax;

    K(key => 3)->clearMaskBit(k1);
    PrintOutRegisterInHex k1;

    K(key => 3)->setMaskBit(k1);
    PrintOutRegisterInHex k1;

    K(key => 0)->clearMaskBit(k1);
    PrintOutRegisterInHex k1;

    ClearRegisters k1;
    K(key => 7)->setMaskFirst(k1);
    PrintOutRegisterInHex k1;

    K(key => 3)->spaces($stdout);
    PrintOutRegisterInHex k1;

    my $N = K size => 4096;
    my $A = $N->allocateMemory;
    $A->clearMemory($N);
    ClearMemory($A, $N);

    $A->setReg(rax);
    Mov "dword[rax]",   0x61626364;
    Mov "dword[rax+4]", 0x65666768;

    ($A+8)->copyMemory($A, K key => 8);

    $A->printOutMemory  (K(key => 16));
    $A->printOutMemoryNL(K(key => 16));

    K(K => Rd(0..63))->loadZmm(1);
    PrintOutRegisterInHex zmm1;

    ok Assemble eq => <<END;
      k1: .... .... .... ..-1
     rax: FFFF FFFF FFFF FFFB
     rax: .... .... .... ..-1
      k1: FFFF FFFF FFFF FFF7
      k1: .... .... .... ..-1
      k1: FFFF FFFF FFFF FFFE
      k1: .... .... .... ..7F
         k1: .... .... .... ..7F
  dcbahgfedcbahgfedcbahgfedcbahgfe
    zmm1: .... ...F .... ...E  .... ...D .... ...C - .... ...B .... ...A  .... ...9 .... ...8 + .... ...7 .... ...6  .... ...5 .... ...4 - .... ...3 .... ...2  .... ...1 .... ....
  END
   }

Nasm::X86::Variable::copyMemory($target, $source, $size)

Copy from one block of memory to another.

     Parameter  Description
  1  $target    Address of target
  2  $source    Address of source
  3  $size      Length to copy

Example:

  if (1)
   {my $a = V(key => 0x123);
    is_deeply $a->at,           "[rbp-8*(2)]";
    is_deeply $a->addressExpr, "[rbp-8*(2)]";

    ok !$a->isRef;

    Mov rax, -1;
    Kmovq k1, rax;
    PrintOutRegisterInHex k1;

    K(key => 2)->clearBit(rax);
    PrintOutRegisterInHex rax;

    K(key => 2)->setBit(rax);
    PrintOutRegisterInHex rax;

    K(key => 3)->clearMaskBit(k1);
    PrintOutRegisterInHex k1;

    K(key => 3)->setMaskBit(k1);
    PrintOutRegisterInHex k1;

    K(key => 0)->clearMaskBit(k1);
    PrintOutRegisterInHex k1;

    ClearRegisters k1;
    K(key => 7)->setMaskFirst(k1);
    PrintOutRegisterInHex k1;

    K(key => 3)->spaces($stdout);
    PrintOutRegisterInHex k1;

    my $N = K size => 4096;
    my $A = $N->allocateMemory;
    $A->clearMemory($N);
    ClearMemory($A, $N);

    $A->setReg(rax);
    Mov "dword[rax]",   0x61626364;
    Mov "dword[rax+4]", 0x65666768;

    ($A+8)->copyMemory($A, K key => 8);

    $A->printOutMemory  (K(key => 16));
    $A->printOutMemoryNL(K(key => 16));

    K(K => Rd(0..63))->loadZmm(1);
    PrintOutRegisterInHex zmm1;

    ok Assemble eq => <<END;
      k1: .... .... .... ..-1
     rax: FFFF FFFF FFFF FFFB
     rax: .... .... .... ..-1
      k1: FFFF FFFF FFFF FFF7
      k1: .... .... .... ..-1
      k1: FFFF FFFF FFFF FFFE
      k1: .... .... .... ..7F
         k1: .... .... .... ..7F
  dcbahgfedcbahgfedcbahgfedcbahgfe
    zmm1: .... ...F .... ...E  .... ...D .... ...C - .... ...B .... ...A  .... ...9 .... ...8 + .... ...7 .... ...6  .... ...5 .... ...4 - .... ...3 .... ...2  .... ...1 .... ....
  END
   }

Nasm::X86::Variable::printOutMemory($address, $size)

Print the specified number of bytes of the memory addressed by the variable on stdout.

     Parameter  Description
  1  $address   Address of memory
  2  $size      Number of bytes to print

Example:

  if (1)
   {my $a = V(key => 0x123);
    is_deeply $a->at,           "[rbp-8*(2)]";
    is_deeply $a->addressExpr, "[rbp-8*(2)]";

    ok !$a->isRef;

    Mov rax, -1;
    Kmovq k1, rax;
    PrintOutRegisterInHex k1;

    K(key => 2)->clearBit(rax);
    PrintOutRegisterInHex rax;

    K(key => 2)->setBit(rax);
    PrintOutRegisterInHex rax;

    K(key => 3)->clearMaskBit(k1);
    PrintOutRegisterInHex k1;

    K(key => 3)->setMaskBit(k1);
    PrintOutRegisterInHex k1;

    K(key => 0)->clearMaskBit(k1);
    PrintOutRegisterInHex k1;

    ClearRegisters k1;
    K(key => 7)->setMaskFirst(k1);
    PrintOutRegisterInHex k1;

    K(key => 3)->spaces($stdout);
    PrintOutRegisterInHex k1;

    my $N = K size => 4096;
    my $A = $N->allocateMemory;
    $A->clearMemory($N);
    ClearMemory($A, $N);

    $A->setReg(rax);
    Mov "dword[rax]",   0x61626364;
    Mov "dword[rax+4]", 0x65666768;

    ($A+8)->copyMemory($A, K key => 8);

    $A->printOutMemory  (K(key => 16));
    $A->printOutMemoryNL(K(key => 16));

    K(K => Rd(0..63))->loadZmm(1);
    PrintOutRegisterInHex zmm1;

    ok Assemble eq => <<END;
      k1: .... .... .... ..-1
     rax: FFFF FFFF FFFF FFFB
     rax: .... .... .... ..-1
      k1: FFFF FFFF FFFF FFF7
      k1: .... .... .... ..-1
      k1: FFFF FFFF FFFF FFFE
      k1: .... .... .... ..7F
         k1: .... .... .... ..7F
  dcbahgfedcbahgfedcbahgfedcbahgfe
    zmm1: .... ...F .... ...E  .... ...D .... ...C - .... ...B .... ...A  .... ...9 .... ...8 + .... ...7 .... ...6  .... ...5 .... ...4 - .... ...3 .... ...2  .... ...1 .... ....
  END
   }

Nasm::X86::Variable::printOutMemoryNL($address, $size)

Print the specified number of bytes of the memory addressed by the variable on stdout followed by a new line.

     Parameter  Description
  1  $address   Address of memory
  2  $size      Number of bytes to print

Example:

  if (1)
   {my $a = V(key => 0x123);
    is_deeply $a->at,           "[rbp-8*(2)]";
    is_deeply $a->addressExpr, "[rbp-8*(2)]";

    ok !$a->isRef;

    Mov rax, -1;
    Kmovq k1, rax;
    PrintOutRegisterInHex k1;

    K(key => 2)->clearBit(rax);
    PrintOutRegisterInHex rax;

    K(key => 2)->setBit(rax);
    PrintOutRegisterInHex rax;

    K(key => 3)->clearMaskBit(k1);
    PrintOutRegisterInHex k1;

    K(key => 3)->setMaskBit(k1);
    PrintOutRegisterInHex k1;

    K(key => 0)->clearMaskBit(k1);
    PrintOutRegisterInHex k1;

    ClearRegisters k1;
    K(key => 7)->setMaskFirst(k1);
    PrintOutRegisterInHex k1;

    K(key => 3)->spaces($stdout);
    PrintOutRegisterInHex k1;

    my $N = K size => 4096;
    my $A = $N->allocateMemory;
    $A->clearMemory($N);
    ClearMemory($A, $N);

    $A->setReg(rax);
    Mov "dword[rax]",   0x61626364;
    Mov "dword[rax+4]", 0x65666768;

    ($A+8)->copyMemory($A, K key => 8);

    $A->printOutMemory  (K(key => 16));
    $A->printOutMemoryNL(K(key => 16));

    K(K => Rd(0..63))->loadZmm(1);
    PrintOutRegisterInHex zmm1;

    ok Assemble eq => <<END;
      k1: .... .... .... ..-1
     rax: FFFF FFFF FFFF FFFB
     rax: .... .... .... ..-1
      k1: FFFF FFFF FFFF FFF7
      k1: .... .... .... ..-1
      k1: FFFF FFFF FFFF FFFE
      k1: .... .... .... ..7F
         k1: .... .... .... ..7F
  dcbahgfedcbahgfedcbahgfedcbahgfe
    zmm1: .... ...F .... ...E  .... ...D .... ...C - .... ...B .... ...A  .... ...9 .... ...8 + .... ...7 .... ...6  .... ...5 .... ...4 - .... ...3 .... ...2  .... ...1 .... ....
  END
   }

Nasm::X86::Variable::printOutMemoryInHexNL($address, $size)

Write the memory addressed by a variable to stdout.

     Parameter  Description
  1  $address   Address of memory
  2  $size      Number of bytes to print

Example:

    my $u = Rd(ord('𝝰'), ord('𝝱'), ord('𝝲'), ord('𝝳'));
    Mov rax, $u;
    my $address = V address=>rax;
    $address->printOutMemoryInHexNL(K size => 16);

    ok Assemble(debug => 0, trace => 0, eq => <<END, avx512=>0);
  70D7 .1.. 71D7 .1..  72D7 .1.. 73D7 .1..
  END

    my $v = V var => 2;

    If  $v == 0, Then {Mov rax, 0},
    Ef {$v == 1} Then {Mov rax, 1},
    Ef {$v == 2} Then {Mov rax, 2},
                 Else {Mov rax, 3};
    PrintOutRegisterInHex rax;
    ok Assemble(debug => 0, trace => 0, eq => <<END, avx512=>0);
     rax: .... .... .... ...2
  END

Nasm::X86::Variable::freeMemory($address, $size)

Free the memory addressed by this variable for the specified length.

     Parameter  Description
  1  $address   Address of memory to free
  2  $size      Size of the memory to free

Example:

    my $N = K size => 2048;
    my $q = Rs('a'..'p');
    my $address = $N->allocateMemory;

    Vmovdqu8 xmm0, "[$q]";
    $address->setReg(rax);
    Vmovdqu8 "[rax]", xmm0;
    Mov rdi, 16;
    PrintOutMemory;
    PrintOutNL;

    $address->freeMemory($N);

    ok Assemble eq => <<END;
  abcdefghijklmnop
  END

Nasm::X86::Variable::allocateMemory($size)

Allocate a variable amount of memory via mmap and return its address.

     Parameter  Description
  1  $size      Size as a variable

Example:

    my $N = K size => 2048;
    my $q = Rs('a'..'p');
    my $address = $N->allocateMemory;

    Vmovdqu8 xmm0, "[$q]";
    $address->setReg(rax);
    Vmovdqu8 "[rax]", xmm0;
    Mov rdi, 16;
    PrintOutMemory;
    PrintOutNL;

    $address->freeMemory($N);

    ok Assemble eq => <<END;
  abcdefghijklmnop
  END

Structured Programming with variables

Structured programming operations driven off variables.

Nasm::X86::Variable::for($limit, $block)

Iterate a block a variable number of times.

     Parameter  Description
  1  $limit     Number of times
  2  $block     Block

Example:

    V(limit => 10)->for(sub
     {my ($i, $start, $next, $end) = @_;
      $i->outNL;
     });

    ok Assemble(debug => 0, eq => <<END, avx512=>0);
  index: .... .... .... ...0
  index: .... .... .... ...1
  index: .... .... .... ...2
  index: .... .... .... ...3
  index: .... .... .... ...4
  index: .... .... .... ...5
  index: .... .... .... ...6
  index: .... .... .... ...7
  index: .... .... .... ...8
  index: .... .... .... ...9
  END

Operating system

Interacting with the operating system.

Processes

Create and manage processes

Fork()

Fork: create and execute a copy of the current process.

Example:

    Fork;                                                                         # Fork  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲


    Test rax,rax;
    IfNz                                                                          # Parent
    Then
     {Mov rbx, rax;
      WaitPid;
      GetPid;                                                                     # Pid of parent as seen in parent
      Mov rcx,rax;
      PrintOutRegisterInHex rax, rbx, rcx;
     },
    Else                                                                          # Child
     {Mov r8,rax;
      GetPid;                                                                     # Child pid as seen in child
      Mov r9,rax;
      GetPPid;                                                                    # Parent pid as seen in child
      Mov r10,rax;
      PrintOutRegisterInHex r8, r9, r10;
     };

    my $r = Assemble(avx512=>0);

  #    r8: 0000 0000 0000 0000   #1 Return from fork as seen by child
  #    r9: 0000 0000 0003 0C63   #2 Pid of child
  #   r10: 0000 0000 0003 0C60   #3 Pid of parent from child
  #   rax: 0000 0000 0003 0C63   #4 Return from fork as seen by parent
  #   rbx: 0000 0000 0003 0C63   #5 Wait for child pid result
  #   rcx: 0000 0000 0003 0C60   #6 Pid of parent

    if ($r =~ m(r8:( 0000){4}.*r9:(.*)\s{5,}r10:(.*)\s{5,}rax:(.*)\s{5,}rbx:(.*)\s{5,}rcx:(.*)\s{2,})s)
     {ok $2 eq $4;
      ok $2 eq $5;
      ok $3 eq $6;
      ok $2 gt $6;
     }

GetPid()

Get process identifier.

Example:

    Fork;                                                                         # Fork

    Test rax,rax;
    IfNz                                                                          # Parent
    Then
     {Mov rbx, rax;
      WaitPid;

      GetPid;                                                                     # Pid of parent as seen in parent  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

      Mov rcx,rax;
      PrintOutRegisterInHex rax, rbx, rcx;
     },
    Else                                                                          # Child
     {Mov r8,rax;

      GetPid;                                                                     # Child pid as seen in child  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

      Mov r9,rax;
      GetPPid;                                                                    # Parent pid as seen in child
      Mov r10,rax;
      PrintOutRegisterInHex r8, r9, r10;
     };

    my $r = Assemble(avx512=>0);

  #    r8: 0000 0000 0000 0000   #1 Return from fork as seen by child
  #    r9: 0000 0000 0003 0C63   #2 Pid of child
  #   r10: 0000 0000 0003 0C60   #3 Pid of parent from child
  #   rax: 0000 0000 0003 0C63   #4 Return from fork as seen by parent
  #   rbx: 0000 0000 0003 0C63   #5 Wait for child pid result
  #   rcx: 0000 0000 0003 0C60   #6 Pid of parent

    if ($r =~ m(r8:( 0000){4}.*r9:(.*)\s{5,}r10:(.*)\s{5,}rax:(.*)\s{5,}rbx:(.*)\s{5,}rcx:(.*)\s{2,})s)
     {ok $2 eq $4;
      ok $2 eq $5;
      ok $3 eq $6;
      ok $2 gt $6;
     }

GetPidInHex()

Get process identifier in hex as 8 zero terminated bytes in rax.

Example:

    GetPidInHex;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    Mov r15, rax;


    GetPidInHex;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    Cmp r15, rax;
    IfEq Then {PrintOutStringNL "Same"}, Else {PrintOutStringNL "Diff"};

    ok Assemble eq => <<END, avx512=>0;
  Same
  END

GetPPid()

Get parent process identifier.

Example:

    Fork;                                                                         # Fork

    Test rax,rax;
    IfNz                                                                          # Parent
    Then
     {Mov rbx, rax;
      WaitPid;
      GetPid;                                                                     # Pid of parent as seen in parent
      Mov rcx,rax;
      PrintOutRegisterInHex rax, rbx, rcx;
     },
    Else                                                                          # Child
     {Mov r8,rax;
      GetPid;                                                                     # Child pid as seen in child
      Mov r9,rax;

      GetPPid;                                                                    # Parent pid as seen in child  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

      Mov r10,rax;
      PrintOutRegisterInHex r8, r9, r10;
     };

    my $r = Assemble(avx512=>0);

  #    r8: 0000 0000 0000 0000   #1 Return from fork as seen by child
  #    r9: 0000 0000 0003 0C63   #2 Pid of child
  #   r10: 0000 0000 0003 0C60   #3 Pid of parent from child
  #   rax: 0000 0000 0003 0C63   #4 Return from fork as seen by parent
  #   rbx: 0000 0000 0003 0C63   #5 Wait for child pid result
  #   rcx: 0000 0000 0003 0C60   #6 Pid of parent

    if ($r =~ m(r8:( 0000){4}.*r9:(.*)\s{5,}r10:(.*)\s{5,}rax:(.*)\s{5,}rbx:(.*)\s{5,}rcx:(.*)\s{2,})s)
     {ok $2 eq $4;
      ok $2 eq $5;
      ok $3 eq $6;
      ok $2 gt $6;
     }

GetUid()

Get userid of current process.

Example:

  if (!onGitHub) {

WaitPid()

Wait for the pid in rax to complete.

Example:

    Fork;                                                                         # Fork

    Test rax,rax;
    IfNz                                                                          # Parent
    Then
     {Mov rbx, rax;

      WaitPid;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

      GetPid;                                                                     # Pid of parent as seen in parent
      Mov rcx,rax;
      PrintOutRegisterInHex rax, rbx, rcx;
     },
    Else                                                                          # Child
     {Mov r8,rax;
      GetPid;                                                                     # Child pid as seen in child
      Mov r9,rax;
      GetPPid;                                                                    # Parent pid as seen in child
      Mov r10,rax;
      PrintOutRegisterInHex r8, r9, r10;
     };

    my $r = Assemble(avx512=>0);

  #    r8: 0000 0000 0000 0000   #1 Return from fork as seen by child
  #    r9: 0000 0000 0003 0C63   #2 Pid of child
  #   r10: 0000 0000 0003 0C60   #3 Pid of parent from child
  #   rax: 0000 0000 0003 0C63   #4 Return from fork as seen by parent
  #   rbx: 0000 0000 0003 0C63   #5 Wait for child pid result
  #   rcx: 0000 0000 0003 0C60   #6 Pid of parent

    if ($r =~ m(r8:( 0000){4}.*r9:(.*)\s{5,}r10:(.*)\s{5,}rax:(.*)\s{5,}rbx:(.*)\s{5,}rcx:(.*)\s{2,})s)
     {ok $2 eq $4;
      ok $2 eq $5;
      ok $3 eq $6;
      ok $2 gt $6;
     }

ReadTimeStampCounter()

Read the time stamp counter and return the time in nanoseconds in rax.

Example:

    for(1..10)

     {ReadTimeStampCounter;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

      PrintOutRegisterInHex rax;
     }

    my @s = split /
/, Assemble(avx512=>0);
    my @S = sort @s;
    is_deeply \@s, \@S;

Memory

Allocate and print memory

PrintOutMemoryInHex()

Dump memory from the address in rax for the length in rdi on stdout.

Example:

    Mov rax, 0x07654321;
    Shl rax, 32;
    Or  rax, 0x07654321;
    PushR rax;

    PrintOutRaxInHex;
    PrintOutNL;
    PrintOutRaxInReverseInHex;
    PrintOutNL;

    Mov rax, rsp;
    Mov rdi, 8;

    PrintOutMemoryInHex;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    PrintOutNL;
    PopR rax;

    Mov rax, 4096;
    PushR rax;
    Mov rax, rsp;
    Mov rdi, 8;

    PrintOutMemoryInHex;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    PrintOutNL;
    PopR rax;

    ok Assemble eq => <<END, avx512=>0;
  .765 4321 .765 4321
  2143 65.7 2143 65.7
  2143 65.7 2143 65.7
  ..10 .... .... ....
  END

PrintOutMemoryInHexNL()

Dump memory from the address in rax for the length in rdi and then print a new line.

Example:

    my $N = 256;
    my $s = Rb 0..$N-1;
    my $a = AllocateMemory K size => $N;
    CopyMemory(V(source => $s), $a, K(size => $N));

    my $b = AllocateMemory K size => $N;
    CopyMemory($a, $b, K size => $N);

    $b->setReg(rax);
    Mov rdi, $N;
    PrintOutMemory_InHexNL;

    ok Assemble eq => <<END, avx512=>0;
  __.1 .2.3 .4.5 .6.7  .8.9 .A.B .C.D .E.F  1011 1213 1415 1617  1819 1A1B 1C1D 1E1F  2021 2223 2425 2627  2829 2A2B 2C2D 2E2F  3031 3233 3435 3637  3839 3A3B 3C3D 3E3F  4041 4243 4445 4647  4849 4A4B 4C4D 4E4F  5051 5253 5455 5657  5859 5A5B 5C5D 5E5F  6061 6263 6465 6667  6869 6A6B 6C6D 6E6F  7071 7273 7475 7677  7879 7A7B 7C7D 7E7F  8081 8283 8485 8687  8889 8A8B 8C8D 8E8F  9091 9293 9495 9697  9899 9A9B 9C9D 9E9F  A0A1 A2A3 A4A5 A6A7  A8A9 AAAB ACAD AEAF  B0B1 B2B3 B4B5 B6B7  B8B9 BABB BCBD BEBF  C0C1 C2C3 C4C5 C6C7  C8C9 CACB CCCD CECF  D0D1 D2D3 D4D5 D6D7  D8D9 DADB DCDD DEDF  E0E1 E2E3 E4E5 E6E7  E8E9 EAEB ECED EEEF  F0F1 F2F3 F4F5 F6F7  F8F9 FAFB FCFD FEFF
  END

PrintOutMemory_InHex()

Dump memory from the address in rax for the length in rdi on stdout.

Example:

    K(loop => 8+1)->for(sub
     {my ($index, $start, $next, $end) = @_;
      $index->setReg(15);
      Push r15;
     });

    Mov rax, rsp;
    Mov rdi, 8*9;
    PrintOutMemory_InHexNL;
    ClearMemory(V(address => rax), K(size => 8*9));

    PrintOutMemory_InHex;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    PrintOutNL;

    ok Assemble eq => <<END;
  .8__ ____ ____ ____  .7__ ____ ____ ____  .6__ ____ ____ ____  .5__ ____ ____ ____  .4__ ____ ____ ____  .3__ ____ ____ ____  .2__ ____ ____ ____  .1__ ____ ____ ____  ____ ____ ____ ____
  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  END

PrintOutMemory_InHexNL()

Dump memory from the address in rax for the length in rdi and then print a new line.

Example:

    K(loop => 8+1)->for(sub
     {my ($index, $start, $next, $end) = @_;
      $index->setReg(15);
      Push r15;
     });

    Mov rax, rsp;
    Mov rdi, 8*9;

    PrintOutMemory_InHexNL;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    ClearMemory(V(address => rax), K(size => 8*9));
    PrintOutMemory_InHex;
    PrintOutNL;

    ok Assemble eq => <<END;
  .8__ ____ ____ ____  .7__ ____ ____ ____  .6__ ____ ____ ____  .5__ ____ ____ ____  .4__ ____ ____ ____  .3__ ____ ____ ____  .2__ ____ ____ ____  .1__ ____ ____ ____  ____ ____ ____ ____
  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  END

PrintOutMemory()

Print the memory addressed by rax for a length of rdi on stdout.

Example:

    Comment "Print a string from memory";
    my $s = "Hello World";
    Mov rax, Rs($s);
    Mov rdi, length $s;

    PrintOutMemory;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    Exit(0);

    ok Assemble(avx512=>0) =~ m(Hello World);

PrintOutMemoryNL()

Print the memory addressed by rax for a length of rdi followed by a new line on stdout.

Example:

    my $s = Rs("Hello World

Hello Skye"); my $l = StringLength(my $t = V string => $s); $t->setReg(rax); $l->setReg(rdi);

    PrintOutMemoryNL;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲


    ok Assemble eq => <<END, avx512=>0;
  Hello World

  Hello Skye
  END

AllocateMemory($size)

Allocate the variable specified amount of memory via mmap and return its address as a variable.

     Parameter  Description
  1  $size      Size as a variable

Example:

    my $N = K size => 2048;
    my $q = Rs('a'..'p');

    my $address = AllocateMemory $N;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲


    Vmovdqu8 xmm0, "[$q]";
    $address->setReg(rax);
    Vmovdqu8 "[rax]", xmm0;
    Mov rdi, 16;
    PrintOutMemory;
    PrintOutNL;

    FreeMemory $address, $N;

    ok Assemble eq => <<END;
  abcdefghijklmnop
  END

    my $N = K size => 4096;                                                       # Size of the initial allocation which should be one or more pages


    my $A = AllocateMemory $N;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲


    ClearMemory($A, $N);

    $A->setReg(rax);
    Mov rdi, 128;
    PrintOutMemory_InHexNL;

    FreeMemory $A, $N;

    ok Assemble eq => <<END;
  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  END

    my $N = 256;
    my $s = Rb 0..$N-1;

    my $a = AllocateMemory K size => $N;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    CopyMemory(V(source => $s), $a, K(size => $N));


    my $b = AllocateMemory K size => $N;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    CopyMemory($a, $b, K size => $N);

    $b->setReg(rax);
    Mov rdi, $N;
    PrintOutMemory_InHexNL;

    ok Assemble eq => <<END, avx512=>0;
  __.1 .2.3 .4.5 .6.7  .8.9 .A.B .C.D .E.F  1011 1213 1415 1617  1819 1A1B 1C1D 1E1F  2021 2223 2425 2627  2829 2A2B 2C2D 2E2F  3031 3233 3435 3637  3839 3A3B 3C3D 3E3F  4041 4243 4445 4647  4849 4A4B 4C4D 4E4F  5051 5253 5455 5657  5859 5A5B 5C5D 5E5F  6061 6263 6465 6667  6869 6A6B 6C6D 6E6F  7071 7273 7475 7677  7879 7A7B 7C7D 7E7F  8081 8283 8485 8687  8889 8A8B 8C8D 8E8F  9091 9293 9495 9697  9899 9A9B 9C9D 9E9F  A0A1 A2A3 A4A5 A6A7  A8A9 AAAB ACAD AEAF  B0B1 B2B3 B4B5 B6B7  B8B9 BABB BCBD BEBF  C0C1 C2C3 C4C5 C6C7  C8C9 CACB CCCD CECF  D0D1 D2D3 D4D5 D6D7  D8D9 DADB DCDD DEDF  E0E1 E2E3 E4E5 E6E7  E8E9 EAEB ECED EEEF  F0F1 F2F3 F4F5 F6F7  F8F9 FAFB FCFD FEFF
  END

FreeMemory($address, $size)

Free memory specified by variables.

     Parameter  Description
  1  $address   Variable address of memory
  2  $size      Variable size of memory

Example:

    my $N = K size => 2048;
    my $q = Rs('a'..'p');
    my $address = AllocateMemory $N;

    Vmovdqu8 xmm0, "[$q]";
    $address->setReg(rax);
    Vmovdqu8 "[rax]", xmm0;
    Mov rdi, 16;
    PrintOutMemory;
    PrintOutNL;


    FreeMemory $address, $N;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲


    ok Assemble eq => <<END;
  abcdefghijklmnop
  END

    my $N = K size => 4096;                                                       # Size of the initial allocation which should be one or more pages

    my $A = AllocateMemory $N;

    ClearMemory($A, $N);

    $A->setReg(rax);
    Mov rdi, 128;
    PrintOutMemory_InHexNL;


    FreeMemory $A, $N;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲


    ok Assemble eq => <<END;
  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  END

ClearMemory($address, $size)

Clear memory with a variable address and variable length.

     Parameter  Description
  1  $address   Address of memory as a variable
  2  $size      Size of memory as a variable

Example:

    K(loop => 8+1)->for(sub
     {my ($index, $start, $next, $end) = @_;
      $index->setReg(15);
      Push r15;
     });

    Mov rax, rsp;
    Mov rdi, 8*9;
    PrintOutMemory_InHexNL;

    ClearMemory(V(address => rax), K(size => 8*9));  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    PrintOutMemory_InHex;
    PrintOutNL;

    ok Assemble eq => <<END;
  .8__ ____ ____ ____  .7__ ____ ____ ____  .6__ ____ ____ ____  .5__ ____ ____ ____  .4__ ____ ____ ____  .3__ ____ ____ ____  .2__ ____ ____ ____  .1__ ____ ____ ____  ____ ____ ____ ____
  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  END

    my $N = K size => 4096;                                                       # Size of the initial allocation which should be one or more pages

    my $A = AllocateMemory $N;


    ClearMemory($A, $N);  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲


    $A->setReg(rax);
    Mov rdi, 128;
    PrintOutMemory_InHexNL;

    FreeMemory $A, $N;

    ok Assemble eq => <<END;
  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  END

CopyMemory($source, $target, $size)

Copy memory.

     Parameter  Description
  1  $source    Source address variable
  2  $target    Target address variable
  3  $size      Length variable

Example:

    my $s = Rb 0; Rb 1; Rw 2; Rd 3;  Rq 4;
    my $t = Db 0; Db 1; Dw 2; Dd 3;  Dq 4;

    Vmovdqu8 xmm0, "[$s]";
    Vmovdqu8 xmm1, "[$t]";
    PrintOutRegisterInHex xmm0;
    PrintOutRegisterInHex xmm1;
    Sub rsp, 16;

    Mov rax, rsp;                                                                 # Copy memory, the target is addressed by rax, the length is in rdi, the source is addressed by rsi
    Mov rdi, 16;
    Mov rsi, $s;

    CopyMemory(V(source => rsi), V(target => rax), V size => rdi);  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    PrintOutMemory_InHexNL;

    ok Assemble eq => <<END;
    xmm0: .... .... .... ...4  .... ...3 ...2 .1..
    xmm1: .... .... .... ...4  .... ...3 ...2 .1..
  __.1 .2__ .3__ ____  .4__ ____ ____ ____
  END

    my $N = 256;
    my $s = Rb 0..$N-1;
    my $a = AllocateMemory K size => $N;

    CopyMemory(V(source => $s), $a, K(size => $N));  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲


    my $b = AllocateMemory K size => $N;

    CopyMemory($a, $b, K size => $N);  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲


    $b->setReg(rax);
    Mov rdi, $N;
    PrintOutMemory_InHexNL;

    ok Assemble eq => <<END, avx512=>0;
  __.1 .2.3 .4.5 .6.7  .8.9 .A.B .C.D .E.F  1011 1213 1415 1617  1819 1A1B 1C1D 1E1F  2021 2223 2425 2627  2829 2A2B 2C2D 2E2F  3031 3233 3435 3637  3839 3A3B 3C3D 3E3F  4041 4243 4445 4647  4849 4A4B 4C4D 4E4F  5051 5253 5455 5657  5859 5A5B 5C5D 5E5F  6061 6263 6465 6667  6869 6A6B 6C6D 6E6F  7071 7273 7475 7677  7879 7A7B 7C7D 7E7F  8081 8283 8485 8687  8889 8A8B 8C8D 8E8F  9091 9293 9495 9697  9899 9A9B 9C9D 9E9F  A0A1 A2A3 A4A5 A6A7  A8A9 AAAB ACAD AEAF  B0B1 B2B3 B4B5 B6B7  B8B9 BABB BCBD BEBF  C0C1 C2C3 C4C5 C6C7  C8C9 CACB CCCD CECF  D0D1 D2D3 D4D5 D6D7  D8D9 DADB DCDD DEDF  E0E1 E2E3 E4E5 E6E7  E8E9 EAEB ECED EEEF  F0F1 F2F3 F4F5 F6F7  F8F9 FAFB FCFD FEFF
  END

CopyMemory64($source, $target, $size)

Copy memory in 64 byte blocks.

     Parameter  Description
  1  $source    Source address variable
  2  $target    Target address variable
  3  $size      Number of 64 byte blocks to move

Example:

    my ($s, $l) =

Files

Interact with the operating system via files.

OpenRead()

Open a file, whose name is addressed by rax, for read and return the file descriptor in rax.

Example:

    Mov rax, Rs($0);                                                              # File to read

    OpenRead;                                                                     # Open file  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    PrintOutRegisterInHex rax;
    CloseFile;                                                                    # Close file
    PrintOutRegisterInHex rax;

    Mov rax, Rs(my $f = "zzzTemporaryFile.txt");                                  # File to write
    OpenWrite;                                                                    # Open file
    CloseFile;                                                                    # Close file

    ok Assemble eq => <<END;
     rax: .... .... .... ...3
     rax: .... .... .... ...0
  END
    ok -e $f;                                                                     # Created file
    unlink $f;

OpenWrite()

Create the file named by the terminated string addressed by rax for write. The file handle will be returned in rax.

Example:

  if (1)
   {my $s = "zzzCreated.data";
    my $f = Rs $s;
    Mov rax, $f;

    OpenWrite;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    Mov r15, rax;
    Mov rax, $f;
    Mov rdi, length $s;
    PrintMemory r15;
    CloseFile;
    ok Assemble eq=><<END, avx512=>1;
  END
    ok -e $s;
    unlink $s;
   }

    Mov rax, Rs($0);                                                              # File to read
    OpenRead;                                                                     # Open file
    PrintOutRegisterInHex rax;
    CloseFile;                                                                    # Close file
    PrintOutRegisterInHex rax;

    Mov rax, Rs(my $f = "zzzTemporaryFile.txt");                                  # File to write

    OpenWrite;                                                                    # Open file  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    CloseFile;                                                                    # Close file

    ok Assemble eq => <<END;
     rax: .... .... .... ...3
     rax: .... .... .... ...0
  END
    ok -e $f;                                                                     # Created file
    unlink $f;

CloseFile()

Close the file whose descriptor is in rax.

Example:

  if (1)
   {my $s = "zzzCreated.data";
    my $f = Rs $s;
    Mov rax, $f;
    OpenWrite;
    Mov r15, rax;
    Mov rax, $f;
    Mov rdi, length $s;
    PrintMemory r15;

    CloseFile;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    ok Assemble eq=><<END, avx512=>1;
  END
    ok -e $s;
    unlink $s;
   }

    Mov rax, Rs($0);                                                              # File to read
    OpenRead;                                                                     # Open file
    PrintOutRegisterInHex rax;

    CloseFile;                                                                    # Close file  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    PrintOutRegisterInHex rax;

    Mov rax, Rs(my $f = "zzzTemporaryFile.txt");                                  # File to write
    OpenWrite;                                                                    # Open file

    CloseFile;                                                                    # Close file  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲


    ok Assemble eq => <<END;
     rax: .... .... .... ...3
     rax: .... .... .... ...0
  END
    ok -e $f;                                                                     # Created file
    unlink $f;

StatSize()

Stat a file whose name is addressed by rax to get its size in rax.

Example:

    Mov rax, Rs $0;                                                               # File to stat

    StatSize;                                                                     # Stat the file  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    PrintOutRegisterInHex rax;

    my $r = Assemble(avx512=>0) =~ s( ) ()gsr;
    if ($r =~ m(rax:([0-9a-f]{16}))is)                                            # Compare file size obtained with that from fileSize()
     {is_deeply $1, sprintf("%016X", fileSize($0));
     }

ReadChar()

Read a character from stdin and return it in rax else return -1 in rax if no character was read.

Example:

    my $e = q(readChar);

    ForEver
     {my ($start, $end) = @_;

      ReadChar;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

      Cmp rax, 0xa;
      Jle $end;
      PrintOutRaxAsChar;
      PrintOutRaxAsCharNL;
     };
    PrintOutNL;

    Assemble keep => $e;

    my $r = qx(echo "ABCDCBA" | ./$e);
    is_deeply $r, <<END;
  AA
  BB
  CC
  DD
  CC
  BB
  AA

  END
    unlink $e;

ReadLine()

Reads up to 8 characters followed by a terminating return and place them into rax.

Example:

    my $e = q(readLine);
    my $f = writeTempFile("hello
world
");


    ReadLine;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    PrintOutRaxAsTextNL;

    ReadLine;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    PrintOutRaxAsTextNL;

    Assemble keep => $e;

    is_deeply scalar(qx(./$e < $f)), <<END;
  hello
  world
  END
    unlink $f;
  }

  #latest:
  if (1) {
    my $e = q(readInteger);
    my $f = writeTempFile("11
22
");

    ReadInteger;
    Shl rax, 1;
    PrintOutRaxInDecNL;
    ReadInteger;
    Shl rax, 1;
    PrintOutRaxInDecNL;

    Assemble keep => $e;

    is_deeply scalar(qx(./$e < $f)), <<END;
  22
  44
  END

    unlink $e, $f;

ReadInteger()

Reads an integer in decimal and returns it in rax.

Example:

    my $e = q(readInteger);
    my $f = writeTempFile("11
22
");


    ReadInteger;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    Shl rax, 1;
    PrintOutRaxInDecNL;

    ReadInteger;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    Shl rax, 1;
    PrintOutRaxInDecNL;

    Assemble keep => $e;

    is_deeply scalar(qx(./$e < $f)), <<END;
  22
  44
  END

    unlink $e, $f;

ReadFile($File)

Read a file into memory.

     Parameter  Description
  1  $File      Variable addressing a zero terminated string naming the file to be read in by mapping it

Example:

  if (!!onGitHub) {

executeFileViaBash($file)

Execute the file named in a variable.

     Parameter  Description
  1  $file      File variable

Example:

  if (0 and !onGitHub) {                                                          # Execute the content of an area

unlinkFile($file)

Unlink the named file.

     Parameter  Description
  1  $file      File variable

Example:

  if (0 and !onGitHub) {                                                          # Execute the content of an area

Hash functions

Hash functions

Hash()

Hash a string addressed by rax with length held in rdi and return the hash code in r15.

Example:

  # Make hash accept parameters at:

    Mov rax, "[rbp+24]";                                                          # Address of string as parameter
    StringLength(V string => rax)->setReg(rdi);                                   # Length of string to hash

    Hash();                                                                       # Hash string  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲


    PrintOutRegisterInHex r15;

    my $e = Assemble keep => 'hash';                                              # Assemble to the specified file name
    say STDERR qx($e "");
    say STDERR qx($e "a");
    ok qx($e "")  =~ m(r15: 0000 3F80 0000 3F80);                                 # Test well known hashes
    ok qx($e "a") =~ m(r15: 0000 3F80 C000 45B2);


    if (0)                                                                        # Hash various strings  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

     {my %r; my %f; my $count = 0;
      my $N = RegisterSize zmm0;

      if (1)                                                                      # Fixed blocks
       {for my $l(qw(a ab abc abcd), 'a a', 'a  a')
         {for my $i(1..$N)
           {my $t = $l x $i;
            last if $N < length $t;
            my $s = substr($t.(' ' x $N), 0, $N);
            next if $f{$s}++;
            my $r = qx($e "$s");
            say STDERR "$count  $r";
            if ($r =~ m(^.*r15:\s*(.*)$)m)
             {push $r{$1}->@*, $s;
              ++$count;
             }
           }
         }
       }

      if (1)                                                                      # Variable blocks
       {for my $l(qw(a ab abc abcd), '', 'a a', 'a  a')
         {for my $i(1..$N)
           {my $t = $l x $i;
            next if $f{$t}++;
            my $r = qx($e "$t");
            say STDERR "$count  $r";
            if ($r =~ m(^.*r15:\s*(.*)$)m)
             {push $r{$1}->@*, $t;
              ++$count;
             }
           }
         }
       }
      for my $r(keys %r)
       {delete $r{$r} if $r{$r}->@* < 2;
       }

      say STDERR dump(\%r);
      say STDERR "Keys hashed: ", $count;
      confess "Duplicates : ",  scalar keys(%r);
     }

    unlink 'hash';

Unicode

Convert between utf8 and utf32

GetNextUtf8CharAsUtf32($in)

Get the next UTF-8 encoded character from the addressed memory and return it as a UTF-32 character as a variable along with the size of the input character and a variable indicating the success - 1 - or failure - 0 - of the operation.

     Parameter  Description
  1  $in        Address of utf8 character as a variable

Example:

    my ($out, $size, $fail);

    my $Chars = Rb(0x24, 0xc2, 0xa2, 0xc9, 0x91, 0xE2, 0x82, 0xAC, 0xF0, 0x90, 0x8D, 0x88);
    my $chars = V(chars => $Chars);


   ($out, $size, $fail) = GetNextUtf8CharAsUtf32 $chars+0;                        # Dollar               UTF-8 Encoding: 0x24                UTF-32 Encoding: 0x00000024  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    $out->out('out1 : ');
    $size->outNL(' size : ');


   ($out, $size, $fail) = GetNextUtf8CharAsUtf32 $chars+1;                        # Cents                UTF-8 Encoding: 0xC2 0xA2           UTF-32 Encoding: 0x000000a2  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    $out->out('out2 : ');     $size->outNL(' size : ');


   ($out, $size, $fail) = GetNextUtf8CharAsUtf32 $chars+3;                        # Alpha                UTF-8 Encoding: 0xC9 0x91           UTF-32 Encoding: 0x00000251  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    $out->out('out3 : ');     $size->outNL(' size : ');


   ($out, $size, $fail) = GetNextUtf8CharAsUtf32 $chars+5;                        # Euro                 UTF-8 Encoding: 0xE2 0x82 0xAC      UTF-32 Encoding: 0x000020AC  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    $out->out('out4 : ');     $size->outNL(' size : ');


   ($out, $size, $fail) = GetNextUtf8CharAsUtf32 $chars+8;                        # Gothic Letter Hwair  UTF-8 Encoding  0xF0 0x90 0x8D 0x88 UTF-32 Encoding: 0x00010348  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    $out->out('out5 : ');     $size->outNL(' size : ');

    my $statement = qq(𝖺
 𝑎𝑠𝑠𝑖𝑔𝑛 【【𝖻 𝐩𝐥𝐮𝐬 𝖼】】
AAAAAAAA);                        # A sample sentence to parse

    my $s = K(statement => Rutf8($statement));
    my $l = StringLength $s;

    my $address = AllocateMemory $l;                                              # Allocate enough memory for a copy of the string
    CopyMemory($s, $address, $l);


   ($out, $size, $fail) = GetNextUtf8CharAsUtf32 $address;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    $out->out('outA : ');     $size->outNL(' size : ');


   ($out, $size, $fail) = GetNextUtf8CharAsUtf32 $address+4;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    $out->out('outB : ');     $size->outNL(' size : ');


   ($out, $size, $fail) = GetNextUtf8CharAsUtf32 $address+5;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    $out->out('outC : ');     $size->outNL(' size : ');


   ($out, $size, $fail) = GetNextUtf8CharAsUtf32 $address+30;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    $out->out('outD : ');     $size->outNL(' size : ');


   ($out, $size, $fail) = GetNextUtf8CharAsUtf32 $address+35;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    $out->out('outE : ');     $size->outNL(' size : ');

    $address->printOutMemoryInHexNL($l);

    ok Assemble(debug => 0, eq => <<END, avx512=>0);
  out1 : .... .... .... ..24 size : .... .... .... ...1
  out2 : .... .... .... ..A2 size : .... .... .... ...2
  out3 : .... .... .... .251 size : .... .... .... ...2
  out4 : .... .... .... 20AC size : .... .... .... ...3
  out5 : .... .... ...1 .348 size : .... .... .... ...4
  outA : .... .... ...1 D5BA size : .... .... .... ...4
  outB : .... .... .... ...A size : .... .... .... ...1
  outC : .... .... .... ..20 size : .... .... .... ...1
  outD : .... .... .... ..20 size : .... .... .... ...1
  outE : .... .... .... ..10 size : .... .... .... ...2
  F09D 96BA .A20 F09D  918E F09D 91A0 F09D  91A0 F09D 9196 F09D  9194 F09D 919B 20E3  8090 E380 90F0 9D96  BB20 F09D 90A9 F09D  90A5 F09D 90AE F09D  90AC 20F0 9D96 BCE3  8091 E380 91.A 4141  4141 4141 4141 ....
  END

ConvertUtf8ToUtf32($a8, $s8)

Convert an allocated string of utf8 to an allocated string of utf32 and return its address and length.

     Parameter  Description
  1  $a8        Utf8 string address variable
  2  $s8        Utf8 length variable

Example:

    my ($out, $size, $fail);

    my $Chars = Rb(0x24, 0xc2, 0xa2, 0xc9, 0x91, 0xE2, 0x82, 0xAC, 0xF0, 0x90, 0x8D, 0x88);
    my $chars = V(chars => $Chars);

   ($out, $size, $fail) = GetNextUtf8CharAsUtf32 $chars+0;                        # Dollar               UTF-8 Encoding: 0x24                UTF-32 Encoding: 0x00000024
    $out->out('out1 : ');
    $size->outNL(' size : ');

   ($out, $size, $fail) = GetNextUtf8CharAsUtf32 $chars+1;                        # Cents                UTF-8 Encoding: 0xC2 0xA2           UTF-32 Encoding: 0x000000a2
    $out->out('out2 : ');     $size->outNL(' size : ');

   ($out, $size, $fail) = GetNextUtf8CharAsUtf32 $chars+3;                        # Alpha                UTF-8 Encoding: 0xC9 0x91           UTF-32 Encoding: 0x00000251
    $out->out('out3 : ');     $size->outNL(' size : ');

   ($out, $size, $fail) = GetNextUtf8CharAsUtf32 $chars+5;                        # Euro                 UTF-8 Encoding: 0xE2 0x82 0xAC      UTF-32 Encoding: 0x000020AC
    $out->out('out4 : ');     $size->outNL(' size : ');

   ($out, $size, $fail) = GetNextUtf8CharAsUtf32 $chars+8;                        # Gothic Letter Hwair  UTF-8 Encoding  0xF0 0x90 0x8D 0x88 UTF-32 Encoding: 0x00010348
    $out->out('out5 : ');     $size->outNL(' size : ');

    my $statement = qq(𝖺
 𝑎𝑠𝑠𝑖𝑔𝑛 【【𝖻 𝐩𝐥𝐮𝐬 𝖼】】
AAAAAAAA);                        # A sample sentence to parse

    my $s = K(statement => Rutf8($statement));
    my $l = StringLength $s;

    my $address = AllocateMemory $l;                                              # Allocate enough memory for a copy of the string
    CopyMemory($s, $address, $l);

   ($out, $size, $fail) = GetNextUtf8CharAsUtf32 $address;
    $out->out('outA : ');     $size->outNL(' size : ');

   ($out, $size, $fail) = GetNextUtf8CharAsUtf32 $address+4;
    $out->out('outB : ');     $size->outNL(' size : ');

   ($out, $size, $fail) = GetNextUtf8CharAsUtf32 $address+5;
    $out->out('outC : ');     $size->outNL(' size : ');

   ($out, $size, $fail) = GetNextUtf8CharAsUtf32 $address+30;
    $out->out('outD : ');     $size->outNL(' size : ');

   ($out, $size, $fail) = GetNextUtf8CharAsUtf32 $address+35;
    $out->out('outE : ');     $size->outNL(' size : ');

    $address->printOutMemoryInHexNL($l);

    ok Assemble(debug => 0, eq => <<END, avx512=>0);
  out1 : .... .... .... ..24 size : .... .... .... ...1
  out2 : .... .... .... ..A2 size : .... .... .... ...2
  out3 : .... .... .... .251 size : .... .... .... ...2
  out4 : .... .... .... 20AC size : .... .... .... ...3
  out5 : .... .... ...1 .348 size : .... .... .... ...4
  outA : .... .... ...1 D5BA size : .... .... .... ...4
  outB : .... .... .... ...A size : .... .... .... ...1
  outC : .... .... .... ..20 size : .... .... .... ...1
  outD : .... .... .... ..20 size : .... .... .... ...1
  outE : .... .... .... ..10 size : .... .... .... ...2
  F09D 96BA .A20 F09D  918E F09D 91A0 F09D  91A0 F09D 9196 F09D  9194 F09D 919B 20E3  8090 E380 90F0 9D96  BB20 F09D 90A9 F09D  90A5 F09D 90AE F09D  90AC 20F0 9D96 BCE3  8091 E380 91.A 4141  4141 4141 4141 ....
  END

C Strings

C strings are a series of bytes terminated by a zero byte.

StringLength($string)

Length of a zero terminated string.

     Parameter  Description
  1  $string    String

Example:

    my $s = Rs("Hello World

Hello Skye");

    my $l = StringLength(my $t = V string => $s);  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    $t->setReg(rax);
    $l->setReg(rdi);
    PrintOutMemoryNL;

    ok Assemble eq => <<END, avx512=>0;
  Hello World

  Hello Skye
  END


    StringLength(V string => Rs("abcd"))->outNL;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    Assemble eq => <<END, avx512=>0;
  size: .... .... .... ...4
  END

Areas

An area is single extensible block of memory which contains other data structures such as strings, arrays, trees within it.

Constructors

Construct an area either in memory or by reading it from a file or by incorporating it into an assembly.

CreateArea(%options)

Create an relocatable area and returns its address in rax. We add a chain header so that 64 byte blocks of memory can be freed and reused within the area.

     Parameter  Description
  1  %options   Free=>1 adds a free chain.

Example:

    my $a = CreateArea;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    $a->q('aa');
    $a->outNL;
    $a->ql('bb');
    $a->out;
    ok Assemble eq => <<END, avx512=>0;
  aa
  aabb
  END


    my $a = CreateArea;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲


    my $b = CreateArea;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    $a->q('aa');
    $b->q('bb');
    $a->out;
    PrintOutNL;
    $b->out;
    PrintOutNL;
    ok Assemble eq => <<END, avx512=>0;
  aa
  bb
  END


    my $a = CreateArea;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲


    my $b = CreateArea;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    $a->q('aa');
    $a->q('AA');
    $a->out;
    PrintOutNL;
    ok Assemble eq => <<END, avx512=>0;
  aaAA
  END


    my $a = CreateArea;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲


    my $b = CreateArea;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    $a->q('aa');
    $b->q('bb');
    $a->q('AA');
    $b->q('BB');
    $a->q('aa');
    $b->q('bb');
    $a->out;
    $b->out;
    PrintOutNL;
    ok Assemble eq => <<END, avx512=>0;
  aaAAaabbBBbb
  END


    my $a = CreateArea;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    $a->q('ab');

    my $b = CreateArea;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    $b->append($a);
    $b->append($a);
    $a->append($b);
    $b->append($a);
    $a->append($b);
    $b->append($a);
    $b->append($a);
    $b->append($a);
    $b->append($a);


    $a->out;   PrintOutNL;
    $b->outNL;
    my $sa = $a->used; $sa->outNL;
    my $sb = $b->used; $sb->outNL;
    $a->clear;
    my $sA = $a->used; $sA->outNL;
    my $sB = $b->used; $sB->outNL;

    ok Assemble eq => <<END, avx512=>0;
  abababababababab
  ababababababababababababababababababababababababababababababababababababab
  area used up: .... .... .... ..10
  area used up: .... .... .... ..4A
  area used up: .... .... .... ...0
  area used up: .... .... .... ..4A
  END

ReadArea($file)

Read an area stored in a file into memory and return an area descriptor for the area so created.

     Parameter  Description
  1  $file      Name of file to read

Example:

  if (1)
   {LoadZmm 0, 61..61+63;

    my $a = CreateArea;
    $a->appendZmm(0);
    $a->printOut(0x44, 2);
    $a->dump("AA");
    $a->write(my $f = "aaa.txt");


    my $A = ReadArea $f;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    $A->dump("BB");
    ok Assemble eq => <<END;
  AB
  AA
  Area     Size:     4096    Used:      128
  .... .... .... ...0 | __10 ____ ____ ____  80__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 3D3E 3F40 4142 4344  4546 4748 494A 4B4C  4D4E 4F50 5152 5354  5556 5758 595A 5B5C  5D5E 5F60 6162 6364  6566 6768 696A 6B6C  6D6E 6F70 7172 7374  7576 7778 797A 7B7C
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  BB
  Area     Size:     4096    Used:      128
  .... .... .... ...0 | __10 ____ ____ ____  80__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 3D3E 3F40 4142 4344  4546 4748 494A 4B4C  4D4E 4F50 5152 5354  5556 5758 595A 5B5C  5D5E 5F60 6162 6364  6566 6768 696A 6B6C  6D6E 6F70 7172 7374  7576 7778 797A 7B7C
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  END
   }

loadAreaIntoAssembly($file)

Load an area into the current assembly and return a descriptor for it.

     Parameter  Description
  1  $file      File containing an area

Example:

    unlink my $f = q(zzzArea.data);
    my $sub = "abcd";

    my $s = Subroutine
     {my ($p, $s, $sub) = @_;

      my $a = Subroutine
       {my ($p, $s, $sub) = @_;
        Mov rax, 0x111;
        PrintOutRegisterInHex rax;
       } name => 'a', parameters=>[qw(a)];

      my $b = Subroutine
       {my ($p, $s, $sub) = @_;
        $$p{a}->setReg(rax);
        PrintOutRegisterInHex rax;
       } name => 'b', parameters=>[qw(a)];

      PrintOutStringNL "abcd";
      $$p{a}->outNL;
     } name => $sub, parameters=>[qw(a)], export => $f;                           # Export the library

    my $t = Subroutine {} name => "t", parameters=>[qw(a)];

    my sub mapSubroutines                                                         # Create a string tree mapping subroutine names to subroutine numbers
     {my $n = CreateArea->CreateTree(stringTree=>1);
      $n->putKeyString(constantString("abcd"), K offset => 0);
      $n->putKeyString(constantString("a"),    K offset => 1);
      $n->putKeyString(constantString("b"),    K offset => 2);
      $n
     }

    if (1)                                                                        # Read a library and call the subroutines there-in
     {my $a = ReadArea $f;                                                        # Reload the area elsewhere
      my ($inter, $symbols) = $a->readLibraryHeader(mapSubroutines);              # Create a tree mapping the subroutine numbers to subroutine offsets

      $inter->find(K sub => 1);                                                   # Look up the offset of the first subroutine

      If $inter->found > 0,
      Then
       {$t->call(parameters=>{a => K key => 0x9999},                              # Call position independent code
                              override => $a->address + $inter->data);
       },
      Else
       {PrintOutStringNL "Unable to locate subroutine 'a'";
       };

      $inter->find(K sub => 2);                                                   # Look  up the offset of the second subroutine

      If $inter->found > 0,
      Then
       {$t->call(parameters=>{a        => K key => 0x9999},                       # Call position independent code
                              override => $a->address + $inter->data);
       },
      Else
       {PrintOutStringNL "Unable to locate subroutine 'b'";
       };
     }

    ok Assemble eq=><<END, avx512=>1;
     rax: .... .... .... .111
     rax: .... .... .... 9999
  END
    ok -e $f;                                                                     # Confirm we have created the library

    if (1)                                                                        # Include a library in a program

     {my $a = loadAreaIntoAssembly $f;                                            # Load the library from the file it was exported to  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

      my ($inter, $subroutines) = $a->readLibraryHeader(mapSubroutines);          # Create a tree mapping the subroutine numbers to subroutine offsets

      $inter->find(K sub => 0);                                                   # Look  up the offset of the containing subroutine
      $t->call(parameters=>{a        => K key => 0x6666},                         # Call position independent code
                            override => $a->address + $inter->data);

      $inter->find(K sub => 1);                                                   # Look  up the offset of the first subroutine
      $t->call(parameters=>{a        => K key => 0x7777},                         # Call position independent code
                            override => $a->address + $inter->data);

      $inter->find(K sub => 2);                                                   # Look  up the offset of the second subroutine
      $t->call(parameters=>{a        => K key => 0x8888},                         # Call position independent code
                            override => $a->address + $inter->data);
     }

    ok Assemble eq=><<END, avx512=>1;
  abcd
  a: .... .... .... 6666
     rax: .... .... .... .111
     rax: .... .... .... 8888
  END

    unlink $f;

Nasm::X86::Area::free($area)

Free an area.

     Parameter  Description
  1  $area      Area descriptor

Example:

    my $a = CreateArea;

    $a->q("a" x 255);
    $a->used->outNL;
    $a->size->outNL;
    $a->dump('A');
    $a->clear;
    $a->used->outNL;
    $a->size->outNL;
    $a->dump('B');

    $a->q("a" x 4095);
    $a->used->outNL;
    $a->size->outNL;
    $a->dump('C');
    $a->clear;
    $a->used->outNL;
    $a->size->outNL;
    $a->dump('D');

    $a->free;

    ok Assemble(debug => 0, eq => <<END, avx512=>1);
  area used up: .... .... .... ..FF
  size of area: .... .... .... 10..
  A
  Area     Size:     4096    Used:      319
  .... .... .... ...0 | __10 ____ ____ ____  3F.1 ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161
  .... .... .... ..80 | 6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161
  .... .... .... ..C0 | 6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161
  area used up: .... .... .... ...0
  size of area: .... .... .... 10..
  B
  Area     Size:     4096    Used:       64
  .... .... .... ...0 | __10 ____ ____ ____  40__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161
  .... .... .... ..80 | 6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161
  .... .... .... ..C0 | 6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161
  area used up: .... .... .... .FFF
  size of area: .... .... .... 20..
  C
  Area     Size:     8192    Used:     4159
  .... .... .... ...0 | __20 ____ ____ ____  3F10 ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161
  .... .... .... ..80 | 6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161
  .... .... .... ..C0 | 6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161
  area used up: .... .... .... ...0
  size of area: .... .... .... 20..
  D
  Area     Size:     8192    Used:       64
  .... .... .... ...0 | __20 ____ ____ ____  40__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161
  .... .... .... ..80 | 6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161
  .... .... .... ..C0 | 6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161
  END

Memory

Manage memory controlled by an area.

Nasm::X86::Area::used($area)

Return the currently used size of an area as a variable.

     Parameter  Description
  1  $area      Area descriptor

Example:

    my $a = CreateArea;

    $a->q("a" x 255);
    $a->used->outNL;
    $a->size->outNL;
    $a->dump('A');
    $a->clear;
    $a->used->outNL;
    $a->size->outNL;
    $a->dump('B');

    $a->q("a" x 4095);
    $a->used->outNL;
    $a->size->outNL;
    $a->dump('C');
    $a->clear;
    $a->used->outNL;
    $a->size->outNL;
    $a->dump('D');

    $a->free;

    ok Assemble(debug => 0, eq => <<END, avx512=>1);
  area used up: .... .... .... ..FF
  size of area: .... .... .... 10..
  A
  Area     Size:     4096    Used:      319
  .... .... .... ...0 | __10 ____ ____ ____  3F.1 ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161
  .... .... .... ..80 | 6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161
  .... .... .... ..C0 | 6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161
  area used up: .... .... .... ...0
  size of area: .... .... .... 10..
  B
  Area     Size:     4096    Used:       64
  .... .... .... ...0 | __10 ____ ____ ____  40__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161
  .... .... .... ..80 | 6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161
  .... .... .... ..C0 | 6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161
  area used up: .... .... .... .FFF
  size of area: .... .... .... 20..
  C
  Area     Size:     8192    Used:     4159
  .... .... .... ...0 | __20 ____ ____ ____  3F10 ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161
  .... .... .... ..80 | 6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161
  .... .... .... ..C0 | 6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161
  area used up: .... .... .... ...0
  size of area: .... .... .... 20..
  D
  Area     Size:     8192    Used:       64
  .... .... .... ...0 | __20 ____ ____ ____  40__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161
  .... .... .... ..80 | 6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161
  .... .... .... ..C0 | 6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161
  END

Nasm::X86::Area::size($area)

Get the size of an area as a variable.

     Parameter  Description
  1  $area      Area descriptor

Example:

    my $a = CreateArea;

    $a->q("a" x 255);
    $a->used->outNL;
    $a->size->outNL;
    $a->dump('A');
    $a->clear;
    $a->used->outNL;
    $a->size->outNL;
    $a->dump('B');

    $a->q("a" x 4095);
    $a->used->outNL;
    $a->size->outNL;
    $a->dump('C');
    $a->clear;
    $a->used->outNL;
    $a->size->outNL;
    $a->dump('D');

    $a->free;

    ok Assemble(debug => 0, eq => <<END, avx512=>1);
  area used up: .... .... .... ..FF
  size of area: .... .... .... 10..
  A
  Area     Size:     4096    Used:      319
  .... .... .... ...0 | __10 ____ ____ ____  3F.1 ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161
  .... .... .... ..80 | 6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161
  .... .... .... ..C0 | 6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161
  area used up: .... .... .... ...0
  size of area: .... .... .... 10..
  B
  Area     Size:     4096    Used:       64
  .... .... .... ...0 | __10 ____ ____ ____  40__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161
  .... .... .... ..80 | 6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161
  .... .... .... ..C0 | 6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161
  area used up: .... .... .... .FFF
  size of area: .... .... .... 20..
  C
  Area     Size:     8192    Used:     4159
  .... .... .... ...0 | __20 ____ ____ ____  3F10 ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161
  .... .... .... ..80 | 6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161
  .... .... .... ..C0 | 6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161
  area used up: .... .... .... ...0
  size of area: .... .... .... 20..
  D
  Area     Size:     8192    Used:       64
  .... .... .... ...0 | __20 ____ ____ ____  40__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161
  .... .... .... ..80 | 6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161
  .... .... .... ..C0 | 6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161
  END

Nasm::X86::Area::makeReadOnly($area)

Make an area read only.

     Parameter  Description
  1  $area      Area descriptor

Example:

    my $s = CreateArea;                                                           # Create an area
    $s->q("Hello");                                                               # Write data to area
    $s->makeReadOnly;                                                             # Make area read only - tested above
    $s->makeWriteable;                                                            # Make area writable again
    $s->q(" World");                                                              # Try to write to area
    $s->outNL;

    ok Assemble(avx512=>0, eq => <<END);
  Hello World
  END

Nasm::X86::Area::makeWriteable($area)

Make an area writable.

     Parameter  Description
  1  $area      Area descriptor

Example:

    my $s = CreateArea;                                                           # Create an area
    $s->q("Hello");                                                               # Write data to area
    $s->makeReadOnly;                                                             # Make area read only - tested above
    $s->makeWriteable;                                                            # Make area writable again
    $s->q(" World");                                                              # Try to write to area
    $s->outNL;

    ok Assemble(avx512=>0, eq => <<END);
  Hello World
  END

Alloc/Free

Allocate and free memory in an area, either once only but in variable size blocks or reusably in zmm sized blocks via the free block chain.

Nasm::X86::Area::allocate($area, $Size)

Allocate the variable amount of space in the variable addressed area and return the offset of the allocation in the area as a variable.

     Parameter  Description
  1  $area      Area descriptor
  2  $Size      Variable amount of allocation

Example:

    my $s = CreateArea;
    my $o1 = $s->allocate(0x20);
    my $o2 = $s->allocate(0x30);
    my $o3 = $s->allocate(0x10);
    $o1->outNL;
    $o2->outNL;
    $o3->outNL;

    ok Assemble eq => <<END, avx512=>0;
  offset: .... .... .... ..40
  offset: .... .... .... ..60
  offset: .... .... .... ..90
  END

Nasm::X86::Area::allocZmmBlock($area)

Allocate a block to hold a zmm register in the specified area and return the offset of the block as a variable.

     Parameter  Description
  1  $area      Area

Example:

    my $a = CreateArea;

    my $m = $a->allocZmmBlock;
    K(K => Rd(1..16))->loadZmm(31);

    $a->putZmmBlock  ($m, 31);
    $a->dump("A");

    $a->getZmmBlock  ($m, 30);
    $a->clearZmmBlock($m);
    $a->getZmmBlock  ($m, 29);

    $a->clearZmmBlock($m);
    PrintOutRegisterInHex 31, 30, 29;

    ok Assemble eq => <<END, avx512=>1;
  A
  Area     Size:     4096    Used:      128
  .... .... .... ...0 | __10 ____ ____ ____  80__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | .1__ ____ .2__ ____  .3__ ____ .4__ ____  .5__ ____ .6__ ____  .7__ ____ .8__ ____  .9__ ____ .A__ ____  .B__ ____ .C__ ____  .D__ ____ .E__ ____  .F__ ____ 10__ ____
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
   zmm31: .... ..10 .... ...F  .... ...E .... ...D - .... ...C .... ...B  .... ...A .... ...9 + .... ...8 .... ...7  .... ...6 .... ...5 - .... ...4 .... ...3  .... ...2 .... ...1
   zmm30: .... ..10 .... ...F  .... ...E .... ...D - .... ...C .... ...B  .... ...A .... ...9 + .... ...8 .... ...7  .... ...6 .... ...5 - .... ...4 .... ...3  .... ...2 .... ...1
   zmm29: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0
  END

    my $a = CreateArea;

    K(loop => 3)->for(sub
     {my ($i, $start, $next, $end) = @_;
      $i->outNL;
      my $m1 = $a->allocZmmBlock;
      my $m2 = $a->allocZmmBlock;

      K(K => Rd(1..16))->loadZmm(31);
      K(K => Rd(17..32))->loadZmm(30);
      PrintOutRegisterInHex 31, 30;

      $a->putZmmBlock($m1, 31);
      $a->putZmmBlock($m2, 30);
      $a->dump("A");

      $a->getZmmBlock($m1, 30);
      $a->getZmmBlock($m2, 31);
      PrintOutRegisterInHex 31, 30;

      $a->clearZmmBlock($m1);
      $a->freeZmmBlock($m1);
      $a->dump("B");

      $a->freeZmmBlock($m2);
      $a->dump("C");
     });

    ok Assemble eq => <<END, avx512=>1;
  index: .... .... .... ...0
   zmm31: .... ..10 .... ...F  .... ...E .... ...D - .... ...C .... ...B  .... ...A .... ...9 + .... ...8 .... ...7  .... ...6 .... ...5 - .... ...4 .... ...3  .... ...2 .... ...1
   zmm30: .... ..20 .... ..1F  .... ..1E .... ..1D - .... ..1C .... ..1B  .... ..1A .... ..19 + .... ..18 .... ..17  .... ..16 .... ..15 - .... ..14 .... ..13  .... ..12 .... ..11
  A
  Area     Size:     4096    Used:      192
  .... .... .... ...0 | __10 ____ ____ ____  C0__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | .1__ ____ .2__ ____  .3__ ____ .4__ ____  .5__ ____ .6__ ____  .7__ ____ .8__ ____  .9__ ____ .A__ ____  .B__ ____ .C__ ____  .D__ ____ .E__ ____  .F__ ____ 10__ ____
  .... .... .... ..80 | 11__ ____ 12__ ____  13__ ____ 14__ ____  15__ ____ 16__ ____  17__ ____ 18__ ____  19__ ____ 1A__ ____  1B__ ____ 1C__ ____  1D__ ____ 1E__ ____  1F__ ____ 20__ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
   zmm31: .... ..20 .... ..1F  .... ..1E .... ..1D - .... ..1C .... ..1B  .... ..1A .... ..19 + .... ..18 .... ..17  .... ..16 .... ..15 - .... ..14 .... ..13  .... ..12 .... ..11
   zmm30: .... ..10 .... ...F  .... ...E .... ...D - .... ...C .... ...B  .... ...A .... ...9 + .... ...8 .... ...7  .... ...6 .... ...5 - .... ...4 .... ...3  .... ...2 .... ...1
  B
  Area     Size:     4096    Used:      192
  .... .... .... ...0 | __10 ____ ____ ____  C0__ ____ ____ ____  40__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | 11__ ____ 12__ ____  13__ ____ 14__ ____  15__ ____ 16__ ____  17__ ____ 18__ ____  19__ ____ 1A__ ____  1B__ ____ 1C__ ____  1D__ ____ 1E__ ____  1F__ ____ 20__ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  C
  Area     Size:     4096    Used:      192
  .... .... .... ...0 | __10 ____ ____ ____  C0__ ____ ____ ____  80__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | 40__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  index: .... .... .... ...1
   zmm31: .... ..10 .... ...F  .... ...E .... ...D - .... ...C .... ...B  .... ...A .... ...9 + .... ...8 .... ...7  .... ...6 .... ...5 - .... ...4 .... ...3  .... ...2 .... ...1
   zmm30: .... ..20 .... ..1F  .... ..1E .... ..1D - .... ..1C .... ..1B  .... ..1A .... ..19 + .... ..18 .... ..17  .... ..16 .... ..15 - .... ..14 .... ..13  .... ..12 .... ..11
  A
  Area     Size:     4096    Used:      192
  .... .... .... ...0 | __10 ____ ____ ____  C0__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 11__ ____ 12__ ____  13__ ____ 14__ ____  15__ ____ 16__ ____  17__ ____ 18__ ____  19__ ____ 1A__ ____  1B__ ____ 1C__ ____  1D__ ____ 1E__ ____  1F__ ____ 20__ ____
  .... .... .... ..80 | .1__ ____ .2__ ____  .3__ ____ .4__ ____  .5__ ____ .6__ ____  .7__ ____ .8__ ____  .9__ ____ .A__ ____  .B__ ____ .C__ ____  .D__ ____ .E__ ____  .F__ ____ 10__ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
   zmm31: .... ..20 .... ..1F  .... ..1E .... ..1D - .... ..1C .... ..1B  .... ..1A .... ..19 + .... ..18 .... ..17  .... ..16 .... ..15 - .... ..14 .... ..13  .... ..12 .... ..11
   zmm30: .... ..10 .... ...F  .... ...E .... ...D - .... ...C .... ...B  .... ...A .... ...9 + .... ...8 .... ...7  .... ...6 .... ...5 - .... ...4 .... ...3  .... ...2 .... ...1
  B
  Area     Size:     4096    Used:      192
  .... .... .... ...0 | __10 ____ ____ ____  C0__ ____ ____ ____  80__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 11__ ____ 12__ ____  13__ ____ 14__ ____  15__ ____ 16__ ____  17__ ____ 18__ ____  19__ ____ 1A__ ____  1B__ ____ 1C__ ____  1D__ ____ 1E__ ____  1F__ ____ 20__ ____
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  C
  Area     Size:     4096    Used:      192
  .... .... .... ...0 | __10 ____ ____ ____  C0__ ____ ____ ____  40__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 80__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  index: .... .... .... ...2
   zmm31: .... ..10 .... ...F  .... ...E .... ...D - .... ...C .... ...B  .... ...A .... ...9 + .... ...8 .... ...7  .... ...6 .... ...5 - .... ...4 .... ...3  .... ...2 .... ...1
   zmm30: .... ..20 .... ..1F  .... ..1E .... ..1D - .... ..1C .... ..1B  .... ..1A .... ..19 + .... ..18 .... ..17  .... ..16 .... ..15 - .... ..14 .... ..13  .... ..12 .... ..11
  A
  Area     Size:     4096    Used:      192
  .... .... .... ...0 | __10 ____ ____ ____  C0__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | .1__ ____ .2__ ____  .3__ ____ .4__ ____  .5__ ____ .6__ ____  .7__ ____ .8__ ____  .9__ ____ .A__ ____  .B__ ____ .C__ ____  .D__ ____ .E__ ____  .F__ ____ 10__ ____
  .... .... .... ..80 | 11__ ____ 12__ ____  13__ ____ 14__ ____  15__ ____ 16__ ____  17__ ____ 18__ ____  19__ ____ 1A__ ____  1B__ ____ 1C__ ____  1D__ ____ 1E__ ____  1F__ ____ 20__ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
   zmm31: .... ..20 .... ..1F  .... ..1E .... ..1D - .... ..1C .... ..1B  .... ..1A .... ..19 + .... ..18 .... ..17  .... ..16 .... ..15 - .... ..14 .... ..13  .... ..12 .... ..11
   zmm30: .... ..10 .... ...F  .... ...E .... ...D - .... ...C .... ...B  .... ...A .... ...9 + .... ...8 .... ...7  .... ...6 .... ...5 - .... ...4 .... ...3  .... ...2 .... ...1
  B
  Area     Size:     4096    Used:      192
  .... .... .... ...0 | __10 ____ ____ ____  C0__ ____ ____ ____  40__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | 11__ ____ 12__ ____  13__ ____ 14__ ____  15__ ____ 16__ ____  17__ ____ 18__ ____  19__ ____ 1A__ ____  1B__ ____ 1C__ ____  1D__ ____ 1E__ ____  1F__ ____ 20__ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  C
  Area     Size:     4096    Used:      192
  .... .... .... ...0 | __10 ____ ____ ____  C0__ ____ ____ ____  80__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | 40__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  END

Nasm::X86::Area::freeZmmBlock($area, $offset)

Free a block in an area by placing it on the free chain.

     Parameter  Description
  1  $area      Area descriptor
  2  $offset    Offset of zmm block to be freed

Example:

    my $a = CreateArea;

    my $m = $a->allocZmmBlock;
    K(K => Rd(1..16))->loadZmm(31);

    $a->putZmmBlock  ($m, 31);
    $a->dump("A");

    $a->getZmmBlock  ($m, 30);
    $a->clearZmmBlock($m);
    $a->getZmmBlock  ($m, 29);

    $a->clearZmmBlock($m);
    PrintOutRegisterInHex 31, 30, 29;

    ok Assemble eq => <<END, avx512=>1;
  A
  Area     Size:     4096    Used:      128
  .... .... .... ...0 | __10 ____ ____ ____  80__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | .1__ ____ .2__ ____  .3__ ____ .4__ ____  .5__ ____ .6__ ____  .7__ ____ .8__ ____  .9__ ____ .A__ ____  .B__ ____ .C__ ____  .D__ ____ .E__ ____  .F__ ____ 10__ ____
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
   zmm31: .... ..10 .... ...F  .... ...E .... ...D - .... ...C .... ...B  .... ...A .... ...9 + .... ...8 .... ...7  .... ...6 .... ...5 - .... ...4 .... ...3  .... ...2 .... ...1
   zmm30: .... ..10 .... ...F  .... ...E .... ...D - .... ...C .... ...B  .... ...A .... ...9 + .... ...8 .... ...7  .... ...6 .... ...5 - .... ...4 .... ...3  .... ...2 .... ...1
   zmm29: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0
  END

    my $a = CreateArea;

    K(loop => 3)->for(sub
     {my ($i, $start, $next, $end) = @_;
      $i->outNL;
      my $m1 = $a->allocZmmBlock;
      my $m2 = $a->allocZmmBlock;

      K(K => Rd(1..16))->loadZmm(31);
      K(K => Rd(17..32))->loadZmm(30);
      PrintOutRegisterInHex 31, 30;

      $a->putZmmBlock($m1, 31);
      $a->putZmmBlock($m2, 30);
      $a->dump("A");

      $a->getZmmBlock($m1, 30);
      $a->getZmmBlock($m2, 31);
      PrintOutRegisterInHex 31, 30;

      $a->clearZmmBlock($m1);
      $a->freeZmmBlock($m1);
      $a->dump("B");

      $a->freeZmmBlock($m2);
      $a->dump("C");
     });

    ok Assemble eq => <<END, avx512=>1;
  index: .... .... .... ...0
   zmm31: .... ..10 .... ...F  .... ...E .... ...D - .... ...C .... ...B  .... ...A .... ...9 + .... ...8 .... ...7  .... ...6 .... ...5 - .... ...4 .... ...3  .... ...2 .... ...1
   zmm30: .... ..20 .... ..1F  .... ..1E .... ..1D - .... ..1C .... ..1B  .... ..1A .... ..19 + .... ..18 .... ..17  .... ..16 .... ..15 - .... ..14 .... ..13  .... ..12 .... ..11
  A
  Area     Size:     4096    Used:      192
  .... .... .... ...0 | __10 ____ ____ ____  C0__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | .1__ ____ .2__ ____  .3__ ____ .4__ ____  .5__ ____ .6__ ____  .7__ ____ .8__ ____  .9__ ____ .A__ ____  .B__ ____ .C__ ____  .D__ ____ .E__ ____  .F__ ____ 10__ ____
  .... .... .... ..80 | 11__ ____ 12__ ____  13__ ____ 14__ ____  15__ ____ 16__ ____  17__ ____ 18__ ____  19__ ____ 1A__ ____  1B__ ____ 1C__ ____  1D__ ____ 1E__ ____  1F__ ____ 20__ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
   zmm31: .... ..20 .... ..1F  .... ..1E .... ..1D - .... ..1C .... ..1B  .... ..1A .... ..19 + .... ..18 .... ..17  .... ..16 .... ..15 - .... ..14 .... ..13  .... ..12 .... ..11
   zmm30: .... ..10 .... ...F  .... ...E .... ...D - .... ...C .... ...B  .... ...A .... ...9 + .... ...8 .... ...7  .... ...6 .... ...5 - .... ...4 .... ...3  .... ...2 .... ...1
  B
  Area     Size:     4096    Used:      192
  .... .... .... ...0 | __10 ____ ____ ____  C0__ ____ ____ ____  40__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | 11__ ____ 12__ ____  13__ ____ 14__ ____  15__ ____ 16__ ____  17__ ____ 18__ ____  19__ ____ 1A__ ____  1B__ ____ 1C__ ____  1D__ ____ 1E__ ____  1F__ ____ 20__ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  C
  Area     Size:     4096    Used:      192
  .... .... .... ...0 | __10 ____ ____ ____  C0__ ____ ____ ____  80__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | 40__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  index: .... .... .... ...1
   zmm31: .... ..10 .... ...F  .... ...E .... ...D - .... ...C .... ...B  .... ...A .... ...9 + .... ...8 .... ...7  .... ...6 .... ...5 - .... ...4 .... ...3  .... ...2 .... ...1
   zmm30: .... ..20 .... ..1F  .... ..1E .... ..1D - .... ..1C .... ..1B  .... ..1A .... ..19 + .... ..18 .... ..17  .... ..16 .... ..15 - .... ..14 .... ..13  .... ..12 .... ..11
  A
  Area     Size:     4096    Used:      192
  .... .... .... ...0 | __10 ____ ____ ____  C0__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 11__ ____ 12__ ____  13__ ____ 14__ ____  15__ ____ 16__ ____  17__ ____ 18__ ____  19__ ____ 1A__ ____  1B__ ____ 1C__ ____  1D__ ____ 1E__ ____  1F__ ____ 20__ ____
  .... .... .... ..80 | .1__ ____ .2__ ____  .3__ ____ .4__ ____  .5__ ____ .6__ ____  .7__ ____ .8__ ____  .9__ ____ .A__ ____  .B__ ____ .C__ ____  .D__ ____ .E__ ____  .F__ ____ 10__ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
   zmm31: .... ..20 .... ..1F  .... ..1E .... ..1D - .... ..1C .... ..1B  .... ..1A .... ..19 + .... ..18 .... ..17  .... ..16 .... ..15 - .... ..14 .... ..13  .... ..12 .... ..11
   zmm30: .... ..10 .... ...F  .... ...E .... ...D - .... ...C .... ...B  .... ...A .... ...9 + .... ...8 .... ...7  .... ...6 .... ...5 - .... ...4 .... ...3  .... ...2 .... ...1
  B
  Area     Size:     4096    Used:      192
  .... .... .... ...0 | __10 ____ ____ ____  C0__ ____ ____ ____  80__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 11__ ____ 12__ ____  13__ ____ 14__ ____  15__ ____ 16__ ____  17__ ____ 18__ ____  19__ ____ 1A__ ____  1B__ ____ 1C__ ____  1D__ ____ 1E__ ____  1F__ ____ 20__ ____
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  C
  Area     Size:     4096    Used:      192
  .... .... .... ...0 | __10 ____ ____ ____  C0__ ____ ____ ____  40__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 80__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  index: .... .... .... ...2
   zmm31: .... ..10 .... ...F  .... ...E .... ...D - .... ...C .... ...B  .... ...A .... ...9 + .... ...8 .... ...7  .... ...6 .... ...5 - .... ...4 .... ...3  .... ...2 .... ...1
   zmm30: .... ..20 .... ..1F  .... ..1E .... ..1D - .... ..1C .... ..1B  .... ..1A .... ..19 + .... ..18 .... ..17  .... ..16 .... ..15 - .... ..14 .... ..13  .... ..12 .... ..11
  A
  Area     Size:     4096    Used:      192
  .... .... .... ...0 | __10 ____ ____ ____  C0__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | .1__ ____ .2__ ____  .3__ ____ .4__ ____  .5__ ____ .6__ ____  .7__ ____ .8__ ____  .9__ ____ .A__ ____  .B__ ____ .C__ ____  .D__ ____ .E__ ____  .F__ ____ 10__ ____
  .... .... .... ..80 | 11__ ____ 12__ ____  13__ ____ 14__ ____  15__ ____ 16__ ____  17__ ____ 18__ ____  19__ ____ 1A__ ____  1B__ ____ 1C__ ____  1D__ ____ 1E__ ____  1F__ ____ 20__ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
   zmm31: .... ..20 .... ..1F  .... ..1E .... ..1D - .... ..1C .... ..1B  .... ..1A .... ..19 + .... ..18 .... ..17  .... ..16 .... ..15 - .... ..14 .... ..13  .... ..12 .... ..11
   zmm30: .... ..10 .... ...F  .... ...E .... ...D - .... ...C .... ...B  .... ...A .... ...9 + .... ...8 .... ...7  .... ...6 .... ...5 - .... ...4 .... ...3  .... ...2 .... ...1
  B
  Area     Size:     4096    Used:      192
  .... .... .... ...0 | __10 ____ ____ ____  C0__ ____ ____ ____  40__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | 11__ ____ 12__ ____  13__ ____ 14__ ____  15__ ____ 16__ ____  17__ ____ 18__ ____  19__ ____ 1A__ ____  1B__ ____ 1C__ ____  1D__ ____ 1E__ ____  1F__ ____ 20__ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  C
  Area     Size:     4096    Used:      192
  .... .... .... ...0 | __10 ____ ____ ____  C0__ ____ ____ ____  80__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | 40__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  END

Nasm::X86::Area::freeChainSpace($area)

Count the number of blocks available on the free chain.

     Parameter  Description
  1  $area      Area descriptor

Example:

    my $a = CreateArea;
    my $t = $a->CreateTree;
    my $N = K loop => 16;

    $N->for(sub {my ($i) = @_; $t->push($i+1)});
    $t->size->out("t: ", " ");
    $a->used->out("u: ", " ");
    $a->freeChainSpace->out("f: ", " ");
    $a->size->outNL;
    $t->clear;
    $t->size->out("t: ", " ");
    $a->used->out("u: ", " ");
    $a->freeChainSpace->out("f: ", " ");
    $a->size->outNL;

    $N->for(sub {my ($i) = @_; $t->push($i+1)});
    $t->size->out("t: ", " ");
    $a->used->out("u: ", " ");
    $a->freeChainSpace->out("f: ", " ");
    $a->size->outNL;
    $t->clear;
    $t->size->out("t: ", " ");
    $a->used->out("u: ", " ");
    $a->freeChainSpace->out("f: ", " ");
    $a->size->outNL;

    $N->for(sub {my ($i) = @_; $t->push($i+1)});
    $t->free;
    $a->used->out("Clear tree:            u: ");
    $a->freeChainSpace->out(" f: ", " ");
    $a->size->outNL;

    $a->clear;
    $a->used->out("Clear area:            u: ");
    $a->freeChainSpace->out(" f: ", " ");
    $a->size->outNL;

    ok Assemble eq => <<END, label=>'t5';
  t: .... .... .... ..10 u: .... .... .... .280 f: .... .... .... ...0 size of area: .... .... .... 10..
  t: .... .... .... ...0 u: .... .... .... .280 f: .... .... .... .240 size of area: .... .... .... 10..
  t: .... .... .... ..10 u: .... .... .... .280 f: .... .... .... ...0 size of area: .... .... .... 10..
  t: .... .... .... ...0 u: .... .... .... .280 f: .... .... .... .240 size of area: .... .... .... 10..
  Clear tree:            u: .... .... .... .280 f: .... .... .... .240 size of area: .... .... .... 10..
  Clear area:            u: .... .... .... ...0 f: .... .... .... ...0 size of area: .... .... .... 10..
  END

Nasm::X86::Area::getZmmBlock($area, $block, $zmm)

Get the block with the specified offset in the specified string and return it in the numbered zmm.

     Parameter  Description
  1  $area      Area descriptor
  2  $block     Offset of the block as a variable or register
  3  $zmm       Number of zmm register to contain block

Example:

    my $a = CreateArea;

    my $m = $a->allocZmmBlock;
    K(K => Rd(1..16))->loadZmm(31);

    $a->putZmmBlock  ($m, 31);
    $a->dump("A");

    $a->getZmmBlock  ($m, 30);
    $a->clearZmmBlock($m);
    $a->getZmmBlock  ($m, 29);

    $a->clearZmmBlock($m);
    PrintOutRegisterInHex 31, 30, 29;

    ok Assemble eq => <<END, avx512=>1;
  A
  Area     Size:     4096    Used:      128
  .... .... .... ...0 | __10 ____ ____ ____  80__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | .1__ ____ .2__ ____  .3__ ____ .4__ ____  .5__ ____ .6__ ____  .7__ ____ .8__ ____  .9__ ____ .A__ ____  .B__ ____ .C__ ____  .D__ ____ .E__ ____  .F__ ____ 10__ ____
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
   zmm31: .... ..10 .... ...F  .... ...E .... ...D - .... ...C .... ...B  .... ...A .... ...9 + .... ...8 .... ...7  .... ...6 .... ...5 - .... ...4 .... ...3  .... ...2 .... ...1
   zmm30: .... ..10 .... ...F  .... ...E .... ...D - .... ...C .... ...B  .... ...A .... ...9 + .... ...8 .... ...7  .... ...6 .... ...5 - .... ...4 .... ...3  .... ...2 .... ...1
   zmm29: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0
  END

    my $a = CreateArea;

    K(loop => 3)->for(sub
     {my ($i, $start, $next, $end) = @_;
      $i->outNL;
      my $m1 = $a->allocZmmBlock;
      my $m2 = $a->allocZmmBlock;

      K(K => Rd(1..16))->loadZmm(31);
      K(K => Rd(17..32))->loadZmm(30);
      PrintOutRegisterInHex 31, 30;

      $a->putZmmBlock($m1, 31);
      $a->putZmmBlock($m2, 30);
      $a->dump("A");

      $a->getZmmBlock($m1, 30);
      $a->getZmmBlock($m2, 31);
      PrintOutRegisterInHex 31, 30;

      $a->clearZmmBlock($m1);
      $a->freeZmmBlock($m1);
      $a->dump("B");

      $a->freeZmmBlock($m2);
      $a->dump("C");
     });

    ok Assemble eq => <<END, avx512=>1;
  index: .... .... .... ...0
   zmm31: .... ..10 .... ...F  .... ...E .... ...D - .... ...C .... ...B  .... ...A .... ...9 + .... ...8 .... ...7  .... ...6 .... ...5 - .... ...4 .... ...3  .... ...2 .... ...1
   zmm30: .... ..20 .... ..1F  .... ..1E .... ..1D - .... ..1C .... ..1B  .... ..1A .... ..19 + .... ..18 .... ..17  .... ..16 .... ..15 - .... ..14 .... ..13  .... ..12 .... ..11
  A
  Area     Size:     4096    Used:      192
  .... .... .... ...0 | __10 ____ ____ ____  C0__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | .1__ ____ .2__ ____  .3__ ____ .4__ ____  .5__ ____ .6__ ____  .7__ ____ .8__ ____  .9__ ____ .A__ ____  .B__ ____ .C__ ____  .D__ ____ .E__ ____  .F__ ____ 10__ ____
  .... .... .... ..80 | 11__ ____ 12__ ____  13__ ____ 14__ ____  15__ ____ 16__ ____  17__ ____ 18__ ____  19__ ____ 1A__ ____  1B__ ____ 1C__ ____  1D__ ____ 1E__ ____  1F__ ____ 20__ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
   zmm31: .... ..20 .... ..1F  .... ..1E .... ..1D - .... ..1C .... ..1B  .... ..1A .... ..19 + .... ..18 .... ..17  .... ..16 .... ..15 - .... ..14 .... ..13  .... ..12 .... ..11
   zmm30: .... ..10 .... ...F  .... ...E .... ...D - .... ...C .... ...B  .... ...A .... ...9 + .... ...8 .... ...7  .... ...6 .... ...5 - .... ...4 .... ...3  .... ...2 .... ...1
  B
  Area     Size:     4096    Used:      192
  .... .... .... ...0 | __10 ____ ____ ____  C0__ ____ ____ ____  40__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | 11__ ____ 12__ ____  13__ ____ 14__ ____  15__ ____ 16__ ____  17__ ____ 18__ ____  19__ ____ 1A__ ____  1B__ ____ 1C__ ____  1D__ ____ 1E__ ____  1F__ ____ 20__ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  C
  Area     Size:     4096    Used:      192
  .... .... .... ...0 | __10 ____ ____ ____  C0__ ____ ____ ____  80__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | 40__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  index: .... .... .... ...1
   zmm31: .... ..10 .... ...F  .... ...E .... ...D - .... ...C .... ...B  .... ...A .... ...9 + .... ...8 .... ...7  .... ...6 .... ...5 - .... ...4 .... ...3  .... ...2 .... ...1
   zmm30: .... ..20 .... ..1F  .... ..1E .... ..1D - .... ..1C .... ..1B  .... ..1A .... ..19 + .... ..18 .... ..17  .... ..16 .... ..15 - .... ..14 .... ..13  .... ..12 .... ..11
  A
  Area     Size:     4096    Used:      192
  .... .... .... ...0 | __10 ____ ____ ____  C0__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 11__ ____ 12__ ____  13__ ____ 14__ ____  15__ ____ 16__ ____  17__ ____ 18__ ____  19__ ____ 1A__ ____  1B__ ____ 1C__ ____  1D__ ____ 1E__ ____  1F__ ____ 20__ ____
  .... .... .... ..80 | .1__ ____ .2__ ____  .3__ ____ .4__ ____  .5__ ____ .6__ ____  .7__ ____ .8__ ____  .9__ ____ .A__ ____  .B__ ____ .C__ ____  .D__ ____ .E__ ____  .F__ ____ 10__ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
   zmm31: .... ..20 .... ..1F  .... ..1E .... ..1D - .... ..1C .... ..1B  .... ..1A .... ..19 + .... ..18 .... ..17  .... ..16 .... ..15 - .... ..14 .... ..13  .... ..12 .... ..11
   zmm30: .... ..10 .... ...F  .... ...E .... ...D - .... ...C .... ...B  .... ...A .... ...9 + .... ...8 .... ...7  .... ...6 .... ...5 - .... ...4 .... ...3  .... ...2 .... ...1
  B
  Area     Size:     4096    Used:      192
  .... .... .... ...0 | __10 ____ ____ ____  C0__ ____ ____ ____  80__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 11__ ____ 12__ ____  13__ ____ 14__ ____  15__ ____ 16__ ____  17__ ____ 18__ ____  19__ ____ 1A__ ____  1B__ ____ 1C__ ____  1D__ ____ 1E__ ____  1F__ ____ 20__ ____
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  C
  Area     Size:     4096    Used:      192
  .... .... .... ...0 | __10 ____ ____ ____  C0__ ____ ____ ____  40__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 80__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  index: .... .... .... ...2
   zmm31: .... ..10 .... ...F  .... ...E .... ...D - .... ...C .... ...B  .... ...A .... ...9 + .... ...8 .... ...7  .... ...6 .... ...5 - .... ...4 .... ...3  .... ...2 .... ...1
   zmm30: .... ..20 .... ..1F  .... ..1E .... ..1D - .... ..1C .... ..1B  .... ..1A .... ..19 + .... ..18 .... ..17  .... ..16 .... ..15 - .... ..14 .... ..13  .... ..12 .... ..11
  A
  Area     Size:     4096    Used:      192
  .... .... .... ...0 | __10 ____ ____ ____  C0__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | .1__ ____ .2__ ____  .3__ ____ .4__ ____  .5__ ____ .6__ ____  .7__ ____ .8__ ____  .9__ ____ .A__ ____  .B__ ____ .C__ ____  .D__ ____ .E__ ____  .F__ ____ 10__ ____
  .... .... .... ..80 | 11__ ____ 12__ ____  13__ ____ 14__ ____  15__ ____ 16__ ____  17__ ____ 18__ ____  19__ ____ 1A__ ____  1B__ ____ 1C__ ____  1D__ ____ 1E__ ____  1F__ ____ 20__ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
   zmm31: .... ..20 .... ..1F  .... ..1E .... ..1D - .... ..1C .... ..1B  .... ..1A .... ..19 + .... ..18 .... ..17  .... ..16 .... ..15 - .... ..14 .... ..13  .... ..12 .... ..11
   zmm30: .... ..10 .... ...F  .... ...E .... ...D - .... ...C .... ...B  .... ...A .... ...9 + .... ...8 .... ...7  .... ...6 .... ...5 - .... ...4 .... ...3  .... ...2 .... ...1
  B
  Area     Size:     4096    Used:      192
  .... .... .... ...0 | __10 ____ ____ ____  C0__ ____ ____ ____  40__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | 11__ ____ 12__ ____  13__ ____ 14__ ____  15__ ____ 16__ ____  17__ ____ 18__ ____  19__ ____ 1A__ ____  1B__ ____ 1C__ ____  1D__ ____ 1E__ ____  1F__ ____ 20__ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  C
  Area     Size:     4096    Used:      192
  .... .... .... ...0 | __10 ____ ____ ____  C0__ ____ ____ ____  80__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | 40__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  END

Nasm::X86::Area::putZmmBlock($area, $block, $zmm)

Write the numbered zmm to the block at the specified offset in the specified area.

     Parameter  Description
  1  $area      Area descriptor
  2  $block     Offset of the block as a variable
  3  $zmm       Number of zmm register to contain block

Example:

    my $a = CreateArea;

    my $m = $a->allocZmmBlock;
    K(K => Rd(1..16))->loadZmm(31);

    $a->putZmmBlock  ($m, 31);
    $a->dump("A");

    $a->getZmmBlock  ($m, 30);
    $a->clearZmmBlock($m);
    $a->getZmmBlock  ($m, 29);

    $a->clearZmmBlock($m);
    PrintOutRegisterInHex 31, 30, 29;

    ok Assemble eq => <<END, avx512=>1;
  A
  Area     Size:     4096    Used:      128
  .... .... .... ...0 | __10 ____ ____ ____  80__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | .1__ ____ .2__ ____  .3__ ____ .4__ ____  .5__ ____ .6__ ____  .7__ ____ .8__ ____  .9__ ____ .A__ ____  .B__ ____ .C__ ____  .D__ ____ .E__ ____  .F__ ____ 10__ ____
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
   zmm31: .... ..10 .... ...F  .... ...E .... ...D - .... ...C .... ...B  .... ...A .... ...9 + .... ...8 .... ...7  .... ...6 .... ...5 - .... ...4 .... ...3  .... ...2 .... ...1
   zmm30: .... ..10 .... ...F  .... ...E .... ...D - .... ...C .... ...B  .... ...A .... ...9 + .... ...8 .... ...7  .... ...6 .... ...5 - .... ...4 .... ...3  .... ...2 .... ...1
   zmm29: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0
  END

    my $a = CreateArea;

    K(loop => 3)->for(sub
     {my ($i, $start, $next, $end) = @_;
      $i->outNL;
      my $m1 = $a->allocZmmBlock;
      my $m2 = $a->allocZmmBlock;

      K(K => Rd(1..16))->loadZmm(31);
      K(K => Rd(17..32))->loadZmm(30);
      PrintOutRegisterInHex 31, 30;

      $a->putZmmBlock($m1, 31);
      $a->putZmmBlock($m2, 30);
      $a->dump("A");

      $a->getZmmBlock($m1, 30);
      $a->getZmmBlock($m2, 31);
      PrintOutRegisterInHex 31, 30;

      $a->clearZmmBlock($m1);
      $a->freeZmmBlock($m1);
      $a->dump("B");

      $a->freeZmmBlock($m2);
      $a->dump("C");
     });

    ok Assemble eq => <<END, avx512=>1;
  index: .... .... .... ...0
   zmm31: .... ..10 .... ...F  .... ...E .... ...D - .... ...C .... ...B  .... ...A .... ...9 + .... ...8 .... ...7  .... ...6 .... ...5 - .... ...4 .... ...3  .... ...2 .... ...1
   zmm30: .... ..20 .... ..1F  .... ..1E .... ..1D - .... ..1C .... ..1B  .... ..1A .... ..19 + .... ..18 .... ..17  .... ..16 .... ..15 - .... ..14 .... ..13  .... ..12 .... ..11
  A
  Area     Size:     4096    Used:      192
  .... .... .... ...0 | __10 ____ ____ ____  C0__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | .1__ ____ .2__ ____  .3__ ____ .4__ ____  .5__ ____ .6__ ____  .7__ ____ .8__ ____  .9__ ____ .A__ ____  .B__ ____ .C__ ____  .D__ ____ .E__ ____  .F__ ____ 10__ ____
  .... .... .... ..80 | 11__ ____ 12__ ____  13__ ____ 14__ ____  15__ ____ 16__ ____  17__ ____ 18__ ____  19__ ____ 1A__ ____  1B__ ____ 1C__ ____  1D__ ____ 1E__ ____  1F__ ____ 20__ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
   zmm31: .... ..20 .... ..1F  .... ..1E .... ..1D - .... ..1C .... ..1B  .... ..1A .... ..19 + .... ..18 .... ..17  .... ..16 .... ..15 - .... ..14 .... ..13  .... ..12 .... ..11
   zmm30: .... ..10 .... ...F  .... ...E .... ...D - .... ...C .... ...B  .... ...A .... ...9 + .... ...8 .... ...7  .... ...6 .... ...5 - .... ...4 .... ...3  .... ...2 .... ...1
  B
  Area     Size:     4096    Used:      192
  .... .... .... ...0 | __10 ____ ____ ____  C0__ ____ ____ ____  40__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | 11__ ____ 12__ ____  13__ ____ 14__ ____  15__ ____ 16__ ____  17__ ____ 18__ ____  19__ ____ 1A__ ____  1B__ ____ 1C__ ____  1D__ ____ 1E__ ____  1F__ ____ 20__ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  C
  Area     Size:     4096    Used:      192
  .... .... .... ...0 | __10 ____ ____ ____  C0__ ____ ____ ____  80__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | 40__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  index: .... .... .... ...1
   zmm31: .... ..10 .... ...F  .... ...E .... ...D - .... ...C .... ...B  .... ...A .... ...9 + .... ...8 .... ...7  .... ...6 .... ...5 - .... ...4 .... ...3  .... ...2 .... ...1
   zmm30: .... ..20 .... ..1F  .... ..1E .... ..1D - .... ..1C .... ..1B  .... ..1A .... ..19 + .... ..18 .... ..17  .... ..16 .... ..15 - .... ..14 .... ..13  .... ..12 .... ..11
  A
  Area     Size:     4096    Used:      192
  .... .... .... ...0 | __10 ____ ____ ____  C0__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 11__ ____ 12__ ____  13__ ____ 14__ ____  15__ ____ 16__ ____  17__ ____ 18__ ____  19__ ____ 1A__ ____  1B__ ____ 1C__ ____  1D__ ____ 1E__ ____  1F__ ____ 20__ ____
  .... .... .... ..80 | .1__ ____ .2__ ____  .3__ ____ .4__ ____  .5__ ____ .6__ ____  .7__ ____ .8__ ____  .9__ ____ .A__ ____  .B__ ____ .C__ ____  .D__ ____ .E__ ____  .F__ ____ 10__ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
   zmm31: .... ..20 .... ..1F  .... ..1E .... ..1D - .... ..1C .... ..1B  .... ..1A .... ..19 + .... ..18 .... ..17  .... ..16 .... ..15 - .... ..14 .... ..13  .... ..12 .... ..11
   zmm30: .... ..10 .... ...F  .... ...E .... ...D - .... ...C .... ...B  .... ...A .... ...9 + .... ...8 .... ...7  .... ...6 .... ...5 - .... ...4 .... ...3  .... ...2 .... ...1
  B
  Area     Size:     4096    Used:      192
  .... .... .... ...0 | __10 ____ ____ ____  C0__ ____ ____ ____  80__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 11__ ____ 12__ ____  13__ ____ 14__ ____  15__ ____ 16__ ____  17__ ____ 18__ ____  19__ ____ 1A__ ____  1B__ ____ 1C__ ____  1D__ ____ 1E__ ____  1F__ ____ 20__ ____
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  C
  Area     Size:     4096    Used:      192
  .... .... .... ...0 | __10 ____ ____ ____  C0__ ____ ____ ____  40__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 80__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  index: .... .... .... ...2
   zmm31: .... ..10 .... ...F  .... ...E .... ...D - .... ...C .... ...B  .... ...A .... ...9 + .... ...8 .... ...7  .... ...6 .... ...5 - .... ...4 .... ...3  .... ...2 .... ...1
   zmm30: .... ..20 .... ..1F  .... ..1E .... ..1D - .... ..1C .... ..1B  .... ..1A .... ..19 + .... ..18 .... ..17  .... ..16 .... ..15 - .... ..14 .... ..13  .... ..12 .... ..11
  A
  Area     Size:     4096    Used:      192
  .... .... .... ...0 | __10 ____ ____ ____  C0__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | .1__ ____ .2__ ____  .3__ ____ .4__ ____  .5__ ____ .6__ ____  .7__ ____ .8__ ____  .9__ ____ .A__ ____  .B__ ____ .C__ ____  .D__ ____ .E__ ____  .F__ ____ 10__ ____
  .... .... .... ..80 | 11__ ____ 12__ ____  13__ ____ 14__ ____  15__ ____ 16__ ____  17__ ____ 18__ ____  19__ ____ 1A__ ____  1B__ ____ 1C__ ____  1D__ ____ 1E__ ____  1F__ ____ 20__ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
   zmm31: .... ..20 .... ..1F  .... ..1E .... ..1D - .... ..1C .... ..1B  .... ..1A .... ..19 + .... ..18 .... ..17  .... ..16 .... ..15 - .... ..14 .... ..13  .... ..12 .... ..11
   zmm30: .... ..10 .... ...F  .... ...E .... ...D - .... ...C .... ...B  .... ...A .... ...9 + .... ...8 .... ...7  .... ...6 .... ...5 - .... ...4 .... ...3  .... ...2 .... ...1
  B
  Area     Size:     4096    Used:      192
  .... .... .... ...0 | __10 ____ ____ ____  C0__ ____ ____ ____  40__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | 11__ ____ 12__ ____  13__ ____ 14__ ____  15__ ____ 16__ ____  17__ ____ 18__ ____  19__ ____ 1A__ ____  1B__ ____ 1C__ ____  1D__ ____ 1E__ ____  1F__ ____ 20__ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  C
  Area     Size:     4096    Used:      192
  .... .... .... ...0 | __10 ____ ____ ____  C0__ ____ ____ ____  80__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | 40__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  END

Nasm::X86::Area::clearZmmBlock($area, $offset)

Clear the zmm block at the specified offset in the area.

     Parameter  Description
  1  $area      Area descriptor
  2  $offset    Offset of the block as a variable

Example:

    my $a = CreateArea;

    my $m = $a->allocZmmBlock;
    K(K => Rd(1..16))->loadZmm(31);

    $a->putZmmBlock  ($m, 31);
    $a->dump("A");

    $a->getZmmBlock  ($m, 30);
    $a->clearZmmBlock($m);
    $a->getZmmBlock  ($m, 29);

    $a->clearZmmBlock($m);
    PrintOutRegisterInHex 31, 30, 29;

    ok Assemble eq => <<END, avx512=>1;
  A
  Area     Size:     4096    Used:      128
  .... .... .... ...0 | __10 ____ ____ ____  80__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | .1__ ____ .2__ ____  .3__ ____ .4__ ____  .5__ ____ .6__ ____  .7__ ____ .8__ ____  .9__ ____ .A__ ____  .B__ ____ .C__ ____  .D__ ____ .E__ ____  .F__ ____ 10__ ____
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
   zmm31: .... ..10 .... ...F  .... ...E .... ...D - .... ...C .... ...B  .... ...A .... ...9 + .... ...8 .... ...7  .... ...6 .... ...5 - .... ...4 .... ...3  .... ...2 .... ...1
   zmm30: .... ..10 .... ...F  .... ...E .... ...D - .... ...C .... ...B  .... ...A .... ...9 + .... ...8 .... ...7  .... ...6 .... ...5 - .... ...4 .... ...3  .... ...2 .... ...1
   zmm29: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0
  END

Yggdrasil

The world tree from which we can address so many other things

Nasm::X86::Area::yggdrasil($area)

Return a tree descriptor to the Yggdrasil world tree for an area creating the world tree Yggdrasil if it has not already been created.

     Parameter  Description
  1  $area      Area descriptor

Example:

    my $A = CreateArea;
    my $t = $A->checkYggdrasilCreated;
       $t->found->outNL;
    my $y = $A->yggdrasil;
    my $T = $A->checkYggdrasilCreated;
       $T->found->outNL;
    ok Assemble debug => 0, eq => <<END, avx512=>1;
  found  : .... .... .... ...0
  found  : .... .... .... ...1
  END

Areas as Strings

Use the memory supplied by the area as a string - however, in general, this is too slow unless coupled with another slow operation such as executing a command, mapping a file or writing to a file.

Nasm::X86::Area::appendMemory($area, $address, $size)

Append the variable addressed content in memory of variable size to the specified area and return its offset in that area. Pre-pack data as much as possible before using this routine to optimize processing.

     Parameter  Description
  1  $area      Area descriptor
  2  $address   Variable address of content
  3  $size      Variable length of content

Example:

    my $a = CreateArea;
       $a->appendMemory(constantString("aaaa"));                                  # 82 48
       $a->dump("AA");

    ok Assemble eq => <<END, clocks=>12_391;
  AA
  Area     Size:     4096    Used:       68
  .... .... .... ...0 | __10 ____ ____ ____  44__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 6161 6161 ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  END

Nasm::X86::Area::appendZmm($area, $zmm)

Append the contents of the specified zmm to the specified area and returns its offset in that area as a variable,

     Parameter  Description
  1  $area      Area descriptor
  2  $zmm       Zmm number

Example:

  if (1)
   {LoadZmm 0, 61..61+63;

    my $a = CreateArea;
    $a->appendZmm(0);
    $a->printOut(0x44, 2);
    $a->dump("AA");
    $a->write(my $f = "aaa.txt");

    my $A = ReadArea $f;
    $A->dump("BB");
    ok Assemble eq => <<END;
  AB
  AA
  Area     Size:     4096    Used:      128
  .... .... .... ...0 | __10 ____ ____ ____  80__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 3D3E 3F40 4142 4344  4546 4748 494A 4B4C  4D4E 4F50 5152 5354  5556 5758 595A 5B5C  5D5E 5F60 6162 6364  6566 6768 696A 6B6C  6D6E 6F70 7172 7374  7576 7778 797A 7B7C
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  BB
  Area     Size:     4096    Used:      128
  .... .... .... ...0 | __10 ____ ____ ____  80__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 3D3E 3F40 4142 4344  4546 4748 494A 4B4C  4D4E 4F50 5152 5354  5556 5758 595A 5B5C  5D5E 5F60 6162 6364  6566 6768 696A 6B6C  6D6E 6F70 7172 7374  7576 7778 797A 7B7C
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  END
   }

Nasm::X86::Area::appendVar($area, $var)

Append the contents of a variable to the specified area

     Parameter  Description
  1  $area      Area descriptor
  2  $var       Variable

Example:

  if (1)                                                                          # Place parser tables into an area
   {my $a = CreateArea;
    my ($alphabetN,    $alphabetA)    = Nasm::X86::Unisyn::Lex::AlphabetsArray;
    my ($transitionsN, $transitionsA) = Nasm::X86::Unisyn::Lex::PermissibleTransitionsArray;

    $a->appendVar(V address => "[$transitionsN]");
    $a->appendVar(V address => "[$alphabetN]");                                   # Save sizes at start if area where they can be easily found

    $a->appendMemory(V(address => $transitionsA), V size => "[$transitionsN]");   # Save transitions
    $a->appendMemory(V(address => $alphabetA),    V size => "[$alphabetN]");      # Save alphabets classification

    $a->write("z123.txt");                                                        # Save the area to the named file
    ok Assemble eq => <<END;
  END
   }

Nasm::X86::Area::q($area, $string)

Append a constant string to the area.

     Parameter  Description
  1  $area      Area descriptor
  2  $string    String

Example:

    my $a = CreateArea;
    $a->q('aa');
    $a->outNL;
    $a->ql('bb');
    $a->out;
    ok Assemble eq => <<END, avx512=>0;
  aa
  aabb
  END

Nasm::X86::Area::ql($area, $const)

Append a constant quoted string containing new line characters to the specified area.

     Parameter  Description
  1  $area      Area
  2  $const     Constant

Example:

    my $a = CreateArea;
    $a->q('aa');
    $a->outNL;
    $a->ql('bb');
    $a->out;
    ok Assemble eq => <<END, avx512=>0;
  aa
  aabb
  END

Nasm::X86::Area::char($area, $char)

Append a constant character expressed as a decimal number to the specified area.

     Parameter  Description
  1  $area      Area descriptor
  2  $char      Number of character to be appended

Example:

  if (1)
   {my $a = CreateArea;
    $a->char('a');
    $a->nl;
    $a->dump("AA");
    ok Assemble eq => <<END;
  AA
  Area     Size:     4096    Used:       66
  .... .... .... ...0 | __10 ____ ____ ____  42__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 61.A ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  END
   }

  if (1)
   {my $a = CreateArea;
    $a->char('a');
    $a->nl;
    $a->dump("AA");
    ok Assemble eq => <<END;
  AA
  Area     Size:     4096    Used:       66
  .... .... .... ...0 | __10 ____ ____ ____  42__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 61.A ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  END
   }

Nasm::X86::Area::nl($area)

Append a new line to the area addressed by rax.

     Parameter  Description
  1  $area      Area descriptor

Example:

  if (1)
   {my $a = CreateArea;
    $a->char('a');
    $a->nl;
    $a->dump("AA");
    ok Assemble eq => <<END;
  AA
  Area     Size:     4096    Used:       66
  .... .... .... ...0 | __10 ____ ____ ____  42__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 61.A ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  END
   }

  if (1)
   {my $a = CreateArea;
    $a->char('a');
    $a->nl;
    $a->dump("AA");
    ok Assemble eq => <<END;
  AA
  Area     Size:     4096    Used:       66
  .... .... .... ...0 | __10 ____ ____ ____  42__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 61.A ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  END
   }

Nasm::X86::Area::append($target, $source)

Append one area to another.

     Parameter  Description
  1  $target    Target area descriptor
  2  $source    Source area descriptor

Example:

    my $a = CreateArea;
    $a->q('ab');
    my $b = CreateArea;
    $b->append($a);
    $b->append($a);
    $a->append($b);
    $b->append($a);
    $a->append($b);
    $b->append($a);
    $b->append($a);
    $b->append($a);
    $b->append($a);


    $a->out;   PrintOutNL;
    $b->outNL;
    my $sa = $a->used; $sa->outNL;
    my $sb = $b->used; $sb->outNL;
    $a->clear;
    my $sA = $a->used; $sA->outNL;
    my $sB = $b->used; $sB->outNL;

    ok Assemble eq => <<END, avx512=>0;
  abababababababab
  ababababababababababababababababababababababababababababababababababababab
  area used up: .... .... .... ..10
  area used up: .... .... .... ..4A
  area used up: .... .... .... ...0
  area used up: .... .... .... ..4A
  END

Nasm::X86::Area::clear($area)

Clear an area but keep it at the same size.

     Parameter  Description
  1  $area      Area descriptor

Example:

    my $a = CreateArea;
    $a->q('ab');
    my $b = CreateArea;
    $b->append($a);
    $b->append($a);
    $a->append($b);
    $b->append($a);
    $a->append($b);
    $b->append($a);
    $b->append($a);
    $b->append($a);
    $b->append($a);


    $a->out;   PrintOutNL;
    $b->outNL;
    my $sa = $a->used; $sa->outNL;
    my $sb = $b->used; $sb->outNL;
    $a->clear;
    my $sA = $a->used; $sA->outNL;
    my $sB = $b->used; $sB->outNL;

    ok Assemble eq => <<END, avx512=>0;
  abababababababab
  ababababababababababababababababababababababababababababababababababababab
  area used up: .... .... .... ..10
  area used up: .... .... .... ..4A
  area used up: .... .... .... ...0
  area used up: .... .... .... ..4A
  END

    my $a = CreateArea;

    $a->q("a" x 255);
    $a->used->outNL;
    $a->size->outNL;
    $a->dump('A');
    $a->clear;
    $a->used->outNL;
    $a->size->outNL;
    $a->dump('B');

    $a->q("a" x 4095);
    $a->used->outNL;
    $a->size->outNL;
    $a->dump('C');
    $a->clear;
    $a->used->outNL;
    $a->size->outNL;
    $a->dump('D');

    $a->free;

    ok Assemble(debug => 0, eq => <<END, avx512=>1);
  area used up: .... .... .... ..FF
  size of area: .... .... .... 10..
  A
  Area     Size:     4096    Used:      319
  .... .... .... ...0 | __10 ____ ____ ____  3F.1 ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161
  .... .... .... ..80 | 6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161
  .... .... .... ..C0 | 6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161
  area used up: .... .... .... ...0
  size of area: .... .... .... 10..
  B
  Area     Size:     4096    Used:       64
  .... .... .... ...0 | __10 ____ ____ ____  40__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161
  .... .... .... ..80 | 6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161
  .... .... .... ..C0 | 6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161
  area used up: .... .... .... .FFF
  size of area: .... .... .... 20..
  C
  Area     Size:     8192    Used:     4159
  .... .... .... ...0 | __20 ____ ____ ____  3F10 ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161
  .... .... .... ..80 | 6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161
  .... .... .... ..C0 | 6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161
  area used up: .... .... .... ...0
  size of area: .... .... .... 20..
  D
  Area     Size:     8192    Used:       64
  .... .... .... ...0 | __20 ____ ____ ____  40__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161
  .... .... .... ..80 | 6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161
  .... .... .... ..C0 | 6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161  6161 6161 6161 6161
  END

    my $a = CreateArea;
    my $t = $a->CreateTree;
    my $N = K loop => 16;

    $N->for(sub {my ($i) = @_; $t->push($i+1)});
    $t->size->out("t: ", " ");
    $a->used->out("u: ", " ");
    $a->freeChainSpace->out("f: ", " ");
    $a->size->outNL;
    $t->clear;
    $t->size->out("t: ", " ");
    $a->used->out("u: ", " ");
    $a->freeChainSpace->out("f: ", " ");
    $a->size->outNL;

    $N->for(sub {my ($i) = @_; $t->push($i+1)});
    $t->size->out("t: ", " ");
    $a->used->out("u: ", " ");
    $a->freeChainSpace->out("f: ", " ");
    $a->size->outNL;
    $t->clear;
    $t->size->out("t: ", " ");
    $a->used->out("u: ", " ");
    $a->freeChainSpace->out("f: ", " ");
    $a->size->outNL;

    $N->for(sub {my ($i) = @_; $t->push($i+1)});
    $t->free;
    $a->used->out("Clear tree:            u: ");
    $a->freeChainSpace->out(" f: ", " ");
    $a->size->outNL;

    $a->clear;
    $a->used->out("Clear area:            u: ");
    $a->freeChainSpace->out(" f: ", " ");
    $a->size->outNL;

    ok Assemble eq => <<END, label=>'t5';
  t: .... .... .... ..10 u: .... .... .... .280 f: .... .... .... ...0 size of area: .... .... .... 10..
  t: .... .... .... ...0 u: .... .... .... .280 f: .... .... .... .240 size of area: .... .... .... 10..
  t: .... .... .... ..10 u: .... .... .... .280 f: .... .... .... ...0 size of area: .... .... .... 10..
  t: .... .... .... ...0 u: .... .... .... .280 f: .... .... .... .240 size of area: .... .... .... 10..
  Clear tree:            u: .... .... .... .280 f: .... .... .... .240 size of area: .... .... .... 10..
  Clear area:            u: .... .... .... ...0 f: .... .... .... ...0 size of area: .... .... .... 10..
  END

Nasm::X86::Area::read($area, $file)

Read a file specified by a variable addressed zero terminated string and append its content to the specified area.

     Parameter  Description
  1  $area      Area descriptor
  2  $file      Variable addressing file name

Example:

    my $a = CreateArea;
    my $f = owf q(zzzArea.txt), "AA
";
    $a->read(V file => Rs $f);
    $a->dump("AA");

    ok Assemble(debug => 0, eq => <<END, avx512=>1);
  AA
  Area     Size:     4096    Used:       67
  .... .... .... ...0 | __10 ____ ____ ____  43__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 4141 .A__ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  END

Nasm::X86::Area::write($area, $file)

Write the content of the specified area to a file specified by a zero terminated string.

     Parameter  Description
  1  $area      Area descriptor
  2  $file      Variable addressing zero terminated file name

Example:

  if (1)
   {LoadZmm 0, 61..61+63;

    my $a = CreateArea;
    $a->appendZmm(0);
    $a->printOut(0x44, 2);
    $a->dump("AA");
    $a->write(my $f = "aaa.txt");

    my $A = ReadArea $f;
    $A->dump("BB");
    ok Assemble eq => <<END;
  AB
  AA
  Area     Size:     4096    Used:      128
  .... .... .... ...0 | __10 ____ ____ ____  80__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 3D3E 3F40 4142 4344  4546 4748 494A 4B4C  4D4E 4F50 5152 5354  5556 5758 595A 5B5C  5D5E 5F60 6162 6364  6566 6768 696A 6B6C  6D6E 6F70 7172 7374  7576 7778 797A 7B7C
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  BB
  Area     Size:     4096    Used:      128
  .... .... .... ...0 | __10 ____ ____ ____  80__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 3D3E 3F40 4142 4344  4546 4748 494A 4B4C  4D4E 4F50 5152 5354  5556 5758 595A 5B5C  5D5E 5F60 6162 6364  6566 6768 696A 6B6C  6D6E 6F70 7172 7374  7576 7778 797A 7B7C
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  END
   }

Nasm::X86::Area::out($area)

Print the specified area on sysout.

     Parameter  Description
  1  $area      Area descriptor

Example:

    my $a = CreateArea;
    $a->q('aa');
    $a->outNL;
    $a->ql('bb');
    $a->out;
    ok Assemble eq => <<END, avx512=>0;
  aa
  aabb
  END

    my $a = CreateArea;
    $a->q('ab');
    my $b = CreateArea;
    $b->append($a);
    $b->append($a);
    $a->append($b);
    $b->append($a);
    $a->append($b);
    $b->append($a);
    $b->append($a);
    $b->append($a);
    $b->append($a);


    $a->out;   PrintOutNL;
    $b->outNL;
    my $sa = $a->used; $sa->outNL;
    my $sb = $b->used; $sb->outNL;
    $a->clear;
    my $sA = $a->used; $sA->outNL;
    my $sB = $b->used; $sB->outNL;

    ok Assemble eq => <<END, avx512=>0;
  abababababababab
  ababababababababababababababababababababababababababababababababababababab
  area used up: .... .... .... ..10
  area used up: .... .... .... ..4A
  area used up: .... .... .... ...0
  area used up: .... .... .... ..4A
  END

Nasm::X86::Area::outNL($area)

Print the specified area on sysout followed by a new line.

     Parameter  Description
  1  $area      Area descriptor

Example:

    my $a = CreateArea;
    $a->q('aa');
    $a->outNL;
    $a->ql('bb');
    $a->out;
    ok Assemble eq => <<END, avx512=>0;
  aa
  aabb
  END

    my $a = CreateArea;
    $a->q('ab');
    my $b = CreateArea;
    $b->append($a);
    $b->append($a);
    $a->append($b);
    $b->append($a);
    $a->append($b);
    $b->append($a);
    $b->append($a);
    $b->append($a);
    $b->append($a);


    $a->out;   PrintOutNL;
    $b->outNL;
    my $sa = $a->used; $sa->outNL;
    my $sb = $b->used; $sb->outNL;
    $a->clear;
    my $sA = $a->used; $sA->outNL;
    my $sB = $b->used; $sB->outNL;

    ok Assemble eq => <<END, avx512=>0;
  abababababababab
  ababababababababababababababababababababababababababababababababababababab
  area used up: .... .... .... ..10
  area used up: .... .... .... ..4A
  area used up: .... .... .... ...0
  area used up: .... .... .... ..4A
  END

Nasm::X86::Area::printOut($area, $Offset, $Length)

Print part of the specified area on sysout.

     Parameter  Description
  1  $area      Area descriptor
  2  $Offset    Offset
  3  $Length    Length

Example:

  if (1)
   {LoadZmm 0, 61..61+63;

    my $a = CreateArea;
    $a->appendZmm(0);
    $a->printOut(0x44, 2);
    $a->dump("AA");
    $a->write(my $f = "aaa.txt");

    my $A = ReadArea $f;
    $A->dump("BB");
    ok Assemble eq => <<END;
  AB
  AA
  Area     Size:     4096    Used:      128
  .... .... .... ...0 | __10 ____ ____ ____  80__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 3D3E 3F40 4142 4344  4546 4748 494A 4B4C  4D4E 4F50 5152 5354  5556 5758 595A 5B5C  5D5E 5F60 6162 6364  6566 6768 696A 6B6C  6D6E 6F70 7172 7374  7576 7778 797A 7B7C
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  BB
  Area     Size:     4096    Used:      128
  .... .... .... ...0 | __10 ____ ____ ____  80__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 3D3E 3F40 4142 4344  4546 4748 494A 4B4C  4D4E 4F50 5152 5354  5556 5758 595A 5B5C  5D5E 5F60 6162 6364  6566 6768 696A 6B6C  6D6E 6F70 7172 7374  7576 7778 797A 7B7C
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  END
   }

Nasm::X86::Area::dump($area, $title, $depth)

Dump details of an area.

     Parameter  Description
  1  $area      Area descriptor
  2  $title     Title string
  3  $depth     Optional variable number of 64 byte blocks to dump

Example:

    my $a = CreateArea;

    my $m = $a->allocZmmBlock;
    K(K => Rd(1..16))->loadZmm(31);

    $a->putZmmBlock  ($m, 31);
    $a->dump("A");

    $a->getZmmBlock  ($m, 30);
    $a->clearZmmBlock($m);
    $a->getZmmBlock  ($m, 29);

    $a->clearZmmBlock($m);
    PrintOutRegisterInHex 31, 30, 29;

    ok Assemble eq => <<END, avx512=>1;
  A
  Area     Size:     4096    Used:      128
  .... .... .... ...0 | __10 ____ ____ ____  80__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | .1__ ____ .2__ ____  .3__ ____ .4__ ____  .5__ ____ .6__ ____  .7__ ____ .8__ ____  .9__ ____ .A__ ____  .B__ ____ .C__ ____  .D__ ____ .E__ ____  .F__ ____ 10__ ____
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
   zmm31: .... ..10 .... ...F  .... ...E .... ...D - .... ...C .... ...B  .... ...A .... ...9 + .... ...8 .... ...7  .... ...6 .... ...5 - .... ...4 .... ...3  .... ...2 .... ...1
   zmm30: .... ..10 .... ...F  .... ...E .... ...D - .... ...C .... ...B  .... ...A .... ...9 + .... ...8 .... ...7  .... ...6 .... ...5 - .... ...4 .... ...3  .... ...2 .... ...1
   zmm29: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0
  END

    my $a = CreateArea;

    K(loop => 3)->for(sub
     {my ($i, $start, $next, $end) = @_;
      $i->outNL;
      my $m1 = $a->allocZmmBlock;
      my $m2 = $a->allocZmmBlock;

      K(K => Rd(1..16))->loadZmm(31);
      K(K => Rd(17..32))->loadZmm(30);
      PrintOutRegisterInHex 31, 30;

      $a->putZmmBlock($m1, 31);
      $a->putZmmBlock($m2, 30);
      $a->dump("A");

      $a->getZmmBlock($m1, 30);
      $a->getZmmBlock($m2, 31);
      PrintOutRegisterInHex 31, 30;

      $a->clearZmmBlock($m1);
      $a->freeZmmBlock($m1);
      $a->dump("B");

      $a->freeZmmBlock($m2);
      $a->dump("C");
     });

    ok Assemble eq => <<END, avx512=>1;
  index: .... .... .... ...0
   zmm31: .... ..10 .... ...F  .... ...E .... ...D - .... ...C .... ...B  .... ...A .... ...9 + .... ...8 .... ...7  .... ...6 .... ...5 - .... ...4 .... ...3  .... ...2 .... ...1
   zmm30: .... ..20 .... ..1F  .... ..1E .... ..1D - .... ..1C .... ..1B  .... ..1A .... ..19 + .... ..18 .... ..17  .... ..16 .... ..15 - .... ..14 .... ..13  .... ..12 .... ..11
  A
  Area     Size:     4096    Used:      192
  .... .... .... ...0 | __10 ____ ____ ____  C0__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | .1__ ____ .2__ ____  .3__ ____ .4__ ____  .5__ ____ .6__ ____  .7__ ____ .8__ ____  .9__ ____ .A__ ____  .B__ ____ .C__ ____  .D__ ____ .E__ ____  .F__ ____ 10__ ____
  .... .... .... ..80 | 11__ ____ 12__ ____  13__ ____ 14__ ____  15__ ____ 16__ ____  17__ ____ 18__ ____  19__ ____ 1A__ ____  1B__ ____ 1C__ ____  1D__ ____ 1E__ ____  1F__ ____ 20__ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
   zmm31: .... ..20 .... ..1F  .... ..1E .... ..1D - .... ..1C .... ..1B  .... ..1A .... ..19 + .... ..18 .... ..17  .... ..16 .... ..15 - .... ..14 .... ..13  .... ..12 .... ..11
   zmm30: .... ..10 .... ...F  .... ...E .... ...D - .... ...C .... ...B  .... ...A .... ...9 + .... ...8 .... ...7  .... ...6 .... ...5 - .... ...4 .... ...3  .... ...2 .... ...1
  B
  Area     Size:     4096    Used:      192
  .... .... .... ...0 | __10 ____ ____ ____  C0__ ____ ____ ____  40__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | 11__ ____ 12__ ____  13__ ____ 14__ ____  15__ ____ 16__ ____  17__ ____ 18__ ____  19__ ____ 1A__ ____  1B__ ____ 1C__ ____  1D__ ____ 1E__ ____  1F__ ____ 20__ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  C
  Area     Size:     4096    Used:      192
  .... .... .... ...0 | __10 ____ ____ ____  C0__ ____ ____ ____  80__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | 40__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  index: .... .... .... ...1
   zmm31: .... ..10 .... ...F  .... ...E .... ...D - .... ...C .... ...B  .... ...A .... ...9 + .... ...8 .... ...7  .... ...6 .... ...5 - .... ...4 .... ...3  .... ...2 .... ...1
   zmm30: .... ..20 .... ..1F  .... ..1E .... ..1D - .... ..1C .... ..1B  .... ..1A .... ..19 + .... ..18 .... ..17  .... ..16 .... ..15 - .... ..14 .... ..13  .... ..12 .... ..11
  A
  Area     Size:     4096    Used:      192
  .... .... .... ...0 | __10 ____ ____ ____  C0__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 11__ ____ 12__ ____  13__ ____ 14__ ____  15__ ____ 16__ ____  17__ ____ 18__ ____  19__ ____ 1A__ ____  1B__ ____ 1C__ ____  1D__ ____ 1E__ ____  1F__ ____ 20__ ____
  .... .... .... ..80 | .1__ ____ .2__ ____  .3__ ____ .4__ ____  .5__ ____ .6__ ____  .7__ ____ .8__ ____  .9__ ____ .A__ ____  .B__ ____ .C__ ____  .D__ ____ .E__ ____  .F__ ____ 10__ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
   zmm31: .... ..20 .... ..1F  .... ..1E .... ..1D - .... ..1C .... ..1B  .... ..1A .... ..19 + .... ..18 .... ..17  .... ..16 .... ..15 - .... ..14 .... ..13  .... ..12 .... ..11
   zmm30: .... ..10 .... ...F  .... ...E .... ...D - .... ...C .... ...B  .... ...A .... ...9 + .... ...8 .... ...7  .... ...6 .... ...5 - .... ...4 .... ...3  .... ...2 .... ...1
  B
  Area     Size:     4096    Used:      192
  .... .... .... ...0 | __10 ____ ____ ____  C0__ ____ ____ ____  80__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 11__ ____ 12__ ____  13__ ____ 14__ ____  15__ ____ 16__ ____  17__ ____ 18__ ____  19__ ____ 1A__ ____  1B__ ____ 1C__ ____  1D__ ____ 1E__ ____  1F__ ____ 20__ ____
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  C
  Area     Size:     4096    Used:      192
  .... .... .... ...0 | __10 ____ ____ ____  C0__ ____ ____ ____  40__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 80__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  index: .... .... .... ...2
   zmm31: .... ..10 .... ...F  .... ...E .... ...D - .... ...C .... ...B  .... ...A .... ...9 + .... ...8 .... ...7  .... ...6 .... ...5 - .... ...4 .... ...3  .... ...2 .... ...1
   zmm30: .... ..20 .... ..1F  .... ..1E .... ..1D - .... ..1C .... ..1B  .... ..1A .... ..19 + .... ..18 .... ..17  .... ..16 .... ..15 - .... ..14 .... ..13  .... ..12 .... ..11
  A
  Area     Size:     4096    Used:      192
  .... .... .... ...0 | __10 ____ ____ ____  C0__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | .1__ ____ .2__ ____  .3__ ____ .4__ ____  .5__ ____ .6__ ____  .7__ ____ .8__ ____  .9__ ____ .A__ ____  .B__ ____ .C__ ____  .D__ ____ .E__ ____  .F__ ____ 10__ ____
  .... .... .... ..80 | 11__ ____ 12__ ____  13__ ____ 14__ ____  15__ ____ 16__ ____  17__ ____ 18__ ____  19__ ____ 1A__ ____  1B__ ____ 1C__ ____  1D__ ____ 1E__ ____  1F__ ____ 20__ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
   zmm31: .... ..20 .... ..1F  .... ..1E .... ..1D - .... ..1C .... ..1B  .... ..1A .... ..19 + .... ..18 .... ..17  .... ..16 .... ..15 - .... ..14 .... ..13  .... ..12 .... ..11
   zmm30: .... ..10 .... ...F  .... ...E .... ...D - .... ...C .... ...B  .... ...A .... ...9 + .... ...8 .... ...7  .... ...6 .... ...5 - .... ...4 .... ...3  .... ...2 .... ...1
  B
  Area     Size:     4096    Used:      192
  .... .... .... ...0 | __10 ____ ____ ____  C0__ ____ ____ ____  40__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | 11__ ____ 12__ ____  13__ ____ 14__ ____  15__ ____ 16__ ____  17__ ____ 18__ ____  19__ ____ 1A__ ____  1B__ ____ 1C__ ____  1D__ ____ 1E__ ____  1F__ ____ 20__ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  C
  Area     Size:     4096    Used:      192
  .... .... .... ...0 | __10 ____ ____ ____  C0__ ____ ____ ____  80__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | 40__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  END

Areas as Stacks

Use an area as a stack. If the area is simultaneouls used for other operations confusion will ensue.

Nasm::X86::Area::push($area, $var)

Push the contents of a variable into an area

     Parameter  Description
  1  $area      Area descriptor
  2  $var       Variable

Example:

    my $a = CreateArea(stack=>1);

    $a->stackVariableSize->outNL;
    $a->dump("AA");
    $a->push(K key => 0x11111111);
    $a->stackVariableSize->outNL;
    $a->dump("AA");

    $a->push(K key => 0x22222222);                                                # 12
    $a->stackVariableSize->outNL;
    $a->dump("AA");

    PrintOutStringNL "Peek";
    $a->peek(1)->outNL;
    $a->stackVariableSize->outNL;
    $a->peek(2)->outNL;
    $a->stackVariableSize->outNL;
    $a->stackSize->outNL;

    PrintOutStringNL "stackVariable";
    $a->stackVariable(K key => 0)->outNL;
    $a->stackVariable(K key => 1)->outNL;

    PrintOutStringNL "Pop";
    my $s1 = $a->pop;                                                             #  9
       $s1->outNL;
    $a->stackVariableSize->outNL;
    my $s2 = $a->pop;
       $s2->outNL;
    $a->stackVariableSize->outNL;
    $a->dump("pop1");
    $a->dump("pop2");

    ClearRegisters zmm1, zmm2;

    K(key => 0x22222222)->qIntoZ(1, 16);
    K(key => 0x33333333)->qIntoZ(1, 32);
    K(key => 0x44444444)->qIntoZ(1, 48);

    K(key => 0x55555555)->qIntoZ(2, 16);
    K(key => 0x66666666)->qIntoZ(2, 32);
    K(key => 0x77777777)->qIntoZ(2, 48);

    PrintOutStringNL "Push";
    $a->pushZmm(1)->outNL;
    $a->pushZmm(2)->outNL;

    $a->dump("zmm 1, 2");
    $a->peekZmm(1, 1)->outNL;
    $a->peekZmm(2, 2)->outNL;
    PrintOutStringNL "Peek";
    PrintOutRegisterInHex zmm1, zmm2;

    $a->popZmm(3);
    $a->popZmm(4);
    PrintOutStringNL "Pop";
    PrintOutRegisterInHex zmm3, zmm4;

    ok Assemble eq => <<END, clocks=>391;
  size: .... .... .... ...0
  AA
  Area     Size:     4096    Used:       64
  .... .... .... ...0 | __10 ____ ____ ____  40__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  size: .... .... .... ...1
  AA
  Area     Size:     4096    Used:       72
  .... .... .... ...0 | __10 ____ ____ ____  48__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 1111 1111 ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  size: .... .... .... ...2
  AA
  Area     Size:     4096    Used:       80
  .... .... .... ...0 | __10 ____ ____ ____  50__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 1111 1111 ____ ____  2222 2222 ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  Peek
  pop: .... .... 2222 2222
  size: .... .... .... ...2
  pop: .... .... 1111 1111
  size: .... .... .... ...2
  stackSize: .... .... .... ..10
  stackVariable
  pop: .... .... 1111 1111
  pop: .... .... 2222 2222
  Pop
  pop: .... .... 2222 2222
  size: .... .... .... ...1
  pop: .... .... 1111 1111
  size: .... .... .... ...0
  pop1
  Area     Size:     4096    Used:       64
  .... .... .... ...0 | __10 ____ ____ ____  40__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 1111 1111 ____ ____  2222 2222 ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  pop2
  Area     Size:     4096    Used:       64
  .... .... .... ...0 | __10 ____ ____ ____  40__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 1111 1111 ____ ____  2222 2222 ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  Push
  zmmStackOffset: .... .... .... ..40
  zmmStackOffset: .... .... .... ..80
  zmm 1, 2
  Area     Size:     4096    Used:      192
  .... .... .... ...0 | __10 ____ ____ ____  C0__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | ____ ____ ____ ____  ____ ____ ____ ____  2222 2222 ____ ____  ____ ____ ____ ____  3333 3333 ____ ____  ____ ____ ____ ____  4444 4444 ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  5555 5555 ____ ____  ____ ____ ____ ____  6666 6666 ____ ____  ____ ____ ____ ____  7777 7777 ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  offset: .... .... .... ..80
  offset: .... .... .... ..40
  Peek
    zmm1: .... .... .... ...0  .... .... 7777 7777 - .... .... .... ...0  .... .... 6666 6666 + .... .... .... ...0  .... .... 5555 5555 - .... .... .... ...0  .... .... .... ...0
    zmm2: .... .... .... ...0  .... .... 4444 4444 - .... .... .... ...0  .... .... 3333 3333 + .... .... .... ...0  .... .... 2222 2222 - .... .... .... ...0  .... .... .... ...0
  Pop
    zmm3: .... .... .... ...0  .... .... 7777 7777 - .... .... .... ...0  .... .... 6666 6666 + .... .... .... ...0  .... .... 5555 5555 - .... .... .... ...0  .... .... .... ...0
    zmm4: .... .... .... ...0  .... .... 4444 4444 - .... .... .... ...0  .... .... 3333 3333 + .... .... .... ...0  .... .... 2222 2222 - .... .... .... ...0  .... .... .... ...0
  END

Nasm::X86::Area::stackSize($area)

Size of the stack in an area being used as a stack

     Parameter  Description
  1  $area      Area descriptor

Example:

    my $a = CreateArea(stack=>1);

    $a->stackVariableSize->outNL;
    $a->dump("AA");
    $a->push(K key => 0x11111111);
    $a->stackVariableSize->outNL;
    $a->dump("AA");

    $a->push(K key => 0x22222222);                                                # 12
    $a->stackVariableSize->outNL;
    $a->dump("AA");

    PrintOutStringNL "Peek";
    $a->peek(1)->outNL;
    $a->stackVariableSize->outNL;
    $a->peek(2)->outNL;
    $a->stackVariableSize->outNL;
    $a->stackSize->outNL;

    PrintOutStringNL "stackVariable";
    $a->stackVariable(K key => 0)->outNL;
    $a->stackVariable(K key => 1)->outNL;

    PrintOutStringNL "Pop";
    my $s1 = $a->pop;                                                             #  9
       $s1->outNL;
    $a->stackVariableSize->outNL;
    my $s2 = $a->pop;
       $s2->outNL;
    $a->stackVariableSize->outNL;
    $a->dump("pop1");
    $a->dump("pop2");

    ClearRegisters zmm1, zmm2;

    K(key => 0x22222222)->qIntoZ(1, 16);
    K(key => 0x33333333)->qIntoZ(1, 32);
    K(key => 0x44444444)->qIntoZ(1, 48);

    K(key => 0x55555555)->qIntoZ(2, 16);
    K(key => 0x66666666)->qIntoZ(2, 32);
    K(key => 0x77777777)->qIntoZ(2, 48);

    PrintOutStringNL "Push";
    $a->pushZmm(1)->outNL;
    $a->pushZmm(2)->outNL;

    $a->dump("zmm 1, 2");
    $a->peekZmm(1, 1)->outNL;
    $a->peekZmm(2, 2)->outNL;
    PrintOutStringNL "Peek";
    PrintOutRegisterInHex zmm1, zmm2;

    $a->popZmm(3);
    $a->popZmm(4);
    PrintOutStringNL "Pop";
    PrintOutRegisterInHex zmm3, zmm4;

    ok Assemble eq => <<END, clocks=>391;
  size: .... .... .... ...0
  AA
  Area     Size:     4096    Used:       64
  .... .... .... ...0 | __10 ____ ____ ____  40__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  size: .... .... .... ...1
  AA
  Area     Size:     4096    Used:       72
  .... .... .... ...0 | __10 ____ ____ ____  48__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 1111 1111 ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  size: .... .... .... ...2
  AA
  Area     Size:     4096    Used:       80
  .... .... .... ...0 | __10 ____ ____ ____  50__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 1111 1111 ____ ____  2222 2222 ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  Peek
  pop: .... .... 2222 2222
  size: .... .... .... ...2
  pop: .... .... 1111 1111
  size: .... .... .... ...2
  stackSize: .... .... .... ..10
  stackVariable
  pop: .... .... 1111 1111
  pop: .... .... 2222 2222
  Pop
  pop: .... .... 2222 2222
  size: .... .... .... ...1
  pop: .... .... 1111 1111
  size: .... .... .... ...0
  pop1
  Area     Size:     4096    Used:       64
  .... .... .... ...0 | __10 ____ ____ ____  40__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 1111 1111 ____ ____  2222 2222 ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  pop2
  Area     Size:     4096    Used:       64
  .... .... .... ...0 | __10 ____ ____ ____  40__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 1111 1111 ____ ____  2222 2222 ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  Push
  zmmStackOffset: .... .... .... ..40
  zmmStackOffset: .... .... .... ..80
  zmm 1, 2
  Area     Size:     4096    Used:      192
  .... .... .... ...0 | __10 ____ ____ ____  C0__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | ____ ____ ____ ____  ____ ____ ____ ____  2222 2222 ____ ____  ____ ____ ____ ____  3333 3333 ____ ____  ____ ____ ____ ____  4444 4444 ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  5555 5555 ____ ____  ____ ____ ____ ____  6666 6666 ____ ____  ____ ____ ____ ____  7777 7777 ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  offset: .... .... .... ..80
  offset: .... .... .... ..40
  Peek
    zmm1: .... .... .... ...0  .... .... 7777 7777 - .... .... .... ...0  .... .... 6666 6666 + .... .... .... ...0  .... .... 5555 5555 - .... .... .... ...0  .... .... .... ...0
    zmm2: .... .... .... ...0  .... .... 4444 4444 - .... .... .... ...0  .... .... 3333 3333 + .... .... .... ...0  .... .... 2222 2222 - .... .... .... ...0  .... .... .... ...0
  Pop
    zmm3: .... .... .... ...0  .... .... 7777 7777 - .... .... .... ...0  .... .... 6666 6666 + .... .... .... ...0  .... .... 5555 5555 - .... .... .... ...0  .... .... .... ...0
    zmm4: .... .... .... ...0  .... .... 4444 4444 - .... .... .... ...0  .... .... 3333 3333 + .... .... .... ...0  .... .... 2222 2222 - .... .... .... ...0  .... .... .... ...0
  END

Nasm::X86::Area::peek($area, $back)

Peek at a variable on the stack

     Parameter  Description
  1  $area      Area descriptor
  2  $back      How far back to look in the stack with the top most element being at one.

Example:

    my $a = CreateArea(stack=>1);

    $a->stackVariableSize->outNL;
    $a->dump("AA");
    $a->push(K key => 0x11111111);
    $a->stackVariableSize->outNL;
    $a->dump("AA");

    $a->push(K key => 0x22222222);                                                # 12
    $a->stackVariableSize->outNL;
    $a->dump("AA");

    PrintOutStringNL "Peek";
    $a->peek(1)->outNL;
    $a->stackVariableSize->outNL;
    $a->peek(2)->outNL;
    $a->stackVariableSize->outNL;
    $a->stackSize->outNL;

    PrintOutStringNL "stackVariable";
    $a->stackVariable(K key => 0)->outNL;
    $a->stackVariable(K key => 1)->outNL;

    PrintOutStringNL "Pop";
    my $s1 = $a->pop;                                                             #  9
       $s1->outNL;
    $a->stackVariableSize->outNL;
    my $s2 = $a->pop;
       $s2->outNL;
    $a->stackVariableSize->outNL;
    $a->dump("pop1");
    $a->dump("pop2");

    ClearRegisters zmm1, zmm2;

    K(key => 0x22222222)->qIntoZ(1, 16);
    K(key => 0x33333333)->qIntoZ(1, 32);
    K(key => 0x44444444)->qIntoZ(1, 48);

    K(key => 0x55555555)->qIntoZ(2, 16);
    K(key => 0x66666666)->qIntoZ(2, 32);
    K(key => 0x77777777)->qIntoZ(2, 48);

    PrintOutStringNL "Push";
    $a->pushZmm(1)->outNL;
    $a->pushZmm(2)->outNL;

    $a->dump("zmm 1, 2");
    $a->peekZmm(1, 1)->outNL;
    $a->peekZmm(2, 2)->outNL;
    PrintOutStringNL "Peek";
    PrintOutRegisterInHex zmm1, zmm2;

    $a->popZmm(3);
    $a->popZmm(4);
    PrintOutStringNL "Pop";
    PrintOutRegisterInHex zmm3, zmm4;

    ok Assemble eq => <<END, clocks=>391;
  size: .... .... .... ...0
  AA
  Area     Size:     4096    Used:       64
  .... .... .... ...0 | __10 ____ ____ ____  40__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  size: .... .... .... ...1
  AA
  Area     Size:     4096    Used:       72
  .... .... .... ...0 | __10 ____ ____ ____  48__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 1111 1111 ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  size: .... .... .... ...2
  AA
  Area     Size:     4096    Used:       80
  .... .... .... ...0 | __10 ____ ____ ____  50__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 1111 1111 ____ ____  2222 2222 ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  Peek
  pop: .... .... 2222 2222
  size: .... .... .... ...2
  pop: .... .... 1111 1111
  size: .... .... .... ...2
  stackSize: .... .... .... ..10
  stackVariable
  pop: .... .... 1111 1111
  pop: .... .... 2222 2222
  Pop
  pop: .... .... 2222 2222
  size: .... .... .... ...1
  pop: .... .... 1111 1111
  size: .... .... .... ...0
  pop1
  Area     Size:     4096    Used:       64
  .... .... .... ...0 | __10 ____ ____ ____  40__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 1111 1111 ____ ____  2222 2222 ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  pop2
  Area     Size:     4096    Used:       64
  .... .... .... ...0 | __10 ____ ____ ____  40__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 1111 1111 ____ ____  2222 2222 ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  Push
  zmmStackOffset: .... .... .... ..40
  zmmStackOffset: .... .... .... ..80
  zmm 1, 2
  Area     Size:     4096    Used:      192
  .... .... .... ...0 | __10 ____ ____ ____  C0__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | ____ ____ ____ ____  ____ ____ ____ ____  2222 2222 ____ ____  ____ ____ ____ ____  3333 3333 ____ ____  ____ ____ ____ ____  4444 4444 ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  5555 5555 ____ ____  ____ ____ ____ ____  6666 6666 ____ ____  ____ ____ ____ ____  7777 7777 ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  offset: .... .... .... ..80
  offset: .... .... .... ..40
  Peek
    zmm1: .... .... .... ...0  .... .... 7777 7777 - .... .... .... ...0  .... .... 6666 6666 + .... .... .... ...0  .... .... 5555 5555 - .... .... .... ...0  .... .... .... ...0
    zmm2: .... .... .... ...0  .... .... 4444 4444 - .... .... .... ...0  .... .... 3333 3333 + .... .... .... ...0  .... .... 2222 2222 - .... .... .... ...0  .... .... .... ...0
  Pop
    zmm3: .... .... .... ...0  .... .... 7777 7777 - .... .... .... ...0  .... .... 6666 6666 + .... .... .... ...0  .... .... 5555 5555 - .... .... .... ...0  .... .... .... ...0
    zmm4: .... .... .... ...0  .... .... 4444 4444 - .... .... .... ...0  .... .... 3333 3333 + .... .... .... ...0  .... .... 2222 2222 - .... .... .... ...0  .... .... .... ...0
  END

Nasm::X86::Area::stackVariable($area, $index)

Peek at the variable indexed variable on the stack

     Parameter  Description
  1  $area      Area descriptor
  2  $index     Index of element sought

Example:

    my $a = CreateArea(stack=>1);

    $a->stackVariableSize->outNL;
    $a->dump("AA");
    $a->push(K key => 0x11111111);
    $a->stackVariableSize->outNL;
    $a->dump("AA");

    $a->push(K key => 0x22222222);                                                # 12
    $a->stackVariableSize->outNL;
    $a->dump("AA");

    PrintOutStringNL "Peek";
    $a->peek(1)->outNL;
    $a->stackVariableSize->outNL;
    $a->peek(2)->outNL;
    $a->stackVariableSize->outNL;
    $a->stackSize->outNL;

    PrintOutStringNL "stackVariable";
    $a->stackVariable(K key => 0)->outNL;
    $a->stackVariable(K key => 1)->outNL;

    PrintOutStringNL "Pop";
    my $s1 = $a->pop;                                                             #  9
       $s1->outNL;
    $a->stackVariableSize->outNL;
    my $s2 = $a->pop;
       $s2->outNL;
    $a->stackVariableSize->outNL;
    $a->dump("pop1");
    $a->dump("pop2");

    ClearRegisters zmm1, zmm2;

    K(key => 0x22222222)->qIntoZ(1, 16);
    K(key => 0x33333333)->qIntoZ(1, 32);
    K(key => 0x44444444)->qIntoZ(1, 48);

    K(key => 0x55555555)->qIntoZ(2, 16);
    K(key => 0x66666666)->qIntoZ(2, 32);
    K(key => 0x77777777)->qIntoZ(2, 48);

    PrintOutStringNL "Push";
    $a->pushZmm(1)->outNL;
    $a->pushZmm(2)->outNL;

    $a->dump("zmm 1, 2");
    $a->peekZmm(1, 1)->outNL;
    $a->peekZmm(2, 2)->outNL;
    PrintOutStringNL "Peek";
    PrintOutRegisterInHex zmm1, zmm2;

    $a->popZmm(3);
    $a->popZmm(4);
    PrintOutStringNL "Pop";
    PrintOutRegisterInHex zmm3, zmm4;

    ok Assemble eq => <<END, clocks=>391;
  size: .... .... .... ...0
  AA
  Area     Size:     4096    Used:       64
  .... .... .... ...0 | __10 ____ ____ ____  40__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  size: .... .... .... ...1
  AA
  Area     Size:     4096    Used:       72
  .... .... .... ...0 | __10 ____ ____ ____  48__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 1111 1111 ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  size: .... .... .... ...2
  AA
  Area     Size:     4096    Used:       80
  .... .... .... ...0 | __10 ____ ____ ____  50__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 1111 1111 ____ ____  2222 2222 ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  Peek
  pop: .... .... 2222 2222
  size: .... .... .... ...2
  pop: .... .... 1111 1111
  size: .... .... .... ...2
  stackSize: .... .... .... ..10
  stackVariable
  pop: .... .... 1111 1111
  pop: .... .... 2222 2222
  Pop
  pop: .... .... 2222 2222
  size: .... .... .... ...1
  pop: .... .... 1111 1111
  size: .... .... .... ...0
  pop1
  Area     Size:     4096    Used:       64
  .... .... .... ...0 | __10 ____ ____ ____  40__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 1111 1111 ____ ____  2222 2222 ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  pop2
  Area     Size:     4096    Used:       64
  .... .... .... ...0 | __10 ____ ____ ____  40__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 1111 1111 ____ ____  2222 2222 ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  Push
  zmmStackOffset: .... .... .... ..40
  zmmStackOffset: .... .... .... ..80
  zmm 1, 2
  Area     Size:     4096    Used:      192
  .... .... .... ...0 | __10 ____ ____ ____  C0__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | ____ ____ ____ ____  ____ ____ ____ ____  2222 2222 ____ ____  ____ ____ ____ ____  3333 3333 ____ ____  ____ ____ ____ ____  4444 4444 ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  5555 5555 ____ ____  ____ ____ ____ ____  6666 6666 ____ ____  ____ ____ ____ ____  7777 7777 ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  offset: .... .... .... ..80
  offset: .... .... .... ..40
  Peek
    zmm1: .... .... .... ...0  .... .... 7777 7777 - .... .... .... ...0  .... .... 6666 6666 + .... .... .... ...0  .... .... 5555 5555 - .... .... .... ...0  .... .... .... ...0
    zmm2: .... .... .... ...0  .... .... 4444 4444 - .... .... .... ...0  .... .... 3333 3333 + .... .... .... ...0  .... .... 2222 2222 - .... .... .... ...0  .... .... .... ...0
  Pop
    zmm3: .... .... .... ...0  .... .... 7777 7777 - .... .... .... ...0  .... .... 6666 6666 + .... .... .... ...0  .... .... 5555 5555 - .... .... .... ...0  .... .... .... ...0
    zmm4: .... .... .... ...0  .... .... 4444 4444 - .... .... .... ...0  .... .... 3333 3333 + .... .... .... ...0  .... .... 2222 2222 - .... .... .... ...0  .... .... .... ...0
  END

Nasm::X86::Area::stackVariableSize($area)

Size of a stack of variables in an area.

     Parameter  Description
  1  $area      Area descriptor

Example:

    my $a = CreateArea(stack=>1);

    $a->stackVariableSize->outNL;
    $a->dump("AA");
    $a->push(K key => 0x11111111);
    $a->stackVariableSize->outNL;
    $a->dump("AA");

    $a->push(K key => 0x22222222);                                                # 12
    $a->stackVariableSize->outNL;
    $a->dump("AA");

    PrintOutStringNL "Peek";
    $a->peek(1)->outNL;
    $a->stackVariableSize->outNL;
    $a->peek(2)->outNL;
    $a->stackVariableSize->outNL;
    $a->stackSize->outNL;

    PrintOutStringNL "stackVariable";
    $a->stackVariable(K key => 0)->outNL;
    $a->stackVariable(K key => 1)->outNL;

    PrintOutStringNL "Pop";
    my $s1 = $a->pop;                                                             #  9
       $s1->outNL;
    $a->stackVariableSize->outNL;
    my $s2 = $a->pop;
       $s2->outNL;
    $a->stackVariableSize->outNL;
    $a->dump("pop1");
    $a->dump("pop2");

    ClearRegisters zmm1, zmm2;

    K(key => 0x22222222)->qIntoZ(1, 16);
    K(key => 0x33333333)->qIntoZ(1, 32);
    K(key => 0x44444444)->qIntoZ(1, 48);

    K(key => 0x55555555)->qIntoZ(2, 16);
    K(key => 0x66666666)->qIntoZ(2, 32);
    K(key => 0x77777777)->qIntoZ(2, 48);

    PrintOutStringNL "Push";
    $a->pushZmm(1)->outNL;
    $a->pushZmm(2)->outNL;

    $a->dump("zmm 1, 2");
    $a->peekZmm(1, 1)->outNL;
    $a->peekZmm(2, 2)->outNL;
    PrintOutStringNL "Peek";
    PrintOutRegisterInHex zmm1, zmm2;

    $a->popZmm(3);
    $a->popZmm(4);
    PrintOutStringNL "Pop";
    PrintOutRegisterInHex zmm3, zmm4;

    ok Assemble eq => <<END, clocks=>391;
  size: .... .... .... ...0
  AA
  Area     Size:     4096    Used:       64
  .... .... .... ...0 | __10 ____ ____ ____  40__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  size: .... .... .... ...1
  AA
  Area     Size:     4096    Used:       72
  .... .... .... ...0 | __10 ____ ____ ____  48__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 1111 1111 ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  size: .... .... .... ...2
  AA
  Area     Size:     4096    Used:       80
  .... .... .... ...0 | __10 ____ ____ ____  50__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 1111 1111 ____ ____  2222 2222 ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  Peek
  pop: .... .... 2222 2222
  size: .... .... .... ...2
  pop: .... .... 1111 1111
  size: .... .... .... ...2
  stackSize: .... .... .... ..10
  stackVariable
  pop: .... .... 1111 1111
  pop: .... .... 2222 2222
  Pop
  pop: .... .... 2222 2222
  size: .... .... .... ...1
  pop: .... .... 1111 1111
  size: .... .... .... ...0
  pop1
  Area     Size:     4096    Used:       64
  .... .... .... ...0 | __10 ____ ____ ____  40__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 1111 1111 ____ ____  2222 2222 ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  pop2
  Area     Size:     4096    Used:       64
  .... .... .... ...0 | __10 ____ ____ ____  40__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 1111 1111 ____ ____  2222 2222 ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  Push
  zmmStackOffset: .... .... .... ..40
  zmmStackOffset: .... .... .... ..80
  zmm 1, 2
  Area     Size:     4096    Used:      192
  .... .... .... ...0 | __10 ____ ____ ____  C0__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | ____ ____ ____ ____  ____ ____ ____ ____  2222 2222 ____ ____  ____ ____ ____ ____  3333 3333 ____ ____  ____ ____ ____ ____  4444 4444 ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  5555 5555 ____ ____  ____ ____ ____ ____  6666 6666 ____ ____  ____ ____ ____ ____  7777 7777 ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  offset: .... .... .... ..80
  offset: .... .... .... ..40
  Peek
    zmm1: .... .... .... ...0  .... .... 7777 7777 - .... .... .... ...0  .... .... 6666 6666 + .... .... .... ...0  .... .... 5555 5555 - .... .... .... ...0  .... .... .... ...0
    zmm2: .... .... .... ...0  .... .... 4444 4444 - .... .... .... ...0  .... .... 3333 3333 + .... .... .... ...0  .... .... 2222 2222 - .... .... .... ...0  .... .... .... ...0
  Pop
    zmm3: .... .... .... ...0  .... .... 7777 7777 - .... .... .... ...0  .... .... 6666 6666 + .... .... .... ...0  .... .... 5555 5555 - .... .... .... ...0  .... .... .... ...0
    zmm4: .... .... .... ...0  .... .... 4444 4444 - .... .... .... ...0  .... .... 3333 3333 + .... .... .... ...0  .... .... 2222 2222 - .... .... .... ...0  .... .... .... ...0
  END

Nasm::X86::Area::pop($area)

Pop a variable from the stack in an area being used as a stack

     Parameter  Description
  1  $area      Area descriptor

Example:

    my $a = CreateArea(stack=>1);

    $a->stackVariableSize->outNL;
    $a->dump("AA");
    $a->push(K key => 0x11111111);
    $a->stackVariableSize->outNL;
    $a->dump("AA");

    $a->push(K key => 0x22222222);                                                # 12
    $a->stackVariableSize->outNL;
    $a->dump("AA");

    PrintOutStringNL "Peek";
    $a->peek(1)->outNL;
    $a->stackVariableSize->outNL;
    $a->peek(2)->outNL;
    $a->stackVariableSize->outNL;
    $a->stackSize->outNL;

    PrintOutStringNL "stackVariable";
    $a->stackVariable(K key => 0)->outNL;
    $a->stackVariable(K key => 1)->outNL;

    PrintOutStringNL "Pop";
    my $s1 = $a->pop;                                                             #  9
       $s1->outNL;
    $a->stackVariableSize->outNL;
    my $s2 = $a->pop;
       $s2->outNL;
    $a->stackVariableSize->outNL;
    $a->dump("pop1");
    $a->dump("pop2");

    ClearRegisters zmm1, zmm2;

    K(key => 0x22222222)->qIntoZ(1, 16);
    K(key => 0x33333333)->qIntoZ(1, 32);
    K(key => 0x44444444)->qIntoZ(1, 48);

    K(key => 0x55555555)->qIntoZ(2, 16);
    K(key => 0x66666666)->qIntoZ(2, 32);
    K(key => 0x77777777)->qIntoZ(2, 48);

    PrintOutStringNL "Push";
    $a->pushZmm(1)->outNL;
    $a->pushZmm(2)->outNL;

    $a->dump("zmm 1, 2");
    $a->peekZmm(1, 1)->outNL;
    $a->peekZmm(2, 2)->outNL;
    PrintOutStringNL "Peek";
    PrintOutRegisterInHex zmm1, zmm2;

    $a->popZmm(3);
    $a->popZmm(4);
    PrintOutStringNL "Pop";
    PrintOutRegisterInHex zmm3, zmm4;

    ok Assemble eq => <<END, clocks=>391;
  size: .... .... .... ...0
  AA
  Area     Size:     4096    Used:       64
  .... .... .... ...0 | __10 ____ ____ ____  40__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  size: .... .... .... ...1
  AA
  Area     Size:     4096    Used:       72
  .... .... .... ...0 | __10 ____ ____ ____  48__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 1111 1111 ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  size: .... .... .... ...2
  AA
  Area     Size:     4096    Used:       80
  .... .... .... ...0 | __10 ____ ____ ____  50__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 1111 1111 ____ ____  2222 2222 ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  Peek
  pop: .... .... 2222 2222
  size: .... .... .... ...2
  pop: .... .... 1111 1111
  size: .... .... .... ...2
  stackSize: .... .... .... ..10
  stackVariable
  pop: .... .... 1111 1111
  pop: .... .... 2222 2222
  Pop
  pop: .... .... 2222 2222
  size: .... .... .... ...1
  pop: .... .... 1111 1111
  size: .... .... .... ...0
  pop1
  Area     Size:     4096    Used:       64
  .... .... .... ...0 | __10 ____ ____ ____  40__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 1111 1111 ____ ____  2222 2222 ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  pop2
  Area     Size:     4096    Used:       64
  .... .... .... ...0 | __10 ____ ____ ____  40__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 1111 1111 ____ ____  2222 2222 ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  Push
  zmmStackOffset: .... .... .... ..40
  zmmStackOffset: .... .... .... ..80
  zmm 1, 2
  Area     Size:     4096    Used:      192
  .... .... .... ...0 | __10 ____ ____ ____  C0__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | ____ ____ ____ ____  ____ ____ ____ ____  2222 2222 ____ ____  ____ ____ ____ ____  3333 3333 ____ ____  ____ ____ ____ ____  4444 4444 ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  5555 5555 ____ ____  ____ ____ ____ ____  6666 6666 ____ ____  ____ ____ ____ ____  7777 7777 ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  offset: .... .... .... ..80
  offset: .... .... .... ..40
  Peek
    zmm1: .... .... .... ...0  .... .... 7777 7777 - .... .... .... ...0  .... .... 6666 6666 + .... .... .... ...0  .... .... 5555 5555 - .... .... .... ...0  .... .... .... ...0
    zmm2: .... .... .... ...0  .... .... 4444 4444 - .... .... .... ...0  .... .... 3333 3333 + .... .... .... ...0  .... .... 2222 2222 - .... .... .... ...0  .... .... .... ...0
  Pop
    zmm3: .... .... .... ...0  .... .... 7777 7777 - .... .... .... ...0  .... .... 6666 6666 + .... .... .... ...0  .... .... 5555 5555 - .... .... .... ...0  .... .... .... ...0
    zmm4: .... .... .... ...0  .... .... 4444 4444 - .... .... .... ...0  .... .... 3333 3333 + .... .... .... ...0  .... .... 2222 2222 - .... .... .... ...0  .... .... .... ...0
  END

Nasm::X86::Area::pushZmm($area, $zmm)

Push the contents of a zmm register into an area.

     Parameter  Description
  1  $area      Area descriptor
  2  $zmm       Zmm number

Example:

    my $a = CreateArea(stack=>1);

    $a->stackVariableSize->outNL;
    $a->dump("AA");
    $a->push(K key => 0x11111111);
    $a->stackVariableSize->outNL;
    $a->dump("AA");

    $a->push(K key => 0x22222222);                                                # 12
    $a->stackVariableSize->outNL;
    $a->dump("AA");

    PrintOutStringNL "Peek";
    $a->peek(1)->outNL;
    $a->stackVariableSize->outNL;
    $a->peek(2)->outNL;
    $a->stackVariableSize->outNL;
    $a->stackSize->outNL;

    PrintOutStringNL "stackVariable";
    $a->stackVariable(K key => 0)->outNL;
    $a->stackVariable(K key => 1)->outNL;

    PrintOutStringNL "Pop";
    my $s1 = $a->pop;                                                             #  9
       $s1->outNL;
    $a->stackVariableSize->outNL;
    my $s2 = $a->pop;
       $s2->outNL;
    $a->stackVariableSize->outNL;
    $a->dump("pop1");
    $a->dump("pop2");

    ClearRegisters zmm1, zmm2;

    K(key => 0x22222222)->qIntoZ(1, 16);
    K(key => 0x33333333)->qIntoZ(1, 32);
    K(key => 0x44444444)->qIntoZ(1, 48);

    K(key => 0x55555555)->qIntoZ(2, 16);
    K(key => 0x66666666)->qIntoZ(2, 32);
    K(key => 0x77777777)->qIntoZ(2, 48);

    PrintOutStringNL "Push";
    $a->pushZmm(1)->outNL;
    $a->pushZmm(2)->outNL;

    $a->dump("zmm 1, 2");
    $a->peekZmm(1, 1)->outNL;
    $a->peekZmm(2, 2)->outNL;
    PrintOutStringNL "Peek";
    PrintOutRegisterInHex zmm1, zmm2;

    $a->popZmm(3);
    $a->popZmm(4);
    PrintOutStringNL "Pop";
    PrintOutRegisterInHex zmm3, zmm4;

    ok Assemble eq => <<END, clocks=>391;
  size: .... .... .... ...0
  AA
  Area     Size:     4096    Used:       64
  .... .... .... ...0 | __10 ____ ____ ____  40__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  size: .... .... .... ...1
  AA
  Area     Size:     4096    Used:       72
  .... .... .... ...0 | __10 ____ ____ ____  48__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 1111 1111 ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  size: .... .... .... ...2
  AA
  Area     Size:     4096    Used:       80
  .... .... .... ...0 | __10 ____ ____ ____  50__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 1111 1111 ____ ____  2222 2222 ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  Peek
  pop: .... .... 2222 2222
  size: .... .... .... ...2
  pop: .... .... 1111 1111
  size: .... .... .... ...2
  stackSize: .... .... .... ..10
  stackVariable
  pop: .... .... 1111 1111
  pop: .... .... 2222 2222
  Pop
  pop: .... .... 2222 2222
  size: .... .... .... ...1
  pop: .... .... 1111 1111
  size: .... .... .... ...0
  pop1
  Area     Size:     4096    Used:       64
  .... .... .... ...0 | __10 ____ ____ ____  40__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 1111 1111 ____ ____  2222 2222 ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  pop2
  Area     Size:     4096    Used:       64
  .... .... .... ...0 | __10 ____ ____ ____  40__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 1111 1111 ____ ____  2222 2222 ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  Push
  zmmStackOffset: .... .... .... ..40
  zmmStackOffset: .... .... .... ..80
  zmm 1, 2
  Area     Size:     4096    Used:      192
  .... .... .... ...0 | __10 ____ ____ ____  C0__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | ____ ____ ____ ____  ____ ____ ____ ____  2222 2222 ____ ____  ____ ____ ____ ____  3333 3333 ____ ____  ____ ____ ____ ____  4444 4444 ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  5555 5555 ____ ____  ____ ____ ____ ____  6666 6666 ____ ____  ____ ____ ____ ____  7777 7777 ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  offset: .... .... .... ..80
  offset: .... .... .... ..40
  Peek
    zmm1: .... .... .... ...0  .... .... 7777 7777 - .... .... .... ...0  .... .... 6666 6666 + .... .... .... ...0  .... .... 5555 5555 - .... .... .... ...0  .... .... .... ...0
    zmm2: .... .... .... ...0  .... .... 4444 4444 - .... .... .... ...0  .... .... 3333 3333 + .... .... .... ...0  .... .... 2222 2222 - .... .... .... ...0  .... .... .... ...0
  Pop
    zmm3: .... .... .... ...0  .... .... 7777 7777 - .... .... .... ...0  .... .... 6666 6666 + .... .... .... ...0  .... .... 5555 5555 - .... .... .... ...0  .... .... .... ...0
    zmm4: .... .... .... ...0  .... .... 4444 4444 - .... .... .... ...0  .... .... 3333 3333 + .... .... .... ...0  .... .... 2222 2222 - .... .... .... ...0  .... .... .... ...0
  END

Nasm::X86::Area::peekZmm($area, $zmm, $back)

Peek at a zmm register from the stack in an area being used as a stack and return a variable containing its offset in the area so we can update the pushed zmm if desired.

     Parameter  Description
  1  $area      Area descriptor
  2  $zmm       Zmm number
  3  $back      How far back to look in the stack with the top most element being at one.

Example:

    my $a = CreateArea(stack=>1);

    $a->stackVariableSize->outNL;
    $a->dump("AA");
    $a->push(K key => 0x11111111);
    $a->stackVariableSize->outNL;
    $a->dump("AA");

    $a->push(K key => 0x22222222);                                                # 12
    $a->stackVariableSize->outNL;
    $a->dump("AA");

    PrintOutStringNL "Peek";
    $a->peek(1)->outNL;
    $a->stackVariableSize->outNL;
    $a->peek(2)->outNL;
    $a->stackVariableSize->outNL;
    $a->stackSize->outNL;

    PrintOutStringNL "stackVariable";
    $a->stackVariable(K key => 0)->outNL;
    $a->stackVariable(K key => 1)->outNL;

    PrintOutStringNL "Pop";
    my $s1 = $a->pop;                                                             #  9
       $s1->outNL;
    $a->stackVariableSize->outNL;
    my $s2 = $a->pop;
       $s2->outNL;
    $a->stackVariableSize->outNL;
    $a->dump("pop1");
    $a->dump("pop2");

    ClearRegisters zmm1, zmm2;

    K(key => 0x22222222)->qIntoZ(1, 16);
    K(key => 0x33333333)->qIntoZ(1, 32);
    K(key => 0x44444444)->qIntoZ(1, 48);

    K(key => 0x55555555)->qIntoZ(2, 16);
    K(key => 0x66666666)->qIntoZ(2, 32);
    K(key => 0x77777777)->qIntoZ(2, 48);

    PrintOutStringNL "Push";
    $a->pushZmm(1)->outNL;
    $a->pushZmm(2)->outNL;

    $a->dump("zmm 1, 2");
    $a->peekZmm(1, 1)->outNL;
    $a->peekZmm(2, 2)->outNL;
    PrintOutStringNL "Peek";
    PrintOutRegisterInHex zmm1, zmm2;

    $a->popZmm(3);
    $a->popZmm(4);
    PrintOutStringNL "Pop";
    PrintOutRegisterInHex zmm3, zmm4;

    ok Assemble eq => <<END, clocks=>391;
  size: .... .... .... ...0
  AA
  Area     Size:     4096    Used:       64
  .... .... .... ...0 | __10 ____ ____ ____  40__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  size: .... .... .... ...1
  AA
  Area     Size:     4096    Used:       72
  .... .... .... ...0 | __10 ____ ____ ____  48__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 1111 1111 ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  size: .... .... .... ...2
  AA
  Area     Size:     4096    Used:       80
  .... .... .... ...0 | __10 ____ ____ ____  50__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 1111 1111 ____ ____  2222 2222 ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  Peek
  pop: .... .... 2222 2222
  size: .... .... .... ...2
  pop: .... .... 1111 1111
  size: .... .... .... ...2
  stackSize: .... .... .... ..10
  stackVariable
  pop: .... .... 1111 1111
  pop: .... .... 2222 2222
  Pop
  pop: .... .... 2222 2222
  size: .... .... .... ...1
  pop: .... .... 1111 1111
  size: .... .... .... ...0
  pop1
  Area     Size:     4096    Used:       64
  .... .... .... ...0 | __10 ____ ____ ____  40__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 1111 1111 ____ ____  2222 2222 ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  pop2
  Area     Size:     4096    Used:       64
  .... .... .... ...0 | __10 ____ ____ ____  40__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 1111 1111 ____ ____  2222 2222 ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  Push
  zmmStackOffset: .... .... .... ..40
  zmmStackOffset: .... .... .... ..80
  zmm 1, 2
  Area     Size:     4096    Used:      192
  .... .... .... ...0 | __10 ____ ____ ____  C0__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | ____ ____ ____ ____  ____ ____ ____ ____  2222 2222 ____ ____  ____ ____ ____ ____  3333 3333 ____ ____  ____ ____ ____ ____  4444 4444 ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  5555 5555 ____ ____  ____ ____ ____ ____  6666 6666 ____ ____  ____ ____ ____ ____  7777 7777 ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  offset: .... .... .... ..80
  offset: .... .... .... ..40
  Peek
    zmm1: .... .... .... ...0  .... .... 7777 7777 - .... .... .... ...0  .... .... 6666 6666 + .... .... .... ...0  .... .... 5555 5555 - .... .... .... ...0  .... .... .... ...0
    zmm2: .... .... .... ...0  .... .... 4444 4444 - .... .... .... ...0  .... .... 3333 3333 + .... .... .... ...0  .... .... 2222 2222 - .... .... .... ...0  .... .... .... ...0
  Pop
    zmm3: .... .... .... ...0  .... .... 7777 7777 - .... .... .... ...0  .... .... 6666 6666 + .... .... .... ...0  .... .... 5555 5555 - .... .... .... ...0  .... .... .... ...0
    zmm4: .... .... .... ...0  .... .... 4444 4444 - .... .... .... ...0  .... .... 3333 3333 + .... .... .... ...0  .... .... 2222 2222 - .... .... .... ...0  .... .... .... ...0
  END

Nasm::X86::Area::popZmm($area, $zmm)

Pop a zmm register from the stack in an area being used as a stack

     Parameter  Description
  1  $area      Area descriptor
  2  $zmm       Zmm number

Example:

    my $a = CreateArea(stack=>1);

    $a->stackVariableSize->outNL;
    $a->dump("AA");
    $a->push(K key => 0x11111111);
    $a->stackVariableSize->outNL;
    $a->dump("AA");

    $a->push(K key => 0x22222222);                                                # 12
    $a->stackVariableSize->outNL;
    $a->dump("AA");

    PrintOutStringNL "Peek";
    $a->peek(1)->outNL;
    $a->stackVariableSize->outNL;
    $a->peek(2)->outNL;
    $a->stackVariableSize->outNL;
    $a->stackSize->outNL;

    PrintOutStringNL "stackVariable";
    $a->stackVariable(K key => 0)->outNL;
    $a->stackVariable(K key => 1)->outNL;

    PrintOutStringNL "Pop";
    my $s1 = $a->pop;                                                             #  9
       $s1->outNL;
    $a->stackVariableSize->outNL;
    my $s2 = $a->pop;
       $s2->outNL;
    $a->stackVariableSize->outNL;
    $a->dump("pop1");
    $a->dump("pop2");

    ClearRegisters zmm1, zmm2;

    K(key => 0x22222222)->qIntoZ(1, 16);
    K(key => 0x33333333)->qIntoZ(1, 32);
    K(key => 0x44444444)->qIntoZ(1, 48);

    K(key => 0x55555555)->qIntoZ(2, 16);
    K(key => 0x66666666)->qIntoZ(2, 32);
    K(key => 0x77777777)->qIntoZ(2, 48);

    PrintOutStringNL "Push";
    $a->pushZmm(1)->outNL;
    $a->pushZmm(2)->outNL;

    $a->dump("zmm 1, 2");
    $a->peekZmm(1, 1)->outNL;
    $a->peekZmm(2, 2)->outNL;
    PrintOutStringNL "Peek";
    PrintOutRegisterInHex zmm1, zmm2;

    $a->popZmm(3);
    $a->popZmm(4);
    PrintOutStringNL "Pop";
    PrintOutRegisterInHex zmm3, zmm4;

    ok Assemble eq => <<END, clocks=>391;
  size: .... .... .... ...0
  AA
  Area     Size:     4096    Used:       64
  .... .... .... ...0 | __10 ____ ____ ____  40__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  size: .... .... .... ...1
  AA
  Area     Size:     4096    Used:       72
  .... .... .... ...0 | __10 ____ ____ ____  48__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 1111 1111 ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  size: .... .... .... ...2
  AA
  Area     Size:     4096    Used:       80
  .... .... .... ...0 | __10 ____ ____ ____  50__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 1111 1111 ____ ____  2222 2222 ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  Peek
  pop: .... .... 2222 2222
  size: .... .... .... ...2
  pop: .... .... 1111 1111
  size: .... .... .... ...2
  stackSize: .... .... .... ..10
  stackVariable
  pop: .... .... 1111 1111
  pop: .... .... 2222 2222
  Pop
  pop: .... .... 2222 2222
  size: .... .... .... ...1
  pop: .... .... 1111 1111
  size: .... .... .... ...0
  pop1
  Area     Size:     4096    Used:       64
  .... .... .... ...0 | __10 ____ ____ ____  40__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 1111 1111 ____ ____  2222 2222 ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  pop2
  Area     Size:     4096    Used:       64
  .... .... .... ...0 | __10 ____ ____ ____  40__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 1111 1111 ____ ____  2222 2222 ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  Push
  zmmStackOffset: .... .... .... ..40
  zmmStackOffset: .... .... .... ..80
  zmm 1, 2
  Area     Size:     4096    Used:      192
  .... .... .... ...0 | __10 ____ ____ ____  C0__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | ____ ____ ____ ____  ____ ____ ____ ____  2222 2222 ____ ____  ____ ____ ____ ____  3333 3333 ____ ____  ____ ____ ____ ____  4444 4444 ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  5555 5555 ____ ____  ____ ____ ____ ____  6666 6666 ____ ____  ____ ____ ____ ____  7777 7777 ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  offset: .... .... .... ..80
  offset: .... .... .... ..40
  Peek
    zmm1: .... .... .... ...0  .... .... 7777 7777 - .... .... .... ...0  .... .... 6666 6666 + .... .... .... ...0  .... .... 5555 5555 - .... .... .... ...0  .... .... .... ...0
    zmm2: .... .... .... ...0  .... .... 4444 4444 - .... .... .... ...0  .... .... 3333 3333 + .... .... .... ...0  .... .... 2222 2222 - .... .... .... ...0  .... .... .... ...0
  Pop
    zmm3: .... .... .... ...0  .... .... 7777 7777 - .... .... .... ...0  .... .... 6666 6666 + .... .... .... ...0  .... .... 5555 5555 - .... .... .... ...0  .... .... .... ...0
    zmm4: .... .... .... ...0  .... .... 4444 4444 - .... .... .... ...0  .... .... 3333 3333 + .... .... .... ...0  .... .... 2222 2222 - .... .... .... ...0  .... .... .... ...0
  END

Tree

Tree constructed as sets of blocks in an area.

Constructors

Construct a tree.

Nasm::X86::Area::CreateTree($area, %options)

Create a tree in an area.

     Parameter  Description
  1  $area      Area description
  2  %options   Tree options

Example:

    my $a = CreateArea;
    my $t = $a->CreateTree;
    $t->put (K(key => 2), K(data => 0x22));
    $t->find(K key => 2);
    $t->found->outNL;
    $t->data ->outNL;

    ok Assemble eq => <<END, avx512=>1;
  found  : .... .... .... ...1
  data   : .... .... .... ..22
  END

Nasm::X86::Tree::cloneDescriptor($tree)

Clone the descriptor of a tree to make a new tree descriptor.

     Parameter  Description
  1  $tree      Tree descriptor

Example:

    my $a = CreateArea;
    my $t = $a->CreateTree;
    $t->push(ord 'a');
    my $T = $t->cloneDescriptor;
    $T->push(ord 'b');
    my $c = $a->CreateTree;
    $c->copyDescriptor($T);
    $T->push(ord 'c');

    $t->outAsUtf8NL;
    ok Assemble eq => <<END, avx512=>1;
  abc
  END

Nasm::X86::Tree::copyDescriptor($target, $source)

Copy the description of one tree into another.

     Parameter  Description
  1  $target    The target of the copy
  2  $source    The source of the copy

Example:

    my $a = CreateArea;
    my $t = $a->CreateTree;
    $t->push(ord 'a');
    my $T = $t->cloneDescriptor;
    $T->push(ord 'b');
    my $c = $a->CreateTree;
    $c->copyDescriptor($T);
    $T->push(ord 'c');

    $t->outAsUtf8NL;
    ok Assemble eq => <<END, avx512=>1;
  abc
  END

Nasm::X86::Tree::size($tree)

Return in a variable the number of elements currently in the tree.

     Parameter  Description
  1  $tree      Tree descriptor

Example:

    my $a = CreateArea;
    my $t = $a->CreateTree;

    $t->put(K(key => 1), V(key => 1));  $t->size->outNL;
    $t->put(K(key => 2), K(key => 2));  $t->size->outNL;
    $t->put(V(key => 2), V(key => 2));  $t->size->outNL;

    $t->put(K(key => 3), K(key => 3));  $t->size->outNL;
    $t->put(V(key => 3), V(key => 3));  $t->size->outNL;

    $t->put(K(key => 4), K(key => 4));  $t->size->outNL;
    $t->put(K(key => 4), K(key => 4));  $t->size->outNL;

    $t->put(K(key => 5), K(key => 5));  $t->size->outNL;
    $t->put(V(key => 5), V(key => 5));  $t->size->outNL;

    $t->put(K(key => 6), K(key => 5));  $t->size->outNL;
    $t->put(V(key => 6), V(key => 5));  $t->size->outNL;

    $t->put(K(key => 7), K(key => 7));  $t->size->outNL;
    $t->put(V(key => 7), V(key => 7));  $t->size->outNL;

    $t->put(K(key => 8), K(key => 8));  $t->size->outNL;
    $t->put(V(key => 8), V(key => 8));  $t->size->outNL;

    $t->put(K(key => 9), K(key => 9));  $t->size->outNL;
    $t->put(V(key => 9), V(key => 9));  $t->size->outNL;

    $t->put(K(key => 10), K(key => 10));  $t->size->outNL;
    $t->put(V(key => 10), V(key => 10));  $t->size->outNL;

    $t->put(K(key => 11), K(key => 11));  $t->size->outNL;
    $t->put(V(key => 11), V(key => 11));  $t->size->outNL;

    $t->put(K(key => 12), K(key => 12));  $t->size->outNL;
    $t->put(V(key => 12), V(key => 12));  $t->size->outNL;

    $t->put(K(key => 13), K(key => 13));  $t->size->outNL;
    $t->put(V(key => 13), V(key => 13));  $t->size->outNL;

    $t->put(K(key => 14), K(key => 14));  $t->size->outNL;
    $t->put(V(key => 14), V(key => 14));  $t->size->outNL;

    $t->put(K(key => 15), K(key => 15));  $t->size->outNL;
    $t->put(V(key => 15), V(key => 15));  $t->size->outNL;

   $t->put(K(key => 4), K(key => 4));

   $t->dump8xx("AAA");

    ok Assemble debug => 0, eq => <<END, clocks=>18177;
  size of tree: .... .... .... ...1
  size of tree: .... .... .... ...2
  size of tree: .... .... .... ...2
  size of tree: .... .... .... ...3
  size of tree: .... .... .... ...3
  size of tree: .... .... .... ...4
  size of tree: .... .... .... ...4
  size of tree: .... .... .... ...5
  size of tree: .... .... .... ...5
  size of tree: .... .... .... ...6
  size of tree: .... .... .... ...6
  size of tree: .... .... .... ...7
  size of tree: .... .... .... ...7
  size of tree: .... .... .... ...8
  size of tree: .... .... .... ...8
  size of tree: .... .... .... ...9
  size of tree: .... .... .... ...9
  size of tree: .... .... .... ...A
  size of tree: .... .... .... ...A
  size of tree: .... .... .... ...B
  size of tree: .... .... .... ...B
  size of tree: .... .... .... ...C
  size of tree: .... .... .... ...C
  size of tree: .... .... .... ...D
  size of tree: .... .... .... ...D
  size of tree: .... .... .... ...E
  size of tree: .... .... .... ...E
  size of tree: .... .... .... ...F
  size of tree: .... .... .... ...F
  AAA
  Tree: .... .... .... ..40
  At:      200                                                                                length:        1,  data:      240,  nodes:      280,  first:       40, root, parent
    Index:        0
    Keys :        7
    Data :        7
    Nodes:       80      140
      At:       80                                                                            length:        6,  data:       C0,  nodes:      100,  first:       40,  up:      200, leaf
        Index:        0        1        2        3        4        5
        Keys :        1        2        3        4        5        6
        Data :        1        2        3        4        5        5
      end
      At:      140                                                                            length:        8,  data:      180,  nodes:      1C0,  first:       40,  up:      200, leaf
        Index:        0        1        2        3        4        5        6        7
        Keys :        8        9        A        B        C        D        E        F
        Data :        8        9        A        B        C        D        E        F
      end
  end
  END

Insert

Insert a key into the tree.

Nasm::X86::Tree::put($tree, $key, $data)

Put a variable key and data into a tree. The data could be a tree descriptor to place a sub tree into a tree at the indicated key.

     Parameter  Description
  1  $tree      Tree definition
  2  $key       Variable key containing a number for a normal key or the offset in the area of a zmm block containing the key
  3  $data      Data as a variable or a tree descriptor

Example:

  if (1)
   {my $a = CreateArea;
    my $t = $a->CreateTree;
    $t->put(1, 1);
    $t->find (1);
    $t->found->outNL;
    $t->data ->outNL;

    ok Assemble eq=><<END, avx512=>1;
  found  : .... .... .... ...1
  data   : .... .... .... ...1
  END
   }

    my $a = CreateArea;
    my $t = $a->CreateTree;
    my $N = K count => 128;

    $N->for(sub
     {my ($index, $start, $next, $end) = @_;
      my $l = $N-$index;
      $t->put($l, $l * 2);
      my $h = $N+$index;
      $t->put($h, $h * 2);
     });
    $t->put(K(zero=>0), K(zero=>0));
    $t->printInOrder("AAAA");

    PrintOutStringNL 'Indx   Found  Offset  Double   Found  Offset    Quad   Found  Offset    Octo   Found  Offset     *16   Found  Offset     *32   Found  Offset     *64   Found  Offset    *128   Found  Offset    *256   Found  Offset    *512';
    $N->for(sub
     {my ($index, $start, $next, $end) = @_;
      my $i = $index;
      my $j = $i * 2;
      my $k = $j * 2;
      my $l = $k * 2;
      my $m = $l * 2;
      my $n = $m * 2;
      my $o = $n * 2;
      my $p = $o * 2;
      my $q = $p * 2;
      $t->find($i); $i->outRightInDec(4); $t->found->outRightInBin(8); $t->offset->outRightInHex(8);  $t->data->outRightInDec  (8);
      $t->find($j);                       $t->found->outRightInBin(8); $t->offset->outRightInHex(8);  $t->data->outRightInDec  (8);
      $t->find($k);                       $t->found->outRightInBin(8); $t->offset->outRightInHex(8);  $t->data->outRightInDec  (8);
      $t->find($l);                       $t->found->outRightInBin(8); $t->offset->outRightInHex(8);  $t->data->outRightInDec  (8);
      $t->find($m);                       $t->found->outRightInBin(8); $t->offset->outRightInHex(8);  $t->data->outRightInDec  (8);
      $t->find($n);                       $t->found->outRightInBin(8); $t->offset->outRightInHex(8);  $t->data->outRightInDec  (8);
      $t->find($o);                       $t->found->outRightInBin(8); $t->offset->outRightInHex(8);  $t->data->outRightInDec  (8);
      $t->find($p);                       $t->found->outRightInBin(8); $t->offset->outRightInHex(8);  $t->data->outRightInDec  (8);
      $t->find($q);                       $t->found->outRightInBin(8); $t->offset->outRightInHex(8);  $t->data->outRightInDecNL(8);
     });

     ok Assemble eq => <<END, avx512=>1;
  AAAA 256:    0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F  10  11  12  13  14  15  16  17  18  19  1A  1B  1C  1D  1E  1F  20  21  22  23  24  25  26  27  28  29  2A  2B  2C  2D  2E  2F  30  31  32  33  34  35  36  37  38  39  3A  3B  3C  3D  3E  3F  40  41  42  43  44  45  46  47  48  49  4A  4B  4C  4D  4E  4F  50  51  52  53  54  55  56  57  58  59  5A  5B  5C  5D  5E  5F  60  61  62  63  64  65  66  67  68  69  6A  6B  6C  6D  6E  6F  70  71  72  73  74  75  76  77  78  79  7A  7B  7C  7D  7E  7F  80  81  82  83  84  85  86  87  88  89  8A  8B  8C  8D  8E  8F  90  91  92  93  94  95  96  97  98  99  9A  9B  9C  9D  9E  9F  A0  A1  A2  A3  A4  A5  A6  A7  A8  A9  AA  AB  AC  AD  AE  AF  B0  B1  B2  B3  B4  B5  B6  B7  B8  B9  BA  BB  BC  BD  BE  BF  C0  C1  C2  C3  C4  C5  C6  C7  C8  C9  CA  CB  CC  CD  CE  CF  D0  D1  D2  D3  D4  D5  D6  D7  D8  D9  DA  DB  DC  DD  DE  DF  E0  E1  E2  E3  E4  E5  E6  E7  E8  E9  EA  EB  EC  ED  EE  EF  F0  F1  F2  F3  F4  F5  F6  F7  F8  F9  FA  FB  FC  FD  FE  FF
  Indx   Found  Offset  Double   Found  Offset    Quad   Found  Offset    Octo   Found  Offset     *16   Found  Offset     *32   Found  Offset     *64   Found  Offset    *128   Found  Offset    *256   Found  Offset    *512
     0       1      80       0       1      80       0       1      80       0       1      80       0       1      80       0       1      80       0       1      80       0       1      80       0       1      80       0
     1      10      80       2     100      80       4   10000      80       800000000      80      16      10     200      32      10    1940      64  100000    11C0     128      10     C80     256               0       0
     2     100      80       4   10000      80       800000000      80      16      10     200      32      10    1940      64  100000    11C0     128      10     C80     256               0       0               0       0
     3    1000      80       6 1000000      80      12     100    1DC0      24       1    1AC0      48    1000    14C0      96     100     8C0     192       1    1100     384               0       0               0       0
     4   10000      80       800000000      80      16      10     200      32      10    1940      64  100000    11C0     128      10     C80     256               0       0               0       0               0       0
     5  100000      80      10       1    1DC0      20    1000    1C40      40     100    1640      80       1     D40     160    1000     800     320               0       0               0       0               0       0
     6 1000000      80      12     100    1DC0      24       1    1AC0      48    1000    14C0      96     100     8C0     192       1    1100     384               0       0               0       0               0       0
     710000000      80      14   10000    1DC0      28   10000    1AC0      56   10000    1340     112   10000     5C0     224   10000    17C0     448               0       0               0       0               0       0
     800000000      80      16      10     200      32      10    1940      64  100000    11C0     128      10     C80     256               0       0               0       0               0       0               0       0
     9       1     200      18      10    1C40      36  100000    1940      7200000000     200     144      10     500     288               0       0               0       0               0       0               0       0
    10       1    1DC0      20    1000    1C40      40     100    1640      80       1     D40     160    1000     800     320               0       0               0       0               0       0               0       0
    11      10    1DC0      22  100000    1C40      44  100000     200      88      10     A40     176  100000     B00     352               0       0               0       0               0       0               0       0
    12     100    1DC0      24       1    1AC0      48    1000    14C0      96     100     8C0     192       1    1100     384               0       0               0       0               0       0               0       0
    13    1000    1DC0      26     100    1AC0      52       1    1340     104    1000     740     208     100    1400     416               0       0               0       0               0       0               0       0
    14   10000    1DC0      28   10000    1AC0      56   10000    1340     112   10000     5C0     224   10000    17C0     448               0       0               0       0               0       0               0       0
    15  100000    1DC0      30    1000     200      60      10    11C0     120  100000     440     24000000000    1880     480               0       0               0       0               0       0               0       0
    16      10     200      32      10    1940      64  100000    11C0     128      10     C80     256               0       0               0       0               0       0               0       0               0       0
    17       1    1C40      34    1000    1940      68     100    1040     136       1     380     272               0       0               0       0               0       0               0       0               0       0
    18      10    1C40      36  100000    1940      7200000000     200     144      10     500     288               0       0               0       0               0       0               0       0               0       0
    19     100    1C40      38       1    1640      76    1000     EC0     152     100     680     304               0       0               0       0               0       0               0       0               0       0
    20    1000    1C40      40     100    1640      80       1     D40     160    1000     800     320               0       0               0       0               0       0               0       0               0       0
    21   10000    1C40      42   10000    1640      84   10000     D40     168   10000     980     336               0       0               0       0               0       0               0       0               0       0
    22  100000    1C40      44  100000     200      88      10     A40     176  100000     B00     352               0       0               0       0               0       0               0       0               0       0
    23     100     200      46      10    14C0      92  100000     A40     184       1    1880     368               0       0               0       0               0       0               0       0               0       0
    24       1    1AC0      48    1000    14C0      96     100     8C0     192       1    1100     384               0       0               0       0               0       0               0       0               0       0
    25      10    1AC0      50  100000    14C0     100     100    1700     200      10    1280     400               0       0               0       0               0       0               0       0               0       0
    26     100    1AC0      52       1    1340     104    1000     740     208     100    1400     416               0       0               0       0               0       0               0       0               0       0
    27    1000    1AC0      54     100    1340     108       1     5C0     216    1000    1580     432               0       0               0       0               0       0               0       0               0       0
    28   10000    1AC0      56   10000    1340     112   10000     5C0     224   10000    17C0     448               0       0               0       0               0       0               0       0               0       0
    29  100000    1AC0      5810000000     200     116      10     440     232  100000    1A00     464               0       0               0       0               0       0               0       0               0       0
    30    1000     200      60      10    11C0     120  100000     440     24000000000    1880     480               0       0               0       0               0       0               0       0               0       0
    31       1    1940      62    1000    11C0     124     100     2C0     248       1    1E80     496               0       0               0       0               0       0               0       0               0       0
    32      10    1940      64  100000    11C0     128      10     C80     256               0       0               0       0               0       0               0       0               0       0               0       0
    33     100    1940      66       1    1040     132    1000     140     264               0       0               0       0               0       0               0       0               0       0               0       0
    34    1000    1940      68     100    1040     136       1     380     272               0       0               0       0               0       0               0       0               0       0               0       0
    35   10000    1940      70   10000    1040     140   10000     380     280               0       0               0       0               0       0               0       0               0       0               0       0
    36  100000    1940      7200000000     200     144      10     500     288               0       0               0       0               0       0               0       0               0       0               0       0
    37   10000     200      74      10     EC0     148  100000     500     296               0       0               0       0               0       0               0       0               0       0               0       0
    38       1    1640      76    1000     EC0     152     100     680     304               0       0               0       0               0       0               0       0               0       0               0       0
    39      10    1640      78  100000     EC0     156    1000     BC0     312               0       0               0       0               0       0               0       0               0       0               0       0
    40     100    1640      80       1     D40     160    1000     800     320               0       0               0       0               0       0               0       0               0       0               0       0
    41    1000    1640      82     100     D40     164       1     980     328               0       0               0       0               0       0               0       0               0       0               0       0
    42   10000    1640      84   10000     D40     168   10000     980     336               0       0               0       0               0       0               0       0               0       0               0       0
    43  100000    1640      86       1    1700     172      10     B00     344               0       0               0       0               0       0               0       0               0       0               0       0
    44  100000     200      88      10     A40     176  100000     B00     352               0       0               0       0               0       0               0       0               0       0               0       0
    45       1    14C0      90    1000     A40     180     100     E00     360               0       0               0       0               0       0               0       0               0       0               0       0
    46      10    14C0      92  100000     A40     184       1    1880     368               0       0               0       0               0       0               0       0               0       0               0       0
    47     100    14C0      94       1     8C0     188    1000     F80     376               0       0               0       0               0       0               0       0               0       0               0       0
    48    1000    14C0      96     100     8C0     192       1    1100     384               0       0               0       0               0       0               0       0               0       0               0       0
    49   10000    14C0      98   10000     8C0     196   10000    1100     392               0       0               0       0               0       0               0       0               0       0               0       0
    50  100000    14C0     100     100    1700     200      10    1280     400               0       0               0       0               0       0               0       0               0       0               0       0
    51 1000000     200     102      10     740     204  100000    1280     408               0       0               0       0               0       0               0       0               0       0               0       0
    52       1    1340     104    1000     740     208     100    1400     416               0       0               0       0               0       0               0       0               0       0               0       0
    53      10    1340     106  100000     740     212   10000    1880     424               0       0               0       0               0       0               0       0               0       0               0       0
    54     100    1340     108       1     5C0     216    1000    1580     432               0       0               0       0               0       0               0       0               0       0               0       0
    55    1000    1340     110     100     5C0     220       1    17C0     440               0       0               0       0               0       0               0       0               0       0               0       0
    56   10000    1340     112   10000     5C0     224   10000    17C0     448               0       0               0       0               0       0               0       0               0       0               0       0
    57  100000    1340     114   10000    1700     228      10    1A00     456               0       0               0       0               0       0               0       0               0       0               0       0
    5810000000     200     116      10     440     232  100000    1A00     464               0       0               0       0               0       0               0       0               0       0               0       0
    59       1    11C0     118    1000     440     236     100    1B80     472               0       0               0       0               0       0               0       0               0       0               0       0
    60      10    11C0     120  100000     440     24000000000    1880     480               0       0               0       0               0       0               0       0               0       0               0       0
    61     100    11C0     122       1     2C0     244    1000    1D00     488               0       0               0       0               0       0               0       0               0       0               0       0
    62    1000    11C0     124     100     2C0     248       1    1E80     496               0       0               0       0               0       0               0       0               0       0               0       0
    63   10000    11C0     126   10000     2C0     252   10000    1E80     504               0       0               0       0               0       0               0       0               0       0               0       0
    64  100000    11C0     128      10     C80     256               0       0               0       0               0       0               0       0               0       0               0       0               0       0
    6500000000     200     130      10     140     260               0       0               0       0               0       0               0       0               0       0               0       0               0       0
    66       1    1040     132    1000     140     264               0       0               0       0               0       0               0       0               0       0               0       0               0       0
    67      10    1040     134  100000     140     268               0       0               0       0               0       0               0       0               0       0               0       0               0       0
    68     100    1040     136       1     380     272               0       0               0       0               0       0               0       0               0       0               0       0               0       0
    69    1000    1040     138     100     380     276               0       0               0       0               0       0               0       0               0       0               0       0               0       0
    70   10000    1040     140   10000     380     280               0       0               0       0               0       0               0       0               0       0               0       0               0       0
    71  100000    1040     142      10     BC0     284               0       0               0       0               0       0               0       0               0       0               0       0               0       0
    7200000000     200     144      10     500     288               0       0               0       0               0       0               0       0               0       0               0       0               0       0
    73       1     EC0     146    1000     500     292               0       0               0       0               0       0               0       0               0       0               0       0               0       0
    74      10     EC0     148  100000     500     296               0       0               0       0               0       0               0       0               0       0               0       0               0       0
    75     100     EC0     150       1     680     300               0       0               0       0               0       0               0       0               0       0               0       0               0       0
    76    1000     EC0     152     100     680     304               0       0               0       0               0       0               0       0               0       0               0       0               0       0
    77   10000     EC0     154   10000     680     308               0       0               0       0               0       0               0       0               0       0               0       0               0       0
    78  100000     EC0     156    1000     BC0     312               0       0               0       0               0       0               0       0               0       0               0       0               0       0
    79       1     C80     158      10     800     316               0       0               0       0               0       0               0       0               0       0               0       0               0       0
    80       1     D40     160    1000     800     320               0       0               0       0               0       0               0       0               0       0               0       0               0       0
    81      10     D40     162  100000     800     324               0       0               0       0               0       0               0       0               0       0               0       0               0       0
    82     100     D40     164       1     980     328               0       0               0       0               0       0               0       0               0       0               0       0               0       0
    83    1000     D40     166     100     980     332               0       0               0       0               0       0               0       0               0       0               0       0               0       0
    84   10000     D40     168   10000     980     336               0       0               0       0               0       0               0       0               0       0               0       0               0       0
    85  100000     D40     170  100000     BC0     340               0       0               0       0               0       0               0       0               0       0               0       0               0       0
    86       1    1700     172      10     B00     344               0       0               0       0               0       0               0       0               0       0               0       0               0       0
    87       1     A40     174    1000     B00     348               0       0               0       0               0       0               0       0               0       0               0       0               0       0
    88      10     A40     176  100000     B00     352               0       0               0       0               0       0               0       0               0       0               0       0               0       0
    89     100     A40     178       1     E00     356               0       0               0       0               0       0               0       0               0       0               0       0               0       0
    90    1000     A40     180     100     E00     360               0       0               0       0               0       0               0       0               0       0               0       0               0       0
    91   10000     A40     182   10000     E00     364               0       0               0       0               0       0               0       0               0       0               0       0               0       0
    92  100000     A40     184       1    1880     368               0       0               0       0               0       0               0       0               0       0               0       0               0       0
    93      10    1700     186      10     F80     372               0       0               0       0               0       0               0       0               0       0               0       0               0       0
    94       1     8C0     188    1000     F80     376               0       0               0       0               0       0               0       0               0       0               0       0               0       0
    95      10     8C0     190  100000     F80     380               0       0               0       0               0       0               0       0               0       0               0       0               0       0
    96     100     8C0     192       1    1100     384               0       0               0       0               0       0               0       0               0       0               0       0               0       0
    97    1000     8C0     194     100    1100     388               0       0               0       0               0       0               0       0               0       0               0       0               0       0
    98   10000     8C0     196   10000    1100     392               0       0               0       0               0       0               0       0               0       0               0       0               0       0
    99  100000     8C0     198     100    1880     396               0       0               0       0               0       0               0       0               0       0               0       0               0       0
   100     100    1700     200      10    1280     400               0       0               0       0               0       0               0       0               0       0               0       0               0       0
   101       1     740     202    1000    1280     404               0       0               0       0               0       0               0       0               0       0               0       0               0       0
   102      10     740     204  100000    1280     408               0       0               0       0               0       0               0       0               0       0               0       0               0       0
   103     100     740     206       1    1400     412               0       0               0       0               0       0               0       0               0       0               0       0               0       0
   104    1000     740     208     100    1400     416               0       0               0       0               0       0               0       0               0       0               0       0               0       0
   105   10000     740     210   10000    1400     420               0       0               0       0               0       0               0       0               0       0               0       0               0       0
   106  100000     740     212   10000    1880     424               0       0               0       0               0       0               0       0               0       0               0       0               0       0
   107    1000    1700     214      10    1580     428               0       0               0       0               0       0               0       0               0       0               0       0               0       0
   108       1     5C0     216    1000    1580     432               0       0               0       0               0       0               0       0               0       0               0       0               0       0
   109      10     5C0     218  100000    1580     436               0       0               0       0               0       0               0       0               0       0               0       0               0       0
   110     100     5C0     220       1    17C0     440               0       0               0       0               0       0               0       0               0       0               0       0               0       0
   111    1000     5C0     222     100    17C0     444               0       0               0       0               0       0               0       0               0       0               0       0               0       0
   112   10000     5C0     224   10000    17C0     448               0       0               0       0               0       0               0       0               0       0               0       0               0       0
   113  100000     5C0     226 1000000    1880     452               0       0               0       0               0       0               0       0               0       0               0       0               0       0
   114   10000    1700     228      10    1A00     456               0       0               0       0               0       0               0       0               0       0               0       0               0       0
   115       1     440     230    1000    1A00     460               0       0               0       0               0       0               0       0               0       0               0       0               0       0
   116      10     440     232  100000    1A00     464               0       0               0       0               0       0               0       0               0       0               0       0               0       0
   117     100     440     234       1    1B80     468               0       0               0       0               0       0               0       0               0       0               0       0               0       0
   118    1000     440     236     100    1B80     472               0       0               0       0               0       0               0       0               0       0               0       0               0       0
   119   10000     440     238   10000    1B80     476               0       0               0       0               0       0               0       0               0       0               0       0               0       0
   120  100000     440     24000000000    1880     480               0       0               0       0               0       0               0       0               0       0               0       0               0       0
   121  100000    1700     242      10    1D00     484               0       0               0       0               0       0               0       0               0       0               0       0               0       0
   122       1     2C0     244    1000    1D00     488               0       0               0       0               0       0               0       0               0       0               0       0               0       0
   123      10     2C0     246  100000    1D00     492               0       0               0       0               0       0               0       0               0       0               0       0               0       0
   124     100     2C0     248       1    1E80     496               0       0               0       0               0       0               0       0               0       0               0       0               0       0
   125    1000     2C0     250     100    1E80     500               0       0               0       0               0       0               0       0               0       0               0       0               0       0
   126   10000     2C0     252   10000    1E80     504               0       0               0       0               0       0               0       0               0       0               0       0               0       0
   127  100000     2C0     254 1000000    1E80     508               0       0               0       0               0       0               0       0               0       0               0       0               0       0
  END

    my $a = CreateArea;
    my $t = $a->CreateTree;

    $t->put(K(key => 1), V(key => 1));  $t->size->outNL;
    $t->put(K(key => 2), K(key => 2));  $t->size->outNL;
    $t->put(V(key => 2), V(key => 2));  $t->size->outNL;

    $t->put(K(key => 3), K(key => 3));  $t->size->outNL;
    $t->put(V(key => 3), V(key => 3));  $t->size->outNL;

    $t->put(K(key => 4), K(key => 4));  $t->size->outNL;
    $t->put(K(key => 4), K(key => 4));  $t->size->outNL;

    $t->put(K(key => 5), K(key => 5));  $t->size->outNL;
    $t->put(V(key => 5), V(key => 5));  $t->size->outNL;

    $t->put(K(key => 6), K(key => 5));  $t->size->outNL;
    $t->put(V(key => 6), V(key => 5));  $t->size->outNL;

    $t->put(K(key => 7), K(key => 7));  $t->size->outNL;
    $t->put(V(key => 7), V(key => 7));  $t->size->outNL;

    $t->put(K(key => 8), K(key => 8));  $t->size->outNL;
    $t->put(V(key => 8), V(key => 8));  $t->size->outNL;

    $t->put(K(key => 9), K(key => 9));  $t->size->outNL;
    $t->put(V(key => 9), V(key => 9));  $t->size->outNL;

    $t->put(K(key => 10), K(key => 10));  $t->size->outNL;
    $t->put(V(key => 10), V(key => 10));  $t->size->outNL;

    $t->put(K(key => 11), K(key => 11));  $t->size->outNL;
    $t->put(V(key => 11), V(key => 11));  $t->size->outNL;

    $t->put(K(key => 12), K(key => 12));  $t->size->outNL;
    $t->put(V(key => 12), V(key => 12));  $t->size->outNL;

    $t->put(K(key => 13), K(key => 13));  $t->size->outNL;
    $t->put(V(key => 13), V(key => 13));  $t->size->outNL;

    $t->put(K(key => 14), K(key => 14));  $t->size->outNL;
    $t->put(V(key => 14), V(key => 14));  $t->size->outNL;

    $t->put(K(key => 15), K(key => 15));  $t->size->outNL;
    $t->put(V(key => 15), V(key => 15));  $t->size->outNL;

   $t->put(K(key => 4), K(key => 4));

   $t->dump8xx("AAA");

    ok Assemble debug => 0, eq => <<END, clocks=>18177;
  size of tree: .... .... .... ...1
  size of tree: .... .... .... ...2
  size of tree: .... .... .... ...2
  size of tree: .... .... .... ...3
  size of tree: .... .... .... ...3
  size of tree: .... .... .... ...4
  size of tree: .... .... .... ...4
  size of tree: .... .... .... ...5
  size of tree: .... .... .... ...5
  size of tree: .... .... .... ...6
  size of tree: .... .... .... ...6
  size of tree: .... .... .... ...7
  size of tree: .... .... .... ...7
  size of tree: .... .... .... ...8
  size of tree: .... .... .... ...8
  size of tree: .... .... .... ...9
  size of tree: .... .... .... ...9
  size of tree: .... .... .... ...A
  size of tree: .... .... .... ...A
  size of tree: .... .... .... ...B
  size of tree: .... .... .... ...B
  size of tree: .... .... .... ...C
  size of tree: .... .... .... ...C
  size of tree: .... .... .... ...D
  size of tree: .... .... .... ...D
  size of tree: .... .... .... ...E
  size of tree: .... .... .... ...E
  size of tree: .... .... .... ...F
  size of tree: .... .... .... ...F
  AAA
  Tree: .... .... .... ..40
  At:      200                                                                                length:        1,  data:      240,  nodes:      280,  first:       40, root, parent
    Index:        0
    Keys :        7
    Data :        7
    Nodes:       80      140
      At:       80                                                                            length:        6,  data:       C0,  nodes:      100,  first:       40,  up:      200, leaf
        Index:        0        1        2        3        4        5
        Keys :        1        2        3        4        5        6
        Data :        1        2        3        4        5        5
      end
      At:      140                                                                            length:        8,  data:      180,  nodes:      1C0,  first:       40,  up:      200, leaf
        Index:        0        1        2        3        4        5        6        7
        Keys :        8        9        A        B        C        D        E        F
        Data :        8        9        A        B        C        D        E        F
      end
  end
  END

    my $a = CreateArea;
    my $t = $a->CreateTree;

    my $N = K(key => 999);
    $N->for(sub
     {my ($index, $start, $next, $end) = @_;
      $t->put($index, $index);
     });

    $N->for(sub
     {my ($index, $start, $next, $end) = @_;
      $t->find($index);
     });

    ok Assemble eq => <<END, clocks=>763430;
  END

Find

Find a key in the tree. Trees have dword integer keys and so can act as arrays as well.

Nasm::X86::Tree::find($tree, $key)

Find a key in a tree and tests whether the found data is a sub tree. The results are held in the variables "found", "data", "subTree" addressed by the tree descriptor. The key just searched for is held in the key field of the tree descriptor. The point at which it was found is held in found which will be zero if the key was not found.

     Parameter  Description
  1  $tree      Tree descriptor
  2  $key       Key field to search for which can either be a variable containing a double word for a normal tree or a zmm register containing the key to be sought for a string tree.

Example:

  if (1)
   {my $a = CreateArea;
    my $t = $a->CreateTree;
    $t->put(1, 1);
    $t->find (1);
    $t->found->outNL;
    $t->data ->outNL;

    ok Assemble eq=><<END, avx512=>1;
  found  : .... .... .... ...1
  data   : .... .... .... ...1
  END
   }

    my $a = CreateArea;
    my $t = $a->CreateTree;
    my $N = K count => 128;

    $N->for(sub
     {my ($index, $start, $next, $end) = @_;
      my $l = $N-$index;
      $t->put($l, $l * 2);
      my $h = $N+$index;
      $t->put($h, $h * 2);
     });
    $t->put(K(zero=>0), K(zero=>0));
    $t->printInOrder("AAAA");

    PrintOutStringNL 'Indx   Found  Offset  Double   Found  Offset    Quad   Found  Offset    Octo   Found  Offset     *16   Found  Offset     *32   Found  Offset     *64   Found  Offset    *128   Found  Offset    *256   Found  Offset    *512';
    $N->for(sub
     {my ($index, $start, $next, $end) = @_;
      my $i = $index;
      my $j = $i * 2;
      my $k = $j * 2;
      my $l = $k * 2;
      my $m = $l * 2;
      my $n = $m * 2;
      my $o = $n * 2;
      my $p = $o * 2;
      my $q = $p * 2;
      $t->find($i); $i->outRightInDec(4); $t->found->outRightInBin(8); $t->offset->outRightInHex(8);  $t->data->outRightInDec  (8);
      $t->find($j);                       $t->found->outRightInBin(8); $t->offset->outRightInHex(8);  $t->data->outRightInDec  (8);
      $t->find($k);                       $t->found->outRightInBin(8); $t->offset->outRightInHex(8);  $t->data->outRightInDec  (8);
      $t->find($l);                       $t->found->outRightInBin(8); $t->offset->outRightInHex(8);  $t->data->outRightInDec  (8);
      $t->find($m);                       $t->found->outRightInBin(8); $t->offset->outRightInHex(8);  $t->data->outRightInDec  (8);
      $t->find($n);                       $t->found->outRightInBin(8); $t->offset->outRightInHex(8);  $t->data->outRightInDec  (8);
      $t->find($o);                       $t->found->outRightInBin(8); $t->offset->outRightInHex(8);  $t->data->outRightInDec  (8);
      $t->find($p);                       $t->found->outRightInBin(8); $t->offset->outRightInHex(8);  $t->data->outRightInDec  (8);
      $t->find($q);                       $t->found->outRightInBin(8); $t->offset->outRightInHex(8);  $t->data->outRightInDecNL(8);
     });

     ok Assemble eq => <<END, avx512=>1;
  AAAA 256:    0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F  10  11  12  13  14  15  16  17  18  19  1A  1B  1C  1D  1E  1F  20  21  22  23  24  25  26  27  28  29  2A  2B  2C  2D  2E  2F  30  31  32  33  34  35  36  37  38  39  3A  3B  3C  3D  3E  3F  40  41  42  43  44  45  46  47  48  49  4A  4B  4C  4D  4E  4F  50  51  52  53  54  55  56  57  58  59  5A  5B  5C  5D  5E  5F  60  61  62  63  64  65  66  67  68  69  6A  6B  6C  6D  6E  6F  70  71  72  73  74  75  76  77  78  79  7A  7B  7C  7D  7E  7F  80  81  82  83  84  85  86  87  88  89  8A  8B  8C  8D  8E  8F  90  91  92  93  94  95  96  97  98  99  9A  9B  9C  9D  9E  9F  A0  A1  A2  A3  A4  A5  A6  A7  A8  A9  AA  AB  AC  AD  AE  AF  B0  B1  B2  B3  B4  B5  B6  B7  B8  B9  BA  BB  BC  BD  BE  BF  C0  C1  C2  C3  C4  C5  C6  C7  C8  C9  CA  CB  CC  CD  CE  CF  D0  D1  D2  D3  D4  D5  D6  D7  D8  D9  DA  DB  DC  DD  DE  DF  E0  E1  E2  E3  E4  E5  E6  E7  E8  E9  EA  EB  EC  ED  EE  EF  F0  F1  F2  F3  F4  F5  F6  F7  F8  F9  FA  FB  FC  FD  FE  FF
  Indx   Found  Offset  Double   Found  Offset    Quad   Found  Offset    Octo   Found  Offset     *16   Found  Offset     *32   Found  Offset     *64   Found  Offset    *128   Found  Offset    *256   Found  Offset    *512
     0       1      80       0       1      80       0       1      80       0       1      80       0       1      80       0       1      80       0       1      80       0       1      80       0       1      80       0
     1      10      80       2     100      80       4   10000      80       800000000      80      16      10     200      32      10    1940      64  100000    11C0     128      10     C80     256               0       0
     2     100      80       4   10000      80       800000000      80      16      10     200      32      10    1940      64  100000    11C0     128      10     C80     256               0       0               0       0
     3    1000      80       6 1000000      80      12     100    1DC0      24       1    1AC0      48    1000    14C0      96     100     8C0     192       1    1100     384               0       0               0       0
     4   10000      80       800000000      80      16      10     200      32      10    1940      64  100000    11C0     128      10     C80     256               0       0               0       0               0       0
     5  100000      80      10       1    1DC0      20    1000    1C40      40     100    1640      80       1     D40     160    1000     800     320               0       0               0       0               0       0
     6 1000000      80      12     100    1DC0      24       1    1AC0      48    1000    14C0      96     100     8C0     192       1    1100     384               0       0               0       0               0       0
     710000000      80      14   10000    1DC0      28   10000    1AC0      56   10000    1340     112   10000     5C0     224   10000    17C0     448               0       0               0       0               0       0
     800000000      80      16      10     200      32      10    1940      64  100000    11C0     128      10     C80     256               0       0               0       0               0       0               0       0
     9       1     200      18      10    1C40      36  100000    1940      7200000000     200     144      10     500     288               0       0               0       0               0       0               0       0
    10       1    1DC0      20    1000    1C40      40     100    1640      80       1     D40     160    1000     800     320               0       0               0       0               0       0               0       0
    11      10    1DC0      22  100000    1C40      44  100000     200      88      10     A40     176  100000     B00     352               0       0               0       0               0       0               0       0
    12     100    1DC0      24       1    1AC0      48    1000    14C0      96     100     8C0     192       1    1100     384               0       0               0       0               0       0               0       0
    13    1000    1DC0      26     100    1AC0      52       1    1340     104    1000     740     208     100    1400     416               0       0               0       0               0       0               0       0
    14   10000    1DC0      28   10000    1AC0      56   10000    1340     112   10000     5C0     224   10000    17C0     448               0       0               0       0               0       0               0       0
    15  100000    1DC0      30    1000     200      60      10    11C0     120  100000     440     24000000000    1880     480               0       0               0       0               0       0               0       0
    16      10     200      32      10    1940      64  100000    11C0     128      10     C80     256               0       0               0       0               0       0               0       0               0       0
    17       1    1C40      34    1000    1940      68     100    1040     136       1     380     272               0       0               0       0               0       0               0       0               0       0
    18      10    1C40      36  100000    1940      7200000000     200     144      10     500     288               0       0               0       0               0       0               0       0               0       0
    19     100    1C40      38       1    1640      76    1000     EC0     152     100     680     304               0       0               0       0               0       0               0       0               0       0
    20    1000    1C40      40     100    1640      80       1     D40     160    1000     800     320               0       0               0       0               0       0               0       0               0       0
    21   10000    1C40      42   10000    1640      84   10000     D40     168   10000     980     336               0       0               0       0               0       0               0       0               0       0
    22  100000    1C40      44  100000     200      88      10     A40     176  100000     B00     352               0       0               0       0               0       0               0       0               0       0
    23     100     200      46      10    14C0      92  100000     A40     184       1    1880     368               0       0               0       0               0       0               0       0               0       0
    24       1    1AC0      48    1000    14C0      96     100     8C0     192       1    1100     384               0       0               0       0               0       0               0       0               0       0
    25      10    1AC0      50  100000    14C0     100     100    1700     200      10    1280     400               0       0               0       0               0       0               0       0               0       0
    26     100    1AC0      52       1    1340     104    1000     740     208     100    1400     416               0       0               0       0               0       0               0       0               0       0
    27    1000    1AC0      54     100    1340     108       1     5C0     216    1000    1580     432               0       0               0       0               0       0               0       0               0       0
    28   10000    1AC0      56   10000    1340     112   10000     5C0     224   10000    17C0     448               0       0               0       0               0       0               0       0               0       0
    29  100000    1AC0      5810000000     200     116      10     440     232  100000    1A00     464               0       0               0       0               0       0               0       0               0       0
    30    1000     200      60      10    11C0     120  100000     440     24000000000    1880     480               0       0               0       0               0       0               0       0               0       0
    31       1    1940      62    1000    11C0     124     100     2C0     248       1    1E80     496               0       0               0       0               0       0               0       0               0       0
    32      10    1940      64  100000    11C0     128      10     C80     256               0       0               0       0               0       0               0       0               0       0               0       0
    33     100    1940      66       1    1040     132    1000     140     264               0       0               0       0               0       0               0       0               0       0               0       0
    34    1000    1940      68     100    1040     136       1     380     272               0       0               0       0               0       0               0       0               0       0               0       0
    35   10000    1940      70   10000    1040     140   10000     380     280               0       0               0       0               0       0               0       0               0       0               0       0
    36  100000    1940      7200000000     200     144      10     500     288               0       0               0       0               0       0               0       0               0       0               0       0
    37   10000     200      74      10     EC0     148  100000     500     296               0       0               0       0               0       0               0       0               0       0               0       0
    38       1    1640      76    1000     EC0     152     100     680     304               0       0               0       0               0       0               0       0               0       0               0       0
    39      10    1640      78  100000     EC0     156    1000     BC0     312               0       0               0       0               0       0               0       0               0       0               0       0
    40     100    1640      80       1     D40     160    1000     800     320               0       0               0       0               0       0               0       0               0       0               0       0
    41    1000    1640      82     100     D40     164       1     980     328               0       0               0       0               0       0               0       0               0       0               0       0
    42   10000    1640      84   10000     D40     168   10000     980     336               0       0               0       0               0       0               0       0               0       0               0       0
    43  100000    1640      86       1    1700     172      10     B00     344               0       0               0       0               0       0               0       0               0       0               0       0
    44  100000     200      88      10     A40     176  100000     B00     352               0       0               0       0               0       0               0       0               0       0               0       0
    45       1    14C0      90    1000     A40     180     100     E00     360               0       0               0       0               0       0               0       0               0       0               0       0
    46      10    14C0      92  100000     A40     184       1    1880     368               0       0               0       0               0       0               0       0               0       0               0       0
    47     100    14C0      94       1     8C0     188    1000     F80     376               0       0               0       0               0       0               0       0               0       0               0       0
    48    1000    14C0      96     100     8C0     192       1    1100     384               0       0               0       0               0       0               0       0               0       0               0       0
    49   10000    14C0      98   10000     8C0     196   10000    1100     392               0       0               0       0               0       0               0       0               0       0               0       0
    50  100000    14C0     100     100    1700     200      10    1280     400               0       0               0       0               0       0               0       0               0       0               0       0
    51 1000000     200     102      10     740     204  100000    1280     408               0       0               0       0               0       0               0       0               0       0               0       0
    52       1    1340     104    1000     740     208     100    1400     416               0       0               0       0               0       0               0       0               0       0               0       0
    53      10    1340     106  100000     740     212   10000    1880     424               0       0               0       0               0       0               0       0               0       0               0       0
    54     100    1340     108       1     5C0     216    1000    1580     432               0       0               0       0               0       0               0       0               0       0               0       0
    55    1000    1340     110     100     5C0     220       1    17C0     440               0       0               0       0               0       0               0       0               0       0               0       0
    56   10000    1340     112   10000     5C0     224   10000    17C0     448               0       0               0       0               0       0               0       0               0       0               0       0
    57  100000    1340     114   10000    1700     228      10    1A00     456               0       0               0       0               0       0               0       0               0       0               0       0
    5810000000     200     116      10     440     232  100000    1A00     464               0       0               0       0               0       0               0       0               0       0               0       0
    59       1    11C0     118    1000     440     236     100    1B80     472               0       0               0       0               0       0               0       0               0       0               0       0
    60      10    11C0     120  100000     440     24000000000    1880     480               0       0               0       0               0       0               0       0               0       0               0       0
    61     100    11C0     122       1     2C0     244    1000    1D00     488               0       0               0       0               0       0               0       0               0       0               0       0
    62    1000    11C0     124     100     2C0     248       1    1E80     496               0       0               0       0               0       0               0       0               0       0               0       0
    63   10000    11C0     126   10000     2C0     252   10000    1E80     504               0       0               0       0               0       0               0       0               0       0               0       0
    64  100000    11C0     128      10     C80     256               0       0               0       0               0       0               0       0               0       0               0       0               0       0
    6500000000     200     130      10     140     260               0       0               0       0               0       0               0       0               0       0               0       0               0       0
    66       1    1040     132    1000     140     264               0       0               0       0               0       0               0       0               0       0               0       0               0       0
    67      10    1040     134  100000     140     268               0       0               0       0               0       0               0       0               0       0               0       0               0       0
    68     100    1040     136       1     380     272               0       0               0       0               0       0               0       0               0       0               0       0               0       0
    69    1000    1040     138     100     380     276               0       0               0       0               0       0               0       0               0       0               0       0               0       0
    70   10000    1040     140   10000     380     280               0       0               0       0               0       0               0       0               0       0               0       0               0       0
    71  100000    1040     142      10     BC0     284               0       0               0       0               0       0               0       0               0       0               0       0               0       0
    7200000000     200     144      10     500     288               0       0               0       0               0       0               0       0               0       0               0       0               0       0
    73       1     EC0     146    1000     500     292               0       0               0       0               0       0               0       0               0       0               0       0               0       0
    74      10     EC0     148  100000     500     296               0       0               0       0               0       0               0       0               0       0               0       0               0       0
    75     100     EC0     150       1     680     300               0       0               0       0               0       0               0       0               0       0               0       0               0       0
    76    1000     EC0     152     100     680     304               0       0               0       0               0       0               0       0               0       0               0       0               0       0
    77   10000     EC0     154   10000     680     308               0       0               0       0               0       0               0       0               0       0               0       0               0       0
    78  100000     EC0     156    1000     BC0     312               0       0               0       0               0       0               0       0               0       0               0       0               0       0
    79       1     C80     158      10     800     316               0       0               0       0               0       0               0       0               0       0               0       0               0       0
    80       1     D40     160    1000     800     320               0       0               0       0               0       0               0       0               0       0               0       0               0       0
    81      10     D40     162  100000     800     324               0       0               0       0               0       0               0       0               0       0               0       0               0       0
    82     100     D40     164       1     980     328               0       0               0       0               0       0               0       0               0       0               0       0               0       0
    83    1000     D40     166     100     980     332               0       0               0       0               0       0               0       0               0       0               0       0               0       0
    84   10000     D40     168   10000     980     336               0       0               0       0               0       0               0       0               0       0               0       0               0       0
    85  100000     D40     170  100000     BC0     340               0       0               0       0               0       0               0       0               0       0               0       0               0       0
    86       1    1700     172      10     B00     344               0       0               0       0               0       0               0       0               0       0               0       0               0       0
    87       1     A40     174    1000     B00     348               0       0               0       0               0       0               0       0               0       0               0       0               0       0
    88      10     A40     176  100000     B00     352               0       0               0       0               0       0               0       0               0       0               0       0               0       0
    89     100     A40     178       1     E00     356               0       0               0       0               0       0               0       0               0       0               0       0               0       0
    90    1000     A40     180     100     E00     360               0       0               0       0               0       0               0       0               0       0               0       0               0       0
    91   10000     A40     182   10000     E00     364               0       0               0       0               0       0               0       0               0       0               0       0               0       0
    92  100000     A40     184       1    1880     368               0       0               0       0               0       0               0       0               0       0               0       0               0       0
    93      10    1700     186      10     F80     372               0       0               0       0               0       0               0       0               0       0               0       0               0       0
    94       1     8C0     188    1000     F80     376               0       0               0       0               0       0               0       0               0       0               0       0               0       0
    95      10     8C0     190  100000     F80     380               0       0               0       0               0       0               0       0               0       0               0       0               0       0
    96     100     8C0     192       1    1100     384               0       0               0       0               0       0               0       0               0       0               0       0               0       0
    97    1000     8C0     194     100    1100     388               0       0               0       0               0       0               0       0               0       0               0       0               0       0
    98   10000     8C0     196   10000    1100     392               0       0               0       0               0       0               0       0               0       0               0       0               0       0
    99  100000     8C0     198     100    1880     396               0       0               0       0               0       0               0       0               0       0               0       0               0       0
   100     100    1700     200      10    1280     400               0       0               0       0               0       0               0       0               0       0               0       0               0       0
   101       1     740     202    1000    1280     404               0       0               0       0               0       0               0       0               0       0               0       0               0       0
   102      10     740     204  100000    1280     408               0       0               0       0               0       0               0       0               0       0               0       0               0       0
   103     100     740     206       1    1400     412               0       0               0       0               0       0               0       0               0       0               0       0               0       0
   104    1000     740     208     100    1400     416               0       0               0       0               0       0               0       0               0       0               0       0               0       0
   105   10000     740     210   10000    1400     420               0       0               0       0               0       0               0       0               0       0               0       0               0       0
   106  100000     740     212   10000    1880     424               0       0               0       0               0       0               0       0               0       0               0       0               0       0
   107    1000    1700     214      10    1580     428               0       0               0       0               0       0               0       0               0       0               0       0               0       0
   108       1     5C0     216    1000    1580     432               0       0               0       0               0       0               0       0               0       0               0       0               0       0
   109      10     5C0     218  100000    1580     436               0       0               0       0               0       0               0       0               0       0               0       0               0       0
   110     100     5C0     220       1    17C0     440               0       0               0       0               0       0               0       0               0       0               0       0               0       0
   111    1000     5C0     222     100    17C0     444               0       0               0       0               0       0               0       0               0       0               0       0               0       0
   112   10000     5C0     224   10000    17C0     448               0       0               0       0               0       0               0       0               0       0               0       0               0       0
   113  100000     5C0     226 1000000    1880     452               0       0               0       0               0       0               0       0               0       0               0       0               0       0
   114   10000    1700     228      10    1A00     456               0       0               0       0               0       0               0       0               0       0               0       0               0       0
   115       1     440     230    1000    1A00     460               0       0               0       0               0       0               0       0               0       0               0       0               0       0
   116      10     440     232  100000    1A00     464               0       0               0       0               0       0               0       0               0       0               0       0               0       0
   117     100     440     234       1    1B80     468               0       0               0       0               0       0               0       0               0       0               0       0               0       0
   118    1000     440     236     100    1B80     472               0       0               0       0               0       0               0       0               0       0               0       0               0       0
   119   10000     440     238   10000    1B80     476               0       0               0       0               0       0               0       0               0       0               0       0               0       0
   120  100000     440     24000000000    1880     480               0       0               0       0               0       0               0       0               0       0               0       0               0       0
   121  100000    1700     242      10    1D00     484               0       0               0       0               0       0               0       0               0       0               0       0               0       0
   122       1     2C0     244    1000    1D00     488               0       0               0       0               0       0               0       0               0       0               0       0               0       0
   123      10     2C0     246  100000    1D00     492               0       0               0       0               0       0               0       0               0       0               0       0               0       0
   124     100     2C0     248       1    1E80     496               0       0               0       0               0       0               0       0               0       0               0       0               0       0
   125    1000     2C0     250     100    1E80     500               0       0               0       0               0       0               0       0               0       0               0       0               0       0
   126   10000     2C0     252   10000    1E80     504               0       0               0       0               0       0               0       0               0       0               0       0               0       0
   127  100000     2C0     254 1000000    1E80     508               0       0               0       0               0       0               0       0               0       0               0       0               0       0
  END

    my $a = CreateArea;
    my $t = $a->CreateTree;

    my $N = K(key => 999);
    $N->for(sub
     {my ($index, $start, $next, $end) = @_;
      $t->put($index, $index);
     });

    $N->for(sub
     {my ($index, $start, $next, $end) = @_;
      $t->find($index);
     });

    ok Assemble eq => <<END, clocks=>763430;
  END

Nasm::X86::Tree::findFirst($tree)

Find the first element in a tree and set found|key|data|subTree to show the result.

     Parameter  Description
  1  $tree      Tree descriptor

Example:

    my $N = K(key => 32);
    my $a = CreateArea;
    my $t = $a->CreateTree;

    $N->for(sub
     {my ($i, $start, $next, $end) = @_;
      $t->put($i, $i);
     });

    $N->for(sub
     {my ($i, $start, $next, $end) = @_;
      $t->put($N + $i, $N + $i);
      $t->findFirst;

      If $t->key != $i,
      Then
       {PrintOutTraceBack "Reverse queue first failed at: "; $i->outNL;
       };
      $t->delete($i);
      If $t->size != $N,
      Then
       {PrintOutTraceBack "Reverse queue size failed at: "; $i->outNL;
       };
      $t->printInOrder("A");
     });

    ok Assemble eq => <<END, avx512=>1;
  A  32:    1   2   3   4   5   6   7   8   9   A   B   C   D   E   F  10  11  12  13  14  15  16  17  18  19  1A  1B  1C  1D  1E  1F  20
  A  32:    2   3   4   5   6   7   8   9   A   B   C   D   E   F  10  11  12  13  14  15  16  17  18  19  1A  1B  1C  1D  1E  1F  20  21
  A  32:    3   4   5   6   7   8   9   A   B   C   D   E   F  10  11  12  13  14  15  16  17  18  19  1A  1B  1C  1D  1E  1F  20  21  22
  A  32:    4   5   6   7   8   9   A   B   C   D   E   F  10  11  12  13  14  15  16  17  18  19  1A  1B  1C  1D  1E  1F  20  21  22  23
  A  32:    5   6   7   8   9   A   B   C   D   E   F  10  11  12  13  14  15  16  17  18  19  1A  1B  1C  1D  1E  1F  20  21  22  23  24
  A  32:    6   7   8   9   A   B   C   D   E   F  10  11  12  13  14  15  16  17  18  19  1A  1B  1C  1D  1E  1F  20  21  22  23  24  25
  A  32:    7   8   9   A   B   C   D   E   F  10  11  12  13  14  15  16  17  18  19  1A  1B  1C  1D  1E  1F  20  21  22  23  24  25  26
  A  32:    8   9   A   B   C   D   E   F  10  11  12  13  14  15  16  17  18  19  1A  1B  1C  1D  1E  1F  20  21  22  23  24  25  26  27
  A  32:    9   A   B   C   D   E   F  10  11  12  13  14  15  16  17  18  19  1A  1B  1C  1D  1E  1F  20  21  22  23  24  25  26  27  28
  A  32:    A   B   C   D   E   F  10  11  12  13  14  15  16  17  18  19  1A  1B  1C  1D  1E  1F  20  21  22  23  24  25  26  27  28  29
  A  32:    B   C   D   E   F  10  11  12  13  14  15  16  17  18  19  1A  1B  1C  1D  1E  1F  20  21  22  23  24  25  26  27  28  29  2A
  A  32:    C   D   E   F  10  11  12  13  14  15  16  17  18  19  1A  1B  1C  1D  1E  1F  20  21  22  23  24  25  26  27  28  29  2A  2B
  A  32:    D   E   F  10  11  12  13  14  15  16  17  18  19  1A  1B  1C  1D  1E  1F  20  21  22  23  24  25  26  27  28  29  2A  2B  2C
  A  32:    E   F  10  11  12  13  14  15  16  17  18  19  1A  1B  1C  1D  1E  1F  20  21  22  23  24  25  26  27  28  29  2A  2B  2C  2D
  A  32:    F  10  11  12  13  14  15  16  17  18  19  1A  1B  1C  1D  1E  1F  20  21  22  23  24  25  26  27  28  29  2A  2B  2C  2D  2E
  A  32:   10  11  12  13  14  15  16  17  18  19  1A  1B  1C  1D  1E  1F  20  21  22  23  24  25  26  27  28  29  2A  2B  2C  2D  2E  2F
  A  32:   11  12  13  14  15  16  17  18  19  1A  1B  1C  1D  1E  1F  20  21  22  23  24  25  26  27  28  29  2A  2B  2C  2D  2E  2F  30
  A  32:   12  13  14  15  16  17  18  19  1A  1B  1C  1D  1E  1F  20  21  22  23  24  25  26  27  28  29  2A  2B  2C  2D  2E  2F  30  31
  A  32:   13  14  15  16  17  18  19  1A  1B  1C  1D  1E  1F  20  21  22  23  24  25  26  27  28  29  2A  2B  2C  2D  2E  2F  30  31  32
  A  32:   14  15  16  17  18  19  1A  1B  1C  1D  1E  1F  20  21  22  23  24  25  26  27  28  29  2A  2B  2C  2D  2E  2F  30  31  32  33
  A  32:   15  16  17  18  19  1A  1B  1C  1D  1E  1F  20  21  22  23  24  25  26  27  28  29  2A  2B  2C  2D  2E  2F  30  31  32  33  34
  A  32:   16  17  18  19  1A  1B  1C  1D  1E  1F  20  21  22  23  24  25  26  27  28  29  2A  2B  2C  2D  2E  2F  30  31  32  33  34  35
  A  32:   17  18  19  1A  1B  1C  1D  1E  1F  20  21  22  23  24  25  26  27  28  29  2A  2B  2C  2D  2E  2F  30  31  32  33  34  35  36
  A  32:   18  19  1A  1B  1C  1D  1E  1F  20  21  22  23  24  25  26  27  28  29  2A  2B  2C  2D  2E  2F  30  31  32  33  34  35  36  37
  A  32:   19  1A  1B  1C  1D  1E  1F  20  21  22  23  24  25  26  27  28  29  2A  2B  2C  2D  2E  2F  30  31  32  33  34  35  36  37  38
  A  32:   1A  1B  1C  1D  1E  1F  20  21  22  23  24  25  26  27  28  29  2A  2B  2C  2D  2E  2F  30  31  32  33  34  35  36  37  38  39
  A  32:   1B  1C  1D  1E  1F  20  21  22  23  24  25  26  27  28  29  2A  2B  2C  2D  2E  2F  30  31  32  33  34  35  36  37  38  39  3A
  A  32:   1C  1D  1E  1F  20  21  22  23  24  25  26  27  28  29  2A  2B  2C  2D  2E  2F  30  31  32  33  34  35  36  37  38  39  3A  3B
  A  32:   1D  1E  1F  20  21  22  23  24  25  26  27  28  29  2A  2B  2C  2D  2E  2F  30  31  32  33  34  35  36  37  38  39  3A  3B  3C
  A  32:   1E  1F  20  21  22  23  24  25  26  27  28  29  2A  2B  2C  2D  2E  2F  30  31  32  33  34  35  36  37  38  39  3A  3B  3C  3D
  A  32:   1F  20  21  22  23  24  25  26  27  28  29  2A  2B  2C  2D  2E  2F  30  31  32  33  34  35  36  37  38  39  3A  3B  3C  3D  3E
  A  32:   20  21  22  23  24  25  26  27  28  29  2A  2B  2C  2D  2E  2F  30  31  32  33  34  35  36  37  38  39  3A  3B  3C  3D  3E  3F
  END

Nasm::X86::Tree::findLast($tree)

Find the last key in a tree - crucial for stack like operations.

     Parameter  Description
  1  $tree      Tree descriptor

Example:

    my $N = K(key => 32);
    my $a = CreateArea;
    my $t = $a->CreateTree;

    $N->for(sub
     {my ($i, $start, $next, $end) = @_;
      $t->put($N + $i, $N + $i);
     });

    $N->for(sub
     {my ($i, $start, $next, $end) = @_;
      $t->put($N - $i, $N - $i);
      $t->findLast;
      $t->delete($t->key);
      If $t->size != $N - 1,
      Then
       {PrintOutTraceBack "Queued size failed at: "; $i->outNL;
       };
      $t->printInOrder("A");
     });

    ok Assemble eq => <<END, avx512=>1;
  A  31:   20  21  22  23  24  25  26  27  28  29  2A  2B  2C  2D  2E  2F  30  31  32  33  34  35  36  37  38  39  3A  3B  3C  3D  3E
  A  31:   1F  20  21  22  23  24  25  26  27  28  29  2A  2B  2C  2D  2E  2F  30  31  32  33  34  35  36  37  38  39  3A  3B  3C  3D
  A  31:   1E  1F  20  21  22  23  24  25  26  27  28  29  2A  2B  2C  2D  2E  2F  30  31  32  33  34  35  36  37  38  39  3A  3B  3C
  A  31:   1D  1E  1F  20  21  22  23  24  25  26  27  28  29  2A  2B  2C  2D  2E  2F  30  31  32  33  34  35  36  37  38  39  3A  3B
  A  31:   1C  1D  1E  1F  20  21  22  23  24  25  26  27  28  29  2A  2B  2C  2D  2E  2F  30  31  32  33  34  35  36  37  38  39  3A
  A  31:   1B  1C  1D  1E  1F  20  21  22  23  24  25  26  27  28  29  2A  2B  2C  2D  2E  2F  30  31  32  33  34  35  36  37  38  39
  A  31:   1A  1B  1C  1D  1E  1F  20  21  22  23  24  25  26  27  28  29  2A  2B  2C  2D  2E  2F  30  31  32  33  34  35  36  37  38
  A  31:   19  1A  1B  1C  1D  1E  1F  20  21  22  23  24  25  26  27  28  29  2A  2B  2C  2D  2E  2F  30  31  32  33  34  35  36  37
  A  31:   18  19  1A  1B  1C  1D  1E  1F  20  21  22  23  24  25  26  27  28  29  2A  2B  2C  2D  2E  2F  30  31  32  33  34  35  36
  A  31:   17  18  19  1A  1B  1C  1D  1E  1F  20  21  22  23  24  25  26  27  28  29  2A  2B  2C  2D  2E  2F  30  31  32  33  34  35
  A  31:   16  17  18  19  1A  1B  1C  1D  1E  1F  20  21  22  23  24  25  26  27  28  29  2A  2B  2C  2D  2E  2F  30  31  32  33  34
  A  31:   15  16  17  18  19  1A  1B  1C  1D  1E  1F  20  21  22  23  24  25  26  27  28  29  2A  2B  2C  2D  2E  2F  30  31  32  33
  A  31:   14  15  16  17  18  19  1A  1B  1C  1D  1E  1F  20  21  22  23  24  25  26  27  28  29  2A  2B  2C  2D  2E  2F  30  31  32
  A  31:   13  14  15  16  17  18  19  1A  1B  1C  1D  1E  1F  20  21  22  23  24  25  26  27  28  29  2A  2B  2C  2D  2E  2F  30  31
  A  31:   12  13  14  15  16  17  18  19  1A  1B  1C  1D  1E  1F  20  21  22  23  24  25  26  27  28  29  2A  2B  2C  2D  2E  2F  30
  A  31:   11  12  13  14  15  16  17  18  19  1A  1B  1C  1D  1E  1F  20  21  22  23  24  25  26  27  28  29  2A  2B  2C  2D  2E  2F
  A  31:   10  11  12  13  14  15  16  17  18  19  1A  1B  1C  1D  1E  1F  20  21  22  23  24  25  26  27  28  29  2A  2B  2C  2D  2E
  A  31:    F  10  11  12  13  14  15  16  17  18  19  1A  1B  1C  1D  1E  1F  20  21  22  23  24  25  26  27  28  29  2A  2B  2C  2D
  A  31:    E   F  10  11  12  13  14  15  16  17  18  19  1A  1B  1C  1D  1E  1F  20  21  22  23  24  25  26  27  28  29  2A  2B  2C
  A  31:    D   E   F  10  11  12  13  14  15  16  17  18  19  1A  1B  1C  1D  1E  1F  20  21  22  23  24  25  26  27  28  29  2A  2B
  A  31:    C   D   E   F  10  11  12  13  14  15  16  17  18  19  1A  1B  1C  1D  1E  1F  20  21  22  23  24  25  26  27  28  29  2A
  A  31:    B   C   D   E   F  10  11  12  13  14  15  16  17  18  19  1A  1B  1C  1D  1E  1F  20  21  22  23  24  25  26  27  28  29
  A  31:    A   B   C   D   E   F  10  11  12  13  14  15  16  17  18  19  1A  1B  1C  1D  1E  1F  20  21  22  23  24  25  26  27  28
  A  31:    9   A   B   C   D   E   F  10  11  12  13  14  15  16  17  18  19  1A  1B  1C  1D  1E  1F  20  21  22  23  24  25  26  27
  A  31:    8   9   A   B   C   D   E   F  10  11  12  13  14  15  16  17  18  19  1A  1B  1C  1D  1E  1F  20  21  22  23  24  25  26
  A  31:    7   8   9   A   B   C   D   E   F  10  11  12  13  14  15  16  17  18  19  1A  1B  1C  1D  1E  1F  20  21  22  23  24  25
  A  31:    6   7   8   9   A   B   C   D   E   F  10  11  12  13  14  15  16  17  18  19  1A  1B  1C  1D  1E  1F  20  21  22  23  24
  A  31:    5   6   7   8   9   A   B   C   D   E   F  10  11  12  13  14  15  16  17  18  19  1A  1B  1C  1D  1E  1F  20  21  22  23
  A  31:    4   5   6   7   8   9   A   B   C   D   E   F  10  11  12  13  14  15  16  17  18  19  1A  1B  1C  1D  1E  1F  20  21  22
  A  31:    3   4   5   6   7   8   9   A   B   C   D   E   F  10  11  12  13  14  15  16  17  18  19  1A  1B  1C  1D  1E  1F  20  21
  A  31:    2   3   4   5   6   7   8   9   A   B   C   D   E   F  10  11  12  13  14  15  16  17  18  19  1A  1B  1C  1D  1E  1F  20
  A  31:    1   2   3   4   5   6   7   8   9   A   B   C   D   E   F  10  11  12  13  14  15  16  17  18  19  1A  1B  1C  1D  1E  1F
  END

Nasm::X86::Tree::findNext($tree, $key)

Find the next key greater than the one specified.

     Parameter  Description
  1  $tree      Tree descriptor
  2  $key       Key

Example:

    my $a = CreateArea;
    my $t = $a->CreateTree;
    my $N = K loop => 8;
    $N->for(sub
     {my ($i) = @_;
      $t->put(2*$i, 2*$i);
     });

    (2*$N)->for(sub
     {my ($i) = @_;
      $i->outRightInDec(4); PrintOutString " -> ";
      $t->findNext($i);
      $t->found->out("f: ", " ");
      If $t->found > 0, Then {$t->key->out};
      PrintOutStringNL '.';
     });

    ok Assemble eq => <<END, avx512=>1;
     0 -> f: .... .... .... ...2 key    : .... .... .... ...2.
     1 -> f: .... .... .... ...2 key    : .... .... .... ...2.
     2 -> f: .... .... .... ...4 key    : .... .... .... ...4.
     3 -> f: .... .... .... ...4 key    : .... .... .... ...4.
     4 -> f: .... .... .... ...8 key    : .... .... .... ...6.
     5 -> f: .... .... .... ...8 key    : .... .... .... ...6.
     6 -> f: .... .... .... ..10 key    : .... .... .... ...8.
     7 -> f: .... .... .... ..10 key    : .... .... .... ...8.
     8 -> f: .... .... .... ..20 key    : .... .... .... ...A.
     9 -> f: .... .... .... ..20 key    : .... .... .... ...A.
    10 -> f: .... .... .... ..40 key    : .... .... .... ...C.
    11 -> f: .... .... .... ..40 key    : .... .... .... ...C.
    12 -> f: .... .... .... ..80 key    : .... .... .... ...E.
    13 -> f: .... .... .... ..80 key    : .... .... .... ...E.
    14 -> f: .... .... .... ...0 .
    15 -> f: .... .... .... ...0 .
  END

Nasm::X86::Tree::findPrev($tree, $key)

Find the previous key less than the one specified.

     Parameter  Description
  1  $tree      Tree descriptor
  2  $key       Key

Example:

    my $a = CreateArea;
    my $t = $a->CreateTree;
    my $N = K loop => 8;
    $N->for(sub
     {my ($i) = @_;
      $t->put(2*$i, 2*$i);
     });

    (2*$N)->for(sub
     {my ($i) = @_;
      $i->outRightInDec(4); PrintOutString " -> ";
      $t->findPrev($i);
      $t->found->out("f: ", " ");
      If $t->found > 0, Then {$t->key->out};
      PrintOutStringNL '.';
     });

    ok Assemble eq => <<END, avx512=>1;
     0 -> f: .... .... .... ...0 .
     1 -> f: .... .... .... ...1 key    : .... .... .... ...0.
     2 -> f: .... .... .... ...1 key    : .... .... .... ...0.
     3 -> f: .... .... .... ...2 key    : .... .... .... ...2.
     4 -> f: .... .... .... ...2 key    : .... .... .... ...2.
     5 -> f: .... .... .... ...4 key    : .... .... .... ...4.
     6 -> f: .... .... .... ...4 key    : .... .... .... ...4.
     7 -> f: .... .... .... ...8 key    : .... .... .... ...6.
     8 -> f: .... .... .... ...8 key    : .... .... .... ...6.
     9 -> f: .... .... .... ..10 key    : .... .... .... ...8.
    10 -> f: .... .... .... ..10 key    : .... .... .... ...8.
    11 -> f: .... .... .... ..20 key    : .... .... .... ...A.
    12 -> f: .... .... .... ..20 key    : .... .... .... ...A.
    13 -> f: .... .... .... ..40 key    : .... .... .... ...C.
    14 -> f: .... .... .... ..40 key    : .... .... .... ...C.
    15 -> f: .... .... .... ..80 key    : .... .... .... ...E.
  END

Nasm::X86::Tree::findSubTree($tree, $key)

Find a key in the specified tree and create a sub tree from the data field if possible.

     Parameter  Description
  1  $tree      Tree descriptor
  2  $key       Key as a dword

Example:

    my $a = CreateArea;
    my $t = $a->CreateTree;
    my $T = $a->CreateTree;

    $t->put(1, $T);
    my $u = $t->findSubTree(1);
    $T->first->outNL;
    $u->first->outNL;

    ok Assemble eq => <<END, avx512=>1;
  first  : .... .... .... ..80
  first  : .... .... .... ..80
  END

Sub trees

Construct trees of trees - all private.

Delete

Delete a key from the tree

Nasm::X86::Tree::delete($tree, $key)

Find a key in a tree and delete it returning he value of the l=key deleted if found.

     Parameter  Description
  1  $tree      Tree descriptor
  2  $key       Key field to delete

Example:

    my $a = CreateArea;
    my $t = $a->CreateTree;

    $t->put   (K(key => 1), K(key => 0x11));
    $t->delete(K key => 1);
    $t->size->outNL;

    ok Assemble eq => <<END, avx512=>1;
  size of tree: .... .... .... ...0
  END

    my $a = CreateArea;
    my $t = $a->CreateTree;
    my $i2 = V  k => 2; $t->put($i2, $i2);
    my $i3 = V  k => 3; $t->put($i3, $i3);
    my $i4 = V  k => 4; $t->put($i4, $i4);
    my $i1 = V  k => 1; $t->put($i1, $i1);
    $t->size->outRightInDecNL(4);  $t->dump("4"); $t->delete($i4);
    $t->size->outRightInDecNL(4);  $t->dump("X"); $t->printInOrder("X");

    ok Assemble eq => <<END, avx512=>1;
     4
  4
  At:   80                    length:    4,  data:   C0,  nodes:  100,  first:   40, root, leaf
    Index:    0    1    2    3
    Keys :    1    2    3    4
    Data :    1    2    3    4
  end
     3
  X
  At:   80                    length:    3,  data:   C0,  nodes:  100,  first:   40, root, leaf
    Index:    0    1    2
    Keys :    1    2    3
    Data :    1    2    3
  end
  X   3:    1   2   3
  END

    my $a = CreateArea;
    my $t = $a->CreateTree;
    my $i20 = V  k => 20; $t->put($i20, $i20);
    my $i30 = V  k => 30; $t->put($i30, $i30);
    my $i40 = V  k => 40; $t->put($i40, $i40);
    my $i10 = V  k => 10; $t->put($i10, $i10);
    my $i31 = V  k => 31; $t->put($i31, $i31);
    my $i32 = V  k => 32; $t->put($i32, $i32);
    my $i33 = V  k => 33; $t->put($i33, $i33);
    $t->size->outRightInDecNL(4);  $t->dump("33"); $t->delete($i33);
    $t->size->outRightInDecNL(4);  $t->dump("40"); $t->delete($i40);
    $t->size->outRightInDecNL(4);  $t->dump("X");  $t->printInOrder("X");

    ok Assemble eq => <<END, avx512=>1;
     7
  33
  At:   80                    length:    7,  data:   C0,  nodes:  100,  first:   40, root, leaf
    Index:    0    1    2    3    4    5    6
    Keys :    A   14   1E   1F   20   21   28
    Data :   10   20   30   31   32   33   40
  end
     6
  40
  At:   80                    length:    6,  data:   C0,  nodes:  100,  first:   40, root, leaf
    Index:    0    1    2    3    4    5
    Keys :    A   14   1E   1F   20   28
    Data :   10   20   30   31   32   40
  end
     5
  X
  At:   80                    length:    5,  data:   C0,  nodes:  100,  first:   40, root, leaf
    Index:    0    1    2    3    4
    Keys :    A   14   1E   1F   20
    Data :   10   20   30   31   32
  end
  X   5:    A  14  1E  1F  20
  END

    my $a = CreateArea;
    my $t = $a->CreateTree;
    my $i1 = V  k =>  0; $t->put($i1, $i1);
    my $i2 = V  k => 11; $t->put($i2, $i2);
    my $i3 = V  k => 13; $t->put($i3, $i3);
    my $i4 = V  k => 15; $t->put($i4, $i4);
    $t->size->outRightInDecNL(4);
    $t->dump("1");
    $a->dump("AAA", K blocks => 12);
    $t->delete($i2);
    $t->size->outRightInDecNL(4);  $t->dump("X"); $t->printInOrder("X");

    ok Assemble eq => <<END, avx512=>1;
     4
  1
  At:   80                    length:    4,  data:   C0,  nodes:  100,  first:   40, root, leaf
    Index:    0    1    2    3
    Keys :    0    B    D    F
    Data :    0   11   13   15
  end
  AAA
  Area     Size:     4096    Used:      320
  .... .... .... ...0 | __10 ____ ____ ____  40.1 ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 80__ ____ ____ ____  .4__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | ____ ____ .B__ ____  .D__ ____ .F__ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  .4__ ____ C0__ ____
  .... .... .... ..C0 | ____ ____ .B__ ____  .D__ ____ .F__ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ __.1 ____
  .... .... .... .1.. | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ 40__ ____
  .... .... .... .140 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... .180 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... .1C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... .2.. | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... .240 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... .280 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... .2C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
     3
  X
  At:   80                    length:    3,  data:   C0,  nodes:  100,  first:   40, root, leaf
    Index:    0    1    2
    Keys :    0    D    F
    Data :    0   13   15
  end
  X   3:    0   D   F
  END

    my $a = CreateArea;
    my $t = $a->CreateTree;
    my $i1 = V  k => 1; $t->put($i1, $i1);
    my $i2 = V  k => 2; $t->put($i2, $i2);
    my $i3 = V  k => 3; $t->put($i3, $i3);
    my $i4 = V  k => 4; $t->put($i4, $i4);
    $t->size->outRightInDecNL(4);  $t->dump("1"); $a->dump("AAA", K blocks => 12); $t->delete($i1);
    $t->size->outRightInDecNL(4);  $t->dump("X"); $t->printInOrder("X");

    ok Assemble eq => <<END, avx512=>1;
     4
  1
  At:   80                    length:    4,  data:   C0,  nodes:  100,  first:   40, root, leaf
    Index:    0    1    2    3
    Keys :    1    2    3    4
    Data :    1    2    3    4
  end
  AAA
  Area     Size:     4096    Used:      320
  .... .... .... ...0 | __10 ____ ____ ____  40.1 ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 80__ ____ ____ ____  .4__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | .1__ ____ .2__ ____  .3__ ____ .4__ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  .4__ ____ C0__ ____
  .... .... .... ..C0 | .1__ ____ .2__ ____  .3__ ____ .4__ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ __.1 ____
  .... .... .... .1.. | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ 40__ ____
  .... .... .... .140 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... .180 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... .1C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... .2.. | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... .240 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... .280 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... .2C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
     3
  X
  At:   80                    length:    3,  data:   C0,  nodes:  100,  first:   40, root, leaf
    Index:    0    1    2
    Keys :    2    3    4
    Data :    2    3    4
  end
  X   3:    2   3   4
  END

    my $a = CreateArea;
    my $t = $a->CreateTree;
    my $i1 = V  k => 1; $t->put($i1, $i1);
    my $i2 = V  k => 2; $t->put($i2, $i2);
    my $i3 = V  k => 3; $t->put($i3, $i3);
    my $i4 = V  k => 4; $t->put($i4, $i4);
    $t->size->outRightInDecNL(4); $t->dump("2"); $t->delete($i2);
    $t->size->outRightInDecNL(4); $t->dump("X"); $t->printInOrder("X");

    ok Assemble eq => <<END, avx512=>1;
     4
  2
  At:   80                    length:    4,  data:   C0,  nodes:  100,  first:   40, root, leaf
    Index:    0    1    2    3
    Keys :    1    2    3    4
    Data :    1    2    3    4
  end
     3
  X
  At:   80                    length:    3,  data:   C0,  nodes:  100,  first:   40, root, leaf
    Index:    0    1    2
    Keys :    1    3    4
    Data :    1    3    4
  end
  X   3:    1   3   4
  END

    my $a = CreateArea;
    my $t = $a->CreateTree;
    my $i1 = V  k => 1; $t->put($i1, $i1);
    my $i2 = V  k => 2; $t->put($i2, $i2);
    my $i3 = V  k => 3; $t->put($i3, $i3);
    my $i4 = V  k => 4; $t->put($i4, $i4);
    $t->size->outRightInDecNL(4);  $t->dump("3"); $t->delete($i3);
    $t->size->outRightInDecNL(4);  $t->dump("X"); $t->printInOrder("X");

    ok Assemble eq => <<END, avx512=>1;
     4
  3
  At:   80                    length:    4,  data:   C0,  nodes:  100,  first:   40, root, leaf
    Index:    0    1    2    3
    Keys :    1    2    3    4
    Data :    1    2    3    4
  end
     3
  X
  At:   80                    length:    3,  data:   C0,  nodes:  100,  first:   40, root, leaf
    Index:    0    1    2
    Keys :    1    2    4
    Data :    1    2    4
  end
  X   3:    1   2   4
  END

    my $a = CreateArea;
    my $t = $a->CreateTree;
    my $i1 = V  k => 1; $t->put($i1, $i1);
    my $i2 = V  k => 2; $t->put($i2, $i2);
    my $i3 = V  k => 3; $t->put($i3, $i3);
    my $i4 = V  k => 4; $t->put($i4, $i4);
    $t->size->outRightInDecNL(4);  $t->dump("4"); $t->delete($i4);
    $t->size->outRightInDecNL(4);  $t->dump("X"); $t->printInOrder("X");

    ok Assemble eq => <<END, avx512=>1;
     4
  4
  At:   80                    length:    4,  data:   C0,  nodes:  100,  first:   40, root, leaf
    Index:    0    1    2    3
    Keys :    1    2    3    4
    Data :    1    2    3    4
  end
     3
  X
  At:   80                    length:    3,  data:   C0,  nodes:  100,  first:   40, root, leaf
    Index:    0    1    2
    Keys :    1    2    3
    Data :    1    2    3
  end
  X   3:    1   2   3
  END

    my $a = CreateArea;
    my $t = $a->CreateTree;
    my $i2 = V  k => 2; $t->put($i2, $i2);
    my $i1 = V  k => 1; $t->put($i1, $i1);
    my $i3 = V  k => 3; $t->put($i3, $i3);
    my $i4 = V  k => 4; $t->put($i4, $i4);
    $t->size->outRightInDecNL(4);  $t->dump("0"); $t->delete($i2);
    $t->size->outRightInDecNL(4);  $t->dump("2"); $t->delete($i3);
    $t->size->outRightInDecNL(4);  $t->dump("3"); $t->delete($i4);
    $t->size->outRightInDecNL(4);  $t->dump("4"); $t->delete($i1);
    $t->size->outRightInDecNL(4);  $t->dump("1");

    ok Assemble eq => <<END, avx512=>1;
     4
  0
  At:   80                    length:    4,  data:   C0,  nodes:  100,  first:   40, root, leaf
    Index:    0    1    2    3
    Keys :    1    2    3    4
    Data :    1    2    3    4
  end
     3
  2
  At:   80                    length:    3,  data:   C0,  nodes:  100,  first:   40, root, leaf
    Index:    0    1    2
    Keys :    1    3    4
    Data :    1    3    4
  end
     2
  3
  At:   80                    length:    2,  data:   C0,  nodes:  100,  first:   40, root, leaf
    Index:    0    1
    Keys :    1    4
    Data :    1    4
  end
     1
  4
  At:   80                    length:    1,  data:   C0,  nodes:  100,  first:   40, root, leaf
    Index:    0
    Keys :    1
    Data :    1
  end
     0
  1
  - empty
  END

    my $a = CreateArea;
    my $t = $a->CreateTree;
    $t->put(   K(k=>1), K(d=>11));
    $t->put(   K(k=>2), K(d=>22));
    $t->put(   K(k=>3), K(d=>33));
    $t->delete(K k=>1);  $t->dump("1");
    $t->delete(K k=>3);  $t->dump("3");
    $t->delete(K k=>2);  $t->dump("2");
    ok Assemble eq => <<END, label=>'t4';
  1
  At:   80                    length:    2,  data:   C0,  nodes:  100,  first:   40, root, leaf
    Index:    0    1
    Keys :    2    3
    Data :   22   33
  end
  3
  At:   80                    length:    1,  data:   C0,  nodes:  100,  first:   40, root, leaf
    Index:    0
    Keys :    2
    Data :   22
  end
  2
  - empty
  END

    my $a = CreateArea;
    my $t = $a->CreateTree;
    $t->put(   K(k=>1), K(d=>11));
    $t->put(   K(k=>2), K(d=>22));
    $t->put(   K(k=>3), K(d=>33));
    $t->put(   K(k=>4), K(d=>44));
    $t->dump("0");
    $t->delete(K k=>1);
    $t->dump("1");
    $t->delete(K k=>2);
    $t->dump("2");
    $t->delete(K k=>3);
    $t->dump("3");
    $t->delete(K k=>4);
    $t->dump("4");
    ok Assemble eq => <<END, avx512=>1;
  0
  At:   80                    length:    4,  data:   C0,  nodes:  100,  first:   40, root, leaf
    Index:    0    1    2    3
    Keys :    1    2    3    4
    Data :   11   22   33   44
  end
  1
  At:   80                    length:    3,  data:   C0,  nodes:  100,  first:   40, root, leaf
    Index:    0    1    2
    Keys :    2    3    4
    Data :   22   33   44
  end
  2
  At:   80                    length:    2,  data:   C0,  nodes:  100,  first:   40, root, leaf
    Index:    0    1
    Keys :    3    4
    Data :   33   44
  end
  3
  At:   80                    length:    1,  data:   C0,  nodes:  100,  first:   40, root, leaf
    Index:    0
    Keys :    4
    Data :   44
  end
  4
  - empty
  END

    my $a = CreateArea;
    my $t = $a->CreateTree;
    $t->put(   K(k=>1), K(d=>11));
    $t->put(   K(k=>2), K(d=>22));
    $t->put(   K(k=>3), K(d=>33));
    $t->put(   K(k=>4), K(d=>44));
    $t->dump("0");
    $t->delete(K k=>3);
    $t->dump("3");
    $t->delete(K k=>4);
    $t->dump("4");
    $t->delete(K k=>2);
    $t->dump("2");
    $t->delete(K k=>1);
    $t->dump("1");
    ok Assemble eq => <<END, avx512=>1;
  0
  At:   80                    length:    4,  data:   C0,  nodes:  100,  first:   40, root, leaf
    Index:    0    1    2    3
    Keys :    1    2    3    4
    Data :   11   22   33   44
  end
  3
  At:   80                    length:    3,  data:   C0,  nodes:  100,  first:   40, root, leaf
    Index:    0    1    2
    Keys :    1    2    4
    Data :   11   22   44
  end
  4
  At:   80                    length:    2,  data:   C0,  nodes:  100,  first:   40, root, leaf
    Index:    0    1
    Keys :    1    2
    Data :   11   22
  end
  2
  At:   80                    length:    1,  data:   C0,  nodes:  100,  first:   40, root, leaf
    Index:    0
    Keys :    1
    Data :   11
  end
  1
  - empty
  END

    my $a = CreateArea;
    my $t = $a->CreateTree;
    my $i1 = V  k => 1; $t->put($i1, $i1);
    my $i2 = V  k => 2; $t->put($i2, $i2);
    my $i3 = V  k => 3; $t->put($i3, $i3);
    my $i4 = V  k => 4; $t->put($i4, $i4);
    my $i5 = V  k => 5; $t->put($i5, $i5);
    my $i6 = V  k => 6; $t->put($i6, $i6);
    my $i7 = V  k => 7; $t->put($i7, $i7);
    my $i8 = V  k => 8; $t->put($i8, $i8);
    $t->size->outRightInDecNL(4);  $t->dump("1"); $t->delete($i1);
    $t->size->outRightInDecNL(4);  $t->dump("2"); $t->delete($i2);
    $t->size->outRightInDecNL(4);  $t->dump("3"); $t->delete($i3);
    $t->size->outRightInDecNL(4);  $t->dump("4"); $t->delete($i4);
    $t->size->outRightInDecNL(4);  $t->dump("5"); $t->delete($i5);
    $t->size->outRightInDecNL(4);  $t->dump("6"); $t->delete($i6);
    $t->size->outRightInDecNL(4);  $t->dump("7"); $t->delete($i7);
    $t->size->outRightInDecNL(4);  $t->dump("8"); $t->delete($i8);
    $t->size->outRightInDecNL(4);
    $t->dump("X");

    ok Assemble eq => <<END, avx512=>1;
     8
  1
  At:   80                    length:    8,  data:   C0,  nodes:  100,  first:   40, root, leaf
    Index:    0    1    2    3    4    5    6    7
    Keys :    1    2    3    4    5    6    7    8
    Data :    1    2    3    4    5    6    7    8
  end
     7
  2
  At:   80                    length:    7,  data:   C0,  nodes:  100,  first:   40, root, leaf
    Index:    0    1    2    3    4    5    6
    Keys :    2    3    4    5    6    7    8
    Data :    2    3    4    5    6    7    8
  end
     6
  3
  At:   80                    length:    6,  data:   C0,  nodes:  100,  first:   40, root, leaf
    Index:    0    1    2    3    4    5
    Keys :    3    4    5    6    7    8
    Data :    3    4    5    6    7    8
  end
     5
  4
  At:   80                    length:    5,  data:   C0,  nodes:  100,  first:   40, root, leaf
    Index:    0    1    2    3    4
    Keys :    4    5    6    7    8
    Data :    4    5    6    7    8
  end
     4
  5
  At:   80                    length:    4,  data:   C0,  nodes:  100,  first:   40, root, leaf
    Index:    0    1    2    3
    Keys :    5    6    7    8
    Data :    5    6    7    8
  end
     3
  6
  At:   80                    length:    3,  data:   C0,  nodes:  100,  first:   40, root, leaf
    Index:    0    1    2
    Keys :    6    7    8
    Data :    6    7    8
  end
     2
  7
  At:   80                    length:    2,  data:   C0,  nodes:  100,  first:   40, root, leaf
    Index:    0    1
    Keys :    7    8
    Data :    7    8
  end
     1
  8
  At:   80                    length:    1,  data:   C0,  nodes:  100,  first:   40, root, leaf
    Index:    0
    Keys :    8
    Data :    8
  end
     0
  X
  - empty
  END

    my $a = CreateArea;
    my $t = $a->CreateTree;
    my $N = K loop => 20;
    $N->for(sub                                                                   # Load tree
     {my ($i) = @_;
      $t->put($i, $i);
     });
    $t->size->outNL;        $t->printInOrder("AA");
    $t->delete(K k =>  0);  $t->printInOrder(" 0");
    $t->delete(K k =>  9);  $t->printInOrder(" 9");
    $t->delete(K k =>  1);  $t->printInOrder(" 1");
    $t->delete(K k =>  8);  $t->printInOrder(" 8");
    $t->delete(K k =>  2);  $t->printInOrder(" 2");
    $t->delete(K k =>  7);  $t->printInOrder(" 7");
    $t->delete(K k =>  3);  $t->printInOrder(" 3");
    $t->delete(K k =>  6);  $t->printInOrder(" 6");
    $t->delete(K k =>  4);  $t->printInOrder(" 4");
    $t->delete(K k =>  5);  $t->printInOrder(" 5");
    $t->delete(K k => 10);  $t->printInOrder("10");
    $t->delete(K k => 19);  $t->printInOrder("19");
    $t->delete(K k => 11);  $t->printInOrder("11");
    $t->delete(K k => 18);  $t->printInOrder("18");
    $t->delete(K k => 12);  $t->printInOrder("12");
    $t->delete(K k => 17);  $t->printInOrder("17");
    $t->delete(K k => 13);  $t->printInOrder("13");
    $t->delete(K k => 16);  $t->printInOrder("16");
    $t->delete(K k => 14);  $t->printInOrder("14");
    $t->delete(K k => 15);  $t->printInOrder("15");

    ok Assemble eq => <<END, avx512=>1;
  size of tree: .... .... .... ..14
  AA  20:    0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F  10  11  12  13
   0  19:    1   2   3   4   5   6   7   8   9   A   B   C   D   E   F  10  11  12  13
   9  18:    1   2   3   4   5   6   7   8   A   B   C   D   E   F  10  11  12  13
   1  17:    2   3   4   5   6   7   8   A   B   C   D   E   F  10  11  12  13
   8  16:    2   3   4   5   6   7   A   B   C   D   E   F  10  11  12  13
   2  15:    3   4   5   6   7   A   B   C   D   E   F  10  11  12  13
   7  14:    3   4   5   6   A   B   C   D   E   F  10  11  12  13
   3  13:    4   5   6   A   B   C   D   E   F  10  11  12  13
   6  12:    4   5   A   B   C   D   E   F  10  11  12  13
   4  11:    5   A   B   C   D   E   F  10  11  12  13
   5  10:    A   B   C   D   E   F  10  11  12  13
  10   9:    B   C   D   E   F  10  11  12  13
  19   8:    B   C   D   E   F  10  11  12
  11   7:    C   D   E   F  10  11  12
  18   6:    C   D   E   F  10  11
  12   5:    D   E   F  10  11
  17   4:    D   E   F  10
  13   3:    E   F  10
  16   2:    E   F
  14   1:    F
  15- empty
  END

    my $a = CreateArea;
    my $t = $a->CreateTree;
    my $N = K loop => 16;
    $N->for(sub
     {my ($i) = @_;
      $t->put($i, $i);
     });
    $t->printInOrder(" 0"); $t->delete(K k =>  0);
    $t->printInOrder(" 2"); $t->delete(K k =>  2);
    $t->printInOrder(" 4"); $t->delete(K k =>  4);
    $t->printInOrder(" 6"); $t->delete(K k =>  6);
    $t->printInOrder(" 8"); $t->delete(K k =>  8);
    $t->printInOrder("10"); $t->delete(K k => 10);
    $t->printInOrder("12"); $t->delete(K k => 12);
    $t->printInOrder("14"); $t->delete(K k => 14);
    $t->printInOrder(" 1"); $t->delete(K k =>  1);
    $t->printInOrder(" 3"); $t->delete(K k =>  3);
    $t->printInOrder(" 5"); $t->delete(K k =>  5);
    $t->printInOrder(" 7"); $t->delete(K k =>  7);
    $t->printInOrder(" 9"); $t->delete(K k =>  9);
    $t->printInOrder("11"); $t->delete(K k => 11);
    $t->printInOrder("13"); $t->delete(K k => 13);
    $t->printInOrder("15"); $t->delete(K k => 15);
    $t->printInOrder("XX");

    ok Assemble eq => <<END, avx512=>1;
   0  16:    0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
   2  15:    1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
   4  14:    1   3   4   5   6   7   8   9   A   B   C   D   E   F
   6  13:    1   3   5   6   7   8   9   A   B   C   D   E   F
   8  12:    1   3   5   7   8   9   A   B   C   D   E   F
  10  11:    1   3   5   7   9   A   B   C   D   E   F
  12  10:    1   3   5   7   9   B   C   D   E   F
  14   9:    1   3   5   7   9   B   D   E   F
   1   8:    1   3   5   7   9   B   D   F
   3   7:    3   5   7   9   B   D   F
   5   6:    5   7   9   B   D   F
   7   5:    7   9   B   D   F
   9   4:    9   B   D   F
  11   3:    B   D   F
  13   2:    D   F
  15   1:    F
  XX- empty
  END

    my $a = CreateArea;
    my $t = $a->CreateTree;
    my $N = K max => 8;

    $N->for(sub                                                                   # Load tree
     {my ($i) = @_;
      $t->put(         $i,     2 *        $i);
      $t->put(2 * $N - $i - 1, 2 * ($N -  $i));
     });
  #  $t->printInOrder("Full");

    ($N-1)->for(sub                                                               # Delete elements
     {my ($i) = @_;
      my $n1 = ($N + $i)->clone("1111"); my $n2 = ($N - $i - 1)->clone("2222");

      $n1->outNL;
      $t->delete($n1);
      $t->printInOrder("1111");

      $n2->outNL;
      $t->delete($n2);
      $t->printInOrder("2222");
     });
    $t->dump("Two:");
    $t->size->outRightInDecNL(4);

    ok Assemble eq => <<END, avx512=>1;
  1111: .... .... .... ...8
  1111  15:    0   1   2   3   4   5   6   7   9   A   B   C   D   E   F
  2222: .... .... .... ...7
  2222  14:    0   1   2   3   4   5   6   9   A   B   C   D   E   F
  1111: .... .... .... ...9
  1111  13:    0   1   2   3   4   5   6   A   B   C   D   E   F
  2222: .... .... .... ...6
  2222  12:    0   1   2   3   4   5   A   B   C   D   E   F
  1111: .... .... .... ...A
  1111  11:    0   1   2   3   4   5   B   C   D   E   F
  2222: .... .... .... ...5
  2222  10:    0   1   2   3   4   B   C   D   E   F
  1111: .... .... .... ...B
  1111   9:    0   1   2   3   4   C   D   E   F
  2222: .... .... .... ...4
  2222   8:    0   1   2   3   C   D   E   F
  1111: .... .... .... ...C
  1111   7:    0   1   2   3   D   E   F
  2222: .... .... .... ...3
  2222   6:    0   1   2   D   E   F
  1111: .... .... .... ...D
  1111   5:    0   1   2   E   F
  2222: .... .... .... ...2
  2222   4:    0   1   E   F
  1111: .... .... .... ...E
  1111   3:    0   1   F
  2222: .... .... .... ...1
  2222   2:    0   F
  Two:
  At:   80                    length:    2,  data:   C0,  nodes:  100,  first:   40, root, leaf
    Index:    0    1
    Keys :    0    F
    Data :    0   16
  end
     2
  END

    my $a = CreateArea;
    my $t = $a->CreateTree;
    my $N = K max => 100;

    $N->for(sub                                                                   # Load tree
     {my ($index, $start, $next, $end) = @_;
      $t->put($index, 2 * $index);
      If $t->size != $index + 1,
      Then
       {PrintOutStringNL "SSSS"; $index->outNL; Exit(0);
       };
     });

    $N->for(sub                                                                   # Check elements
     {my ($i) = @_;
      $t->find($i);
      If $t->found == 0,
      Then
       {PrintOutStringNL "AAAA"; $i->outNL; Exit(0);
       };
     });

    $N->for(sub                                                                   # Delete elements
     {my ($i) = @_;
      $t->delete($i);

      If $t->size != $N - $i - 1,
      Then
       {PrintOutStringNL "TTTT"; $i->outNL; Exit(0);
       };

      $N->for(sub                                                                 # Check elements
       {my ($j) = @_;
        $t->find($j);
        If $t->found == 0,
        Then
         {If $j > $i,
          Then
           {PrintOutStringNL "BBBBB"; $j->outNL; Exit(0);                         # Not deleted yet so it should be findable
           };
         },
        Else
         {If $j <= $i,
          Then
           {PrintOutStringNL "CCCCC"; $j->outNL; Exit(0);                         # Deleted so should not be findable
           };
         };
       });
     });

    ok Assemble eq => <<END, avx512=>1;
  END

    my $a = CreateArea;
    my $t = $a->CreateTree;
    my $N = K loop => 16;
    $N->for(sub
     {my ($i) = @_;
      $t->put($i, $i);
     });
    ($N/2)->for(sub
     {my ($i) = @_;
      $t->printInOrder("AAAA");
      $t->delete($i * 2);
     });
    ($N/2)->for(sub
     {my ($i) = @_;
      $t->printInOrder("BBBB");
      $t->delete($i * 2 + 1);
     });
    $t->printInOrder("CCCC");

    ok Assemble eq => <<END, avx512=>1;
  AAAA  16:    0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
  AAAA  15:    1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
  AAAA  14:    1   3   4   5   6   7   8   9   A   B   C   D   E   F
  AAAA  13:    1   3   5   6   7   8   9   A   B   C   D   E   F
  AAAA  12:    1   3   5   7   8   9   A   B   C   D   E   F
  AAAA  11:    1   3   5   7   9   A   B   C   D   E   F
  AAAA  10:    1   3   5   7   9   B   C   D   E   F
  AAAA   9:    1   3   5   7   9   B   D   E   F
  BBBB   8:    1   3   5   7   9   B   D   F
  BBBB   7:    3   5   7   9   B   D   F
  BBBB   6:    5   7   9   B   D   F
  BBBB   5:    7   9   B   D   F
  BBBB   4:    9   B   D   F
  BBBB   3:    B   D   F
  BBBB   2:    D   F
  BBBB   1:    F
  CCCC- empty
  END

    my $a = CreateArea;
    my $t = $a->CreateTree;
    my $N = K loop => 36;
    $N->for(sub
     {my ($i) = @_;
      $t->put($i, $i);
     });
    $t->delete(K 1 =>  0); $t->printInOrder(" 0");
    $t->delete(K 1 =>  5); $t->printInOrder(" 5");
    $t->delete(K 1 => 10); $t->printInOrder("10");
    $t->delete(K 1 => 15); $t->printInOrder("15");
    $t->delete(K 1 => 20); $t->printInOrder("20");
    $t->delete(K 1 => 25); $t->printInOrder("25");
    $t->delete(K 1 => 30); $t->printInOrder("30");
    $t->delete(K 1 => 35); $t->printInOrder("35");

    $t->delete(K 1 =>  1); $t->printInOrder(" 1");
    $t->delete(K 1 =>  6); $t->printInOrder(" 6");
    $t->delete(K 1 => 11); $t->printInOrder("11");
    $t->delete(K 1 => 16); $t->printInOrder("16");
    $t->delete(K 1 => 21); $t->printInOrder("21");
    $t->delete(K 1 => 26); $t->printInOrder("26");
    $t->delete(K 1 => 31); $t->printInOrder("31");

    $t->delete(K 1 =>  2); $t->printInOrder(" 2");
    $t->delete(K 1 =>  7); $t->printInOrder(" 7");
    $t->delete(K 1 => 12); $t->printInOrder("12");
    $t->delete(K 1 => 17); $t->printInOrder("17");
    $t->delete(K 1 => 22); $t->printInOrder("22");
    $t->delete(K 1 => 27); $t->printInOrder("27");
    $t->delete(K 1 => 32); $t->printInOrder("32");

    $t->delete(K 1 =>  3); $t->printInOrder(" 3");
    $t->delete(K 1 =>  8); $t->printInOrder(" 8");
    $t->delete(K 1 => 13); $t->printInOrder("13");
    $t->delete(K 1 => 18); $t->printInOrder("18");
    $t->delete(K 1 => 23); $t->printInOrder("23");
    $t->delete(K 1 => 28); $t->printInOrder("28");
    $t->delete(K 1 => 33); $t->printInOrder("33");

    $t->delete(K 1 =>  4); $t->printInOrder(" 4");
    $t->delete(K 1 =>  9); $t->printInOrder(" 9");
    $t->delete(K 1 => 14); $t->printInOrder("14");
    $t->delete(K 1 => 19); $t->printInOrder("19");
    $t->delete(K 1 => 24); $t->printInOrder("24");
    $t->delete(K 1 => 29); $t->printInOrder("29");
    $t->delete(K 1 => 34); $t->printInOrder("34");

    ok Assemble eq => <<END, avx512=>1;
   0  35:    1   2   3   4   5   6   7   8   9   A   B   C   D   E   F  10  11  12  13  14  15  16  17  18  19  1A  1B  1C  1D  1E  1F  20  21  22  23
   5  34:    1   2   3   4   6   7   8   9   A   B   C   D   E   F  10  11  12  13  14  15  16  17  18  19  1A  1B  1C  1D  1E  1F  20  21  22  23
  10  33:    1   2   3   4   6   7   8   9   B   C   D   E   F  10  11  12  13  14  15  16  17  18  19  1A  1B  1C  1D  1E  1F  20  21  22  23
  15  32:    1   2   3   4   6   7   8   9   B   C   D   E  10  11  12  13  14  15  16  17  18  19  1A  1B  1C  1D  1E  1F  20  21  22  23
  20  31:    1   2   3   4   6   7   8   9   B   C   D   E  10  11  12  13  15  16  17  18  19  1A  1B  1C  1D  1E  1F  20  21  22  23
  25  30:    1   2   3   4   6   7   8   9   B   C   D   E  10  11  12  13  15  16  17  18  1A  1B  1C  1D  1E  1F  20  21  22  23
  30  29:    1   2   3   4   6   7   8   9   B   C   D   E  10  11  12  13  15  16  17  18  1A  1B  1C  1D  1F  20  21  22  23
  35  28:    1   2   3   4   6   7   8   9   B   C   D   E  10  11  12  13  15  16  17  18  1A  1B  1C  1D  1F  20  21  22
   1  27:    2   3   4   6   7   8   9   B   C   D   E  10  11  12  13  15  16  17  18  1A  1B  1C  1D  1F  20  21  22
   6  26:    2   3   4   7   8   9   B   C   D   E  10  11  12  13  15  16  17  18  1A  1B  1C  1D  1F  20  21  22
  11  25:    2   3   4   7   8   9   C   D   E  10  11  12  13  15  16  17  18  1A  1B  1C  1D  1F  20  21  22
  16  24:    2   3   4   7   8   9   C   D   E  11  12  13  15  16  17  18  1A  1B  1C  1D  1F  20  21  22
  21  23:    2   3   4   7   8   9   C   D   E  11  12  13  16  17  18  1A  1B  1C  1D  1F  20  21  22
  26  22:    2   3   4   7   8   9   C   D   E  11  12  13  16  17  18  1B  1C  1D  1F  20  21  22
  31  21:    2   3   4   7   8   9   C   D   E  11  12  13  16  17  18  1B  1C  1D  20  21  22
   2  20:    3   4   7   8   9   C   D   E  11  12  13  16  17  18  1B  1C  1D  20  21  22
   7  19:    3   4   8   9   C   D   E  11  12  13  16  17  18  1B  1C  1D  20  21  22
  12  18:    3   4   8   9   D   E  11  12  13  16  17  18  1B  1C  1D  20  21  22
  17  17:    3   4   8   9   D   E  12  13  16  17  18  1B  1C  1D  20  21  22
  22  16:    3   4   8   9   D   E  12  13  17  18  1B  1C  1D  20  21  22
  27  15:    3   4   8   9   D   E  12  13  17  18  1C  1D  20  21  22
  32  14:    3   4   8   9   D   E  12  13  17  18  1C  1D  21  22
   3  13:    4   8   9   D   E  12  13  17  18  1C  1D  21  22
   8  12:    4   9   D   E  12  13  17  18  1C  1D  21  22
  13  11:    4   9   E  12  13  17  18  1C  1D  21  22
  18  10:    4   9   E  13  17  18  1C  1D  21  22
  23   9:    4   9   E  13  18  1C  1D  21  22
  28   8:    4   9   E  13  18  1D  21  22
  33   7:    4   9   E  13  18  1D  22
   4   6:    9   E  13  18  1D  22
   9   5:    E  13  18  1D  22
  14   4:   13  18  1D  22
  19   3:   18  1D  22
  24   2:   1D  22
  29   1:   22
  34- empty
  END

Nasm::X86::Tree::clear($tree)

Delete everything in the tree except the first block recording any memory liberated on the free chain.

     Parameter  Description
  1  $tree      Tree

Example:

    my $a = CreateArea;
    my $t = $a->CreateTree;
    my $N = K loop => 16;

    $N->for(sub {my ($i) = @_; $t->push($i+1)});
    $t->size->out("t: ", " ");
    $a->used->out("u: ", " ");
    $a->freeChainSpace->out("f: ", " ");
    $a->size->outNL;
    $t->clear;
    $t->size->out("t: ", " ");
    $a->used->out("u: ", " ");
    $a->freeChainSpace->out("f: ", " ");
    $a->size->outNL;

    $N->for(sub {my ($i) = @_; $t->push($i+1)});
    $t->size->out("t: ", " ");
    $a->used->out("u: ", " ");
    $a->freeChainSpace->out("f: ", " ");
    $a->size->outNL;
    $t->clear;
    $t->size->out("t: ", " ");
    $a->used->out("u: ", " ");
    $a->freeChainSpace->out("f: ", " ");
    $a->size->outNL;

    $N->for(sub {my ($i) = @_; $t->push($i+1)});
    $t->free;
    $a->used->out("Clear tree:            u: ");
    $a->freeChainSpace->out(" f: ", " ");
    $a->size->outNL;

    $a->clear;
    $a->used->out("Clear area:            u: ");
    $a->freeChainSpace->out(" f: ", " ");
    $a->size->outNL;

    ok Assemble eq => <<END, label=>'t5';
  t: .... .... .... ..10 u: .... .... .... .280 f: .... .... .... ...0 size of area: .... .... .... 10..
  t: .... .... .... ...0 u: .... .... .... .280 f: .... .... .... .240 size of area: .... .... .... 10..
  t: .... .... .... ..10 u: .... .... .... .280 f: .... .... .... ...0 size of area: .... .... .... 10..
  t: .... .... .... ...0 u: .... .... .... .280 f: .... .... .... .240 size of area: .... .... .... 10..
  Clear tree:            u: .... .... .... .280 f: .... .... .... .240 size of area: .... .... .... 10..
  Clear area:            u: .... .... .... ...0 f: .... .... .... ...0 size of area: .... .... .... 10..
  END

Nasm::X86::Tree::free($tree)

Free all the memory used by a tree.

     Parameter  Description
  1  $tree      Tree

Example:

    my $a = CreateArea;
    my $t = $a->CreateTree;
    my $N = K loop => 16;

    $N->for(sub {my ($i) = @_; $t->push($i+1)});
    $t->size->out("t: ", " ");
    $a->used->out("u: ", " ");
    $a->freeChainSpace->out("f: ", " ");
    $a->size->outNL;
    $t->clear;
    $t->size->out("t: ", " ");
    $a->used->out("u: ", " ");
    $a->freeChainSpace->out("f: ", " ");
    $a->size->outNL;

    $N->for(sub {my ($i) = @_; $t->push($i+1)});
    $t->size->out("t: ", " ");
    $a->used->out("u: ", " ");
    $a->freeChainSpace->out("f: ", " ");
    $a->size->outNL;
    $t->clear;
    $t->size->out("t: ", " ");
    $a->used->out("u: ", " ");
    $a->freeChainSpace->out("f: ", " ");
    $a->size->outNL;

    $N->for(sub {my ($i) = @_; $t->push($i+1)});
    $t->free;
    $a->used->out("Clear tree:            u: ");
    $a->freeChainSpace->out(" f: ", " ");
    $a->size->outNL;

    $a->clear;
    $a->used->out("Clear area:            u: ");
    $a->freeChainSpace->out(" f: ", " ");
    $a->size->outNL;

    ok Assemble eq => <<END, label=>'t5';
  t: .... .... .... ..10 u: .... .... .... .280 f: .... .... .... ...0 size of area: .... .... .... 10..
  t: .... .... .... ...0 u: .... .... .... .280 f: .... .... .... .240 size of area: .... .... .... 10..
  t: .... .... .... ..10 u: .... .... .... .280 f: .... .... .... ...0 size of area: .... .... .... 10..
  t: .... .... .... ...0 u: .... .... .... .280 f: .... .... .... .240 size of area: .... .... .... 10..
  Clear tree:            u: .... .... .... .280 f: .... .... .... .240 size of area: .... .... .... 10..
  Clear area:            u: .... .... .... ...0 f: .... .... .... ...0 size of area: .... .... .... 10..
  END

Iteration

Iterate through a tree non recursively

Nasm::X86::Tree::by($tree, $block)

Call the specified block with each element of the specified tree in ascending order.

     Parameter  Description
  1  $tree      Tree descriptor
  2  $block     Block to execute

Example:

    my $a = CreateArea;
    my $t = $a->CreateTree;
    my $N = K loop => 16;
    $N->for(sub
     {my ($i) = @_;
      $t->put($i, 2 * $i);
     });

    $t->by(sub
     {my ($tree, $start, $next, $end) = @_;
      $tree->key->out("");  $tree->data->outNL(" ");
     });

    ok Assemble eq => <<END, avx512=>1;
  .... .... .... ...0 .... .... .... ...0
  .... .... .... ...1 .... .... .... ...2
  .... .... .... ...2 .... .... .... ...4
  .... .... .... ...3 .... .... .... ...6
  .... .... .... ...4 .... .... .... ...8
  .... .... .... ...5 .... .... .... ...A
  .... .... .... ...6 .... .... .... ...C
  .... .... .... ...7 .... .... .... ...E
  .... .... .... ...8 .... .... .... ..10
  .... .... .... ...9 .... .... .... ..12
  .... .... .... ...A .... .... .... ..14
  .... .... .... ...B .... .... .... ..16
  .... .... .... ...C .... .... .... ..18
  .... .... .... ...D .... .... .... ..1A
  .... .... .... ...E .... .... .... ..1C
  .... .... .... ...F .... .... .... ..1E
  END

Nasm::X86::Tree::yb($tree, $block)

Call the specified block with each element of the specified tree in descending order.

     Parameter  Description
  1  $tree      Tree descriptor
  2  $block     Block to execute

Example:

    my $a = CreateArea;
    my $t = $a->CreateTree;
    my $N = K loop => 16;
    $N->for(sub
     {my ($i) = @_;
      $t->put($i, 2* $i);
     });

    $t->yb(sub
     {my ($tree, $start, $prev, $end) = @_;
      $tree->key->out("");  $tree->data->outNL(" ");
     });

    ok Assemble eq => <<END, avx512=>1;
  .... .... .... ...F .... .... .... ..1E
  .... .... .... ...E .... .... .... ..1C
  .... .... .... ...D .... .... .... ..1A
  .... .... .... ...C .... .... .... ..18
  .... .... .... ...B .... .... .... ..16
  .... .... .... ...A .... .... .... ..14
  .... .... .... ...9 .... .... .... ..12
  .... .... .... ...8 .... .... .... ..10
  .... .... .... ...7 .... .... .... ...E
  .... .... .... ...6 .... .... .... ...C
  .... .... .... ...5 .... .... .... ...A
  .... .... .... ...4 .... .... .... ...8
  .... .... .... ...3 .... .... .... ...6
  .... .... .... ...2 .... .... .... ...4
  .... .... .... ...1 .... .... .... ...2
  .... .... .... ...0 .... .... .... ...0
  END

Push and Pop

Use a tree as a stack: Push elements on to a tree with the next available key; Pop the last element in a tree.

Nasm::X86::Tree::peek($tree, $Back)

Peek at the element the specified distance back from the top of the stack and return its value in data and found status in found in the tree descriptor.

     Parameter  Description
  1  $tree      Tree descriptor
  2  $Back      How far back to go with 1 being the top

Example:

    my $a = CreateArea;
    my $t = $a->CreateTree;
    my $N = K loop => 16;
    $N->for(sub
     {my ($i) = @_;
      $t->push($i);
     });

    $t->peek(1)->data ->outNL;
    $t->peek(2)->data ->outNL;
    $t->peek(3)->found->outNL;
    $t->peek(2 * $N    )->found->outNL;

    $t->size->outNL;
    $t->get(8); $t->found->out("f: ", " ");  $t->key->out("i: ", " "); $t->data->outNL;

    $N->for(sub
     {my ($i) = @_;
      $t->pop; $t->found->out("f: ", " ");  $t->key->out("i: ", " "); $t->data->outNL;
     });
  # $t->pop; $t->found->outNL("f: ");

    ok Assemble eq => <<END, clocks => 29_852;
  data   : .... .... .... ...F
  data   : .... .... .... ...E
  found  : .... .... .... ..40
  found  : .... .... .... ...0
  size of tree: .... .... .... ..10
  f: .... .... .... ...2 i: .... .... .... ...8 data   : .... .... .... ...8
  f: .... .... .... ...1 i: .... .... .... ...F data   : .... .... .... ...F
  f: .... .... .... ...1 i: .... .... .... ...E data   : .... .... .... ...E
  f: .... .... .... ...1 i: .... .... .... ...D data   : .... .... .... ...D
  f: .... .... .... ...1 i: .... .... .... ...C data   : .... .... .... ...C
  f: .... .... .... ...1 i: .... .... .... ...B data   : .... .... .... ...B
  f: .... .... .... ...1 i: .... .... .... ...A data   : .... .... .... ...A
  f: .... .... .... ...1 i: .... .... .... ...9 data   : .... .... .... ...9
  f: .... .... .... ...1 i: .... .... .... ...8 data   : .... .... .... ...8
  f: .... .... .... ...1 i: .... .... .... ...7 data   : .... .... .... ...7
  f: .... .... .... ...1 i: .... .... .... ...6 data   : .... .... .... ...6
  f: .... .... .... ...1 i: .... .... .... ...5 data   : .... .... .... ...5
  f: .... .... .... ...1 i: .... .... .... ...4 data   : .... .... .... ...4
  f: .... .... .... ...1 i: .... .... .... ...3 data   : .... .... .... ...3
  f: .... .... .... ...1 i: .... .... .... ...2 data   : .... .... .... ...2
  f: .... .... .... ...1 i: .... .... .... ...1 data   : .... .... .... ...1
  f: .... .... .... ...1 i: .... .... .... ...0 data   : .... .... .... ...0
  END

Nasm::X86::Tree::peekSubTree($tree, $Back)

Pop the last value out of a tree and return a tree descriptor positioned on it with the first/found fields set.

     Parameter  Description
  1  $tree      Tree descriptor
  2  $Back      How far back to go with 1 being the top

Example:

    my $a = CreateArea;
    my $t = $a->CreateTree;
    my $T = $a->CreateTree;

    $T->push(0x22);
    $t->push($T);
    my $u = $t->peekSubTree(1);
    $u->peek(1);
    $u->found->outNL;
    $u->data->outNL;
    ok Assemble eq => <<END, avx512=>1;
  found  : .... .... .... ...1
  data   : .... .... .... ..22
  END

Nasm::X86::Tree::pop($tree)

Pop the last value out of a tree and return the key/data/subTree in the tree descriptor.

     Parameter  Description
  1  $tree      Tree descriptor

Example:

    my $a = CreateArea;
    my $t = $a->CreateTree;
    my $N = K loop => 16;
    $N->for(sub
     {my ($i) = @_;
      $t->push($i);
     });

    $t->peek(1)->data ->outNL;
    $t->peek(2)->data ->outNL;
    $t->peek(3)->found->outNL;
    $t->peek(2 * $N    )->found->outNL;

    $t->size->outNL;
    $t->get(8); $t->found->out("f: ", " ");  $t->key->out("i: ", " "); $t->data->outNL;

    $N->for(sub
     {my ($i) = @_;
      $t->pop; $t->found->out("f: ", " ");  $t->key->out("i: ", " "); $t->data->outNL;
     });
  # $t->pop; $t->found->outNL("f: ");

    ok Assemble eq => <<END, clocks => 29_852;
  data   : .... .... .... ...F
  data   : .... .... .... ...E
  found  : .... .... .... ..40
  found  : .... .... .... ...0
  size of tree: .... .... .... ..10
  f: .... .... .... ...2 i: .... .... .... ...8 data   : .... .... .... ...8
  f: .... .... .... ...1 i: .... .... .... ...F data   : .... .... .... ...F
  f: .... .... .... ...1 i: .... .... .... ...E data   : .... .... .... ...E
  f: .... .... .... ...1 i: .... .... .... ...D data   : .... .... .... ...D
  f: .... .... .... ...1 i: .... .... .... ...C data   : .... .... .... ...C
  f: .... .... .... ...1 i: .... .... .... ...B data   : .... .... .... ...B
  f: .... .... .... ...1 i: .... .... .... ...A data   : .... .... .... ...A
  f: .... .... .... ...1 i: .... .... .... ...9 data   : .... .... .... ...9
  f: .... .... .... ...1 i: .... .... .... ...8 data   : .... .... .... ...8
  f: .... .... .... ...1 i: .... .... .... ...7 data   : .... .... .... ...7
  f: .... .... .... ...1 i: .... .... .... ...6 data   : .... .... .... ...6
  f: .... .... .... ...1 i: .... .... .... ...5 data   : .... .... .... ...5
  f: .... .... .... ...1 i: .... .... .... ...4 data   : .... .... .... ...4
  f: .... .... .... ...1 i: .... .... .... ...3 data   : .... .... .... ...3
  f: .... .... .... ...1 i: .... .... .... ...2 data   : .... .... .... ...2
  f: .... .... .... ...1 i: .... .... .... ...1 data   : .... .... .... ...1
  f: .... .... .... ...1 i: .... .... .... ...0 data   : .... .... .... ...0
  END

Nasm::X86::Tree::popSubTree($tree, %options)

Pop the last value out of a tree and return a tree descriptor positioned on it with the first/found fields set.

     Parameter  Description
  1  $tree      Tree descriptor
  2  %options   Options describing the sub tree

Example:

    my $a = CreateArea;
    my $t = $a->CreateTree;
    my $T = $a->CreateTree;
       $T->push(K key => 0x333);

    $t->push($T);
    $t->push(K key => 0x22);

    $t->pop;
    $t->found->outNL;
    $t->data->outNL;
    $t->subTree->outNL;

    my $P = $t->popSubTree;
    $t->found->outNL;
    $t->data->outNL;
    $t->subTree->outNL;
    PrintOutStringNL "PPPPP";
    $P->find(K key => 0);
    $P->found->outNL;
    $P->data->outNL;

    ok Assemble eq => <<END, avx512=>1;
  found  : .... .... .... ...1
  data   : .... .... .... ..22
  subTree: .... .... .... ...0
  found  : .... .... .... ...1
  data   : .... .... .... ..80
  subTree: .... .... .... ...1
  PPPPP
  found  : .... .... .... ...1
  data   : .... .... .... .333
  END

Nasm::X86::Tree::get($tree, $Key)

Retrieves the element at the specified zero based index in the stack.

     Parameter  Description
  1  $tree      Tree descriptor
  2  $Key       Zero based index

Example:

    my $a = CreateArea;
    my $t = $a->CreateTree;
    my $N = K loop => 16;
    $N->for(sub
     {my ($i) = @_;
      $t->push($i);
     });

    $t->peek(1)->data ->outNL;
    $t->peek(2)->data ->outNL;
    $t->peek(3)->found->outNL;
    $t->peek(2 * $N    )->found->outNL;

    $t->size->outNL;
    $t->get(8); $t->found->out("f: ", " ");  $t->key->out("i: ", " "); $t->data->outNL;

    $N->for(sub
     {my ($i) = @_;
      $t->pop; $t->found->out("f: ", " ");  $t->key->out("i: ", " "); $t->data->outNL;
     });
  # $t->pop; $t->found->outNL("f: ");

    ok Assemble eq => <<END, clocks => 29_852;
  data   : .... .... .... ...F
  data   : .... .... .... ...E
  found  : .... .... .... ..40
  found  : .... .... .... ...0
  size of tree: .... .... .... ..10
  f: .... .... .... ...2 i: .... .... .... ...8 data   : .... .... .... ...8
  f: .... .... .... ...1 i: .... .... .... ...F data   : .... .... .... ...F
  f: .... .... .... ...1 i: .... .... .... ...E data   : .... .... .... ...E
  f: .... .... .... ...1 i: .... .... .... ...D data   : .... .... .... ...D
  f: .... .... .... ...1 i: .... .... .... ...C data   : .... .... .... ...C
  f: .... .... .... ...1 i: .... .... .... ...B data   : .... .... .... ...B
  f: .... .... .... ...1 i: .... .... .... ...A data   : .... .... .... ...A
  f: .... .... .... ...1 i: .... .... .... ...9 data   : .... .... .... ...9
  f: .... .... .... ...1 i: .... .... .... ...8 data   : .... .... .... ...8
  f: .... .... .... ...1 i: .... .... .... ...7 data   : .... .... .... ...7
  f: .... .... .... ...1 i: .... .... .... ...6 data   : .... .... .... ...6
  f: .... .... .... ...1 i: .... .... .... ...5 data   : .... .... .... ...5
  f: .... .... .... ...1 i: .... .... .... ...4 data   : .... .... .... ...4
  f: .... .... .... ...1 i: .... .... .... ...3 data   : .... .... .... ...3
  f: .... .... .... ...1 i: .... .... .... ...2 data   : .... .... .... ...2
  f: .... .... .... ...1 i: .... .... .... ...1 data   : .... .... .... ...1
  f: .... .... .... ...1 i: .... .... .... ...0 data   : .... .... .... ...0
  END

Trees as Strings

Use trees as strings of dwords. The size of the tree is the length of the string. Each dword is consider as an indivisible unit. This arrangement allows the normal string operations of concatenation and substring to be performed easily.

Nasm::X86::Tree::appendAscii($string, $address, $size)

Append ascii bytes in memory to a tree acting as a string. The address and size of the source memory are specified via variables. Each byte should represent a valid ascii byte so that it can be considered, when left extended with 24 zero bits, as utf32.

     Parameter  Description
  1  $string    Tree descriptor of string to append to
  2  $address   Variable address of memory to append from
  3  $size      Variable size of memory

Example:

    my $a = CreateArea;
    my $t = $a->CreateTree;
    my $b = Rb(0x41..0x51);
    $t->appendAscii(K(address=> $b), K(size => 1));
    $t->outAsUtf8NL;
    my $T = $a->CreateTree;
    $T->append($t);
    $T->append($t);
    $T->outAsUtf8NL;
    $T->appendAscii(K(address=> $b) + 1, K(size => 1));
    my $c = $T->clone;
    $c->outAsUtf8NL;
    my $d = $c->substring(1, 3);
    $d->outAsUtf8NL;
    ok Assemble eq => <<END, avx512=>1;
  A
  AA
  AAB
  AB
  END

Nasm::X86::Tree::append($string, $append)

Append the second source string to the first target string renumbering the keys of the source string to follow on from those of the target string. A string can safely be appended to itself.

     Parameter  Description
  1  $string    Tree descriptor of string to append to
  2  $append    Tree descriptor of string to append from

Example:

    my $a = CreateArea;
    my $t = $a->CreateTree;

    $t->push(K alpha => 0x03b1);
    $t->push(K beta  => 0x03b2);
    $t->push(K gamma => 0x03b3);
    $t->push(K delta => 0x03b4);

    $t->outAsUtf8NL;

    $t->append($t);
    $t->outAsUtf8NL;

    $t->append($t);
    $t->outAsUtf8NL;

    my $T = $t->substring(K(key => 4), K(key => 8));
    $T->outAsUtf8NL;

    my $r = $T->reverse;
    $r->outAsUtf8NL;

    ok Assemble eq => <<END, avx512=>1;
  αβγδ
  αβγδαβγδ
  αβγδαβγδαβγδαβγδ
  αβγδ
  δγβα
  END

    my $a = CreateArea;
    my $t = $a->CreateTree;
    my $b = Rb(0x41..0x51);
    $t->appendAscii(K(address=> $b), K(size => 1));
    $t->outAsUtf8NL;
    my $T = $a->CreateTree;
    $T->append($t);
    $T->append($t);
    $T->outAsUtf8NL;
    $T->appendAscii(K(address=> $b) + 1, K(size => 1));
    my $c = $T->clone;
    $c->outAsUtf8NL;
    my $d = $c->substring(1, 3);
    $d->outAsUtf8NL;
    ok Assemble eq => <<END, avx512=>1;
  A
  AA
  AAB
  AB
  END

    my $f = "zzzOperators.lib";                                                   # Methods to be called against each syntactic item

    my $library = Subroutine                                                      # This subroutine and all of the subroutines it contains will be saved in an area and that area will be written to a file from where it can be included via L<incBin> in subsequent assemblies.
     {my ($p, $s, $sub) = @_;

      Subroutine                                                                  # A contained routine that we wish to export to a file
       {my ($p, $s, $sub) = @_;
        PrintOutString "Ascii: ";

        my $parse  = $$s{parse};                                                  # Parse
        my $source = $parse->source;                                              # Source

        $parse->area->getZmmBlock($$p{offset}, 1);                                # Load current parse tree node

        my $w = dSize;
        my $length   = dFromZ(1, $w * Nasm::X86::Unisyn::Lex::length);            # Length of ascii
        my $position = dFromZ(1, $w * Nasm::X86::Unisyn::Lex::position);          # Position in source

       ($source+$position)->printOutMemoryNL($length);                            # Print the ascii string

       } name => "Ascii",
         structures => {parse => Nasm::X86::Unisyn::DescribeParse},
         parameters => [qw(offset)];

      Subroutine                                                                  # Another subroutine that will be exported because it is within the subroutine that is being exported as a library
       {my ($p, $s, $sub) = @_;
        PrintOutStringNL "Add";
       } name => "+",
         structures => {parse => Nasm::X86::Unisyn::DescribeParse},
         parameters => [qw(offset)];

      Subroutine
       {my ($p, $s, $sub) = @_;
        PrintOutStringNL "Times";
       } name => "✕",
         structures => {parse => Nasm::X86::Unisyn::DescribeParse},
         parameters => [qw(offset)];

      Subroutine
       {my ($p, $s, $sub) = @_;
        PrintOutStringNL "And";
       } name => "𝕒𝕟𝕕",
         structures => {parse => Nasm::X86::Unisyn::DescribeParse},
         parameters => [qw(offset)];


      Subroutine
       {my ($p, $s, $sub) = @_;
        PrintOutString "Variable: ";

        my $parse  = $$s{parse};                                                  # Parse
        my $source = $parse->source;                                              # Source

        $parse->area->getZmmBlock($$p{offset}, 1);                                # Load current parse tree node

        my $w = dSize;
        my $length   = dFromZ(1, $w * Nasm::X86::Unisyn::Lex::length);            # Length of ascii
        my $position = dFromZ(1, $w * Nasm::X86::Unisyn::Lex::position);          # Position in source

       ($source+$position)->printOutMemoryNL($length);                            # Print the ascii string

       } name => "Variable",
         structures => {parse => Nasm::X86::Unisyn::DescribeParse},
         parameters => [qw(offset)];

     } name => "operators",  parameters=>[qw(a b c)], export => $f;

    ok Assemble eq => <<END, avx512=>1;
  END

    my $l = ReadArea $f;                                                          # Area containing subroutine library

    my ($A, $N) = constantString  qq(1+𝗔✕𝗕+𝗖𝕒𝕟𝕕2✕𝗔+𝗕+𝗖);                          # Utf8 string to parse

    my $p = ParseUnisyn($A, $N);                                                  # 10_445 Parse utf8 string  5_340 after single character lexical items, 4_950 after jump table

   $p->dumpParseResult;

   $p->traverseApplyingLibraryOperators($l);                                      # Traverse a parse tree applying a library of operators where they intersect with lexical items in the parse tree

  # ✕ 2715
  # + ff0b

    ok Assemble eq => <<END, clocks=>20_921;
  parseChar  : .... .... ...1 D5D6
  parseFail  : .... .... .... ...0
  position   : .... .... .... ..38
  parseMatch : .... .... .... ...0
  parseReason: .... .... .... ...0
  𝕒𝕟𝕕
  ._+
  ._._✕
  ._._._+
  ._._._._1
  ._._._._𝗔
  ._._._𝗕
  ._._𝗖
  ._+
  ._._+
  ._._._✕
  ._._._._2
  ._._._._𝗔
  ._._._𝗕
  ._._𝗖
  Ascii: 1
  Variable: 𝗔
  Add
  Variable: 𝗕
  Times
  Variable: 𝗖
  Add
  Ascii: 2
  Variable: 𝗔
  Times
  Variable: 𝗕
  Add
  Variable: 𝗖
  Add
  And
  END
    unlink $f;

Nasm::X86::Tree::clone($string)

Clone a string.

     Parameter  Description
  1  $string    Tree descriptor

Example:

    my $a = CreateArea;
    my $t = $a->CreateTree;
    my $b = Rb(0x41..0x51);
    $t->appendAscii(K(address=> $b), K(size => 1));
    $t->outAsUtf8NL;
    my $T = $a->CreateTree;
    $T->append($t);
    $T->append($t);
    $T->outAsUtf8NL;
    $T->appendAscii(K(address=> $b) + 1, K(size => 1));
    my $c = $T->clone;
    $c->outAsUtf8NL;
    my $d = $c->substring(1, 3);
    $d->outAsUtf8NL;
    ok Assemble eq => <<END, avx512=>1;
  A
  AA
  AAB
  AB
  END

Nasm::X86::Tree::substring($string, $Start, $Finish)

Create the substring of the specified string between the specified start and end keys.

     Parameter  Description
  1  $string    Tree descriptor of string to extract from
  2  $Start     Start key
  3  $Finish    End key

Example:

    my $a = CreateArea;
    my $t = $a->CreateTree;

    $t->push(K alpha => 0x03b1);
    $t->push(K beta  => 0x03b2);
    $t->push(K gamma => 0x03b3);
    $t->push(K delta => 0x03b4);

    $t->outAsUtf8NL;

    $t->append($t);
    $t->outAsUtf8NL;

    $t->append($t);
    $t->outAsUtf8NL;

    my $T = $t->substring(K(key => 4), K(key => 8));
    $T->outAsUtf8NL;

    my $r = $T->reverse;
    $r->outAsUtf8NL;

    ok Assemble eq => <<END, avx512=>1;
  αβγδ
  αβγδαβγδ
  αβγδαβγδαβγδαβγδ
  αβγδ
  δγβα
  END

Nasm::X86::Tree::reverse($string)

Create a clone of the string in reverse order.

     Parameter  Description
  1  $string    Tree descriptor of string

Example:

    my $a = CreateArea;
    my $t = $a->CreateTree;

    $t->push(K alpha => 0x03b1);
    $t->push(K beta  => 0x03b2);
    $t->push(K gamma => 0x03b3);
    $t->push(K delta => 0x03b4);

    $t->outAsUtf8NL;

    $t->append($t);
    $t->outAsUtf8NL;

    $t->append($t);
    $t->outAsUtf8NL;

    my $T = $t->substring(K(key => 4), K(key => 8));
    $T->outAsUtf8NL;

    my $r = $T->reverse;
    $r->outAsUtf8NL;

    ok Assemble eq => <<END, avx512=>1;
  αβγδ
  αβγδαβγδ
  αβγδαβγδαβγδαβγδ
  αβγδ
  δγβα
  END

Trees as sets

Trees of trees as sets

Nasm::X86::Tree::union($tree)

Given a tree of trees consider each sub tree as a set and form the union of all these sets as a new tree.

     Parameter  Description
  1  $tree      Tree descriptor for a tree of trees

Example:

    my $a = CreateArea;
    my $r = $a->CreateTree;
    my $s = $a->CreateTree;
    my $t = $a->CreateTree;

    $r->put(K(key => 1), K(data => 1));
    $r->put(K(key => 2), K(data => 2));

    $s->put(K(key => 1), K(data => 1));
    $s->put(K(key => 3), K(data => 3));

    $t->push($r);
    $t->push($s);

    my $u = $t->union;
    $t->dump('input 1 2  1 3');
    $u->dump('union 1 2    3');

    my $i = $t->intersection;
    $i->dump('intersection 1');

    ok Assemble eq => <<END, avx512=>1;
  input 1 2  1 3
  At:  280                    length:    2,  data:  2C0,  nodes:  300,  first:   C0, root, leaf,  trees:            11
    Index:    0    1
    Keys :    0    1
    Data :  10*  1C*
       At:  100               length:    2,  data:  140,  nodes:  180,  first:   40, root, leaf
         Index:    0    1
         Keys :    1    2
         Data :    1    2
       end
       At:  1C0               length:    2,  data:  200,  nodes:  240,  first:   80, root, leaf
         Index:    0    1
         Keys :    1    3
         Data :    1    3
       end
  end
  union 1 2    3
  At:  380                    length:    3,  data:  3C0,  nodes:  400,  first:  340, root, leaf
    Index:    0    1    2
    Keys :    1    2    3
    Data :    1    2    3
  end
  intersection 1
  At:  480                    length:    1,  data:  4C0,  nodes:  500,  first:  440, root, leaf
    Index:    0
    Keys :    1
    Data :    1
  end
  END

Nasm::X86::Tree::intersection($tree)

Given a tree of trees consider each sub tree as a set and form the intersection of all these sets as a new tree.

     Parameter  Description
  1  $tree      Tree descriptor for a tree of trees

Example:

    my $a = CreateArea;
    my $r = $a->CreateTree;
    my $s = $a->CreateTree;
    my $t = $a->CreateTree;

    $r->put(K(key => 1), K(data => 1));
    $r->put(K(key => 2), K(data => 2));

    $s->put(K(key => 1), K(data => 1));
    $s->put(K(key => 3), K(data => 3));

    $t->push($r);
    $t->push($s);

    my $u = $t->union;
    $t->dump('input 1 2  1 3');
    $u->dump('union 1 2    3');

    my $i = $t->intersection;
    $i->dump('intersection 1');

    ok Assemble eq => <<END, avx512=>1;
  input 1 2  1 3
  At:  280                    length:    2,  data:  2C0,  nodes:  300,  first:   C0, root, leaf,  trees:            11
    Index:    0    1
    Keys :    0    1
    Data :  10*  1C*
       At:  100               length:    2,  data:  140,  nodes:  180,  first:   40, root, leaf
         Index:    0    1
         Keys :    1    2
         Data :    1    2
       end
       At:  1C0               length:    2,  data:  200,  nodes:  240,  first:   80, root, leaf
         Index:    0    1
         Keys :    1    3
         Data :    1    3
       end
  end
  union 1 2    3
  At:  380                    length:    3,  data:  3C0,  nodes:  400,  first:  340, root, leaf
    Index:    0    1    2
    Keys :    1    2    3
    Data :    1    2    3
  end
  intersection 1
  At:  480                    length:    1,  data:  4C0,  nodes:  500,  first:  440, root, leaf
    Index:    0
    Keys :    1
    Data :    1
  end
  END

Key String Trees

A key string tree has strings for keys.

Nasm::X86::Tree::getKeyString($tree, $address, $size)

Find a string in a string tree and return the associated data and find status in the data and found fields of the tree.

     Parameter  Description
  1  $tree      Tree descriptor
  2  $address   Address of key
  3  $size      Length of key

Example:

    my $t = CreateArea->CreateTree(stringTree=>1);

    K(loop => 3)->for(sub
     {my $a = $t->uniqueKeyString(constantString("aaaa")); $a->outNL;
      my $b = $t->uniqueKeyString(constantString("bbbb")); $b->outNL;
     });

    for my $k(qw(aaaa bbbb ccccc))
     {PrintOutStringNL $k;
      $t->getKeyString(constantString $k); $t->found->outNL; $t->data->outNL;
     }

    ok Assemble eq => <<END, clocks=>4374;
  count: .... .... .... ...0
  count: .... .... .... ...1
  count: .... .... .... ...0
  count: .... .... .... ...1
  count: .... .... .... ...0
  count: .... .... .... ...1
  aaaa
  found  : .... .... .... ...1
  data   : .... .... .... ...0
  bbbb
  found  : .... .... .... ...2
  data   : .... .... .... ...1
  ccccc
  found  : .... .... .... ...0
  data   : .... .... .... ...0
  END

    my $a = CreateArea;
    my $t = $a->CreateTree(stringTree=>1);
    $t->putKeyString(constantString("dddd444"),  K(data => 8));
    $t->putKeyString(constantString("dddd4444"), K(data => 9));
    $t->putKeyString(constantString("eeee5555"), K(data =>10));
    $t->putKeyString(constantString("bbbb2222"), K(data => 2));
    $t->putKeyString(constantString("cccc3333"), K(data => 7));
    $t->putKeyString(constantString("aaaa1111"), K(data => 1));
    $t->putKeyString(constantString("cccc1111cccc2222cccc3333cccc4444cccc1111cccc2222cccc3333cccc44443"),  K data => 6);
    $t->putKeyString(constantString("cccc1111cccc2222cccc3333cccc4444cccc1111cccc2222cccc3333cccc44442"),  K data => 5);
    $t->putKeyString(constantString("cccc1111cccc2222cccc3333cccc4444cccc1111cccc2222cccc3333cccc44441"),  K data => 4);
    $t->putKeyString(constantString("cccc1111cccc2222cccc3333cccc4444cccc1111cccc2222cccc3333cccc44440"),  K data => 3);
    $a->dump("AA", K(depth => 20));
    $t->dump("TT");

    $t->getKeyString(constantString("aaaa1111"));                                                          $t->data->outNL;
    $t->getKeyString(constantString("bbbb2222"));                                                          $t->data->outNL;
    $t->getKeyString(constantString("cccc1111cccc2222cccc3333cccc4444cccc1111cccc2222cccc3333cccc44440")); $t->data->outNL;
    $t->getKeyString(constantString("cccc1111cccc2222cccc3333cccc4444cccc1111cccc2222cccc3333cccc44441")); $t->data->outNL;
    $t->getKeyString(constantString("cccc1111cccc2222cccc3333cccc4444cccc1111cccc2222cccc3333cccc44442")); $t->data->outNL;
    $t->getKeyString(constantString("cccc1111cccc2222cccc3333cccc4444cccc1111cccc2222cccc3333cccc44443")); $t->data->outNL;
    $t->getKeyString(constantString("cccc3333"));                                                          $t->data->outNL;
    $t->getKeyString(constantString("dddd444"));                                                           $t->data->outNL;
    $t->getKeyString(constantString("dddd4444"));                                                          $t->data->outNL;
    $t->getKeyString(constantString("eeee5555"));                                                          $t->data->outNL;

    ok Assemble eq => <<END, avx512=>1;
  AA
  Area     Size:     4096    Used:     1280
  .... .... .... ...0 | __10 ____ ____ ____  __.5 ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | C0__ ____ .1__ ____  .7__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | 6464 6464 3434 34__  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | 80.2 ____ __.2 ____  C0.2 ____ 40.2 ____  80__ ____ 80.1 ____  C0.1 ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  .7__ .4__ __.1 ____
  .... .... .... .1.. | .1__ ____ .2__ ____  __.3 ____ .7__ ____  .8__ ____ .9__ ____  .A__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ 40.1 ____
  .... .... .... .140 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ 40__ ____
  .... .... .... .180 | 6464 6464 3434 3434  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... .1C0 | 6565 6565 3535 3535  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... .2.. | 6262 6262 3232 3232  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... .240 | 6363 6363 3333 3333  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... .280 | 6161 6161 3131 3131  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... .2C0 | 6363 6363 3131 3131  6363 6363 3232 3232  6363 6363 3333 3333  6363 6363 3434 3434  6363 6363 3131 3131  6363 6363 3232 3232  6363 6363 3333 3333  6363 6363 3434 3434
  .... .... .... .3.. | 80.3 ____ .1__ ____  .4__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... .340 | 33__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... .380 | C0.4 ____ 80.4 ____  40.4 ____ 40.3 ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  .4__ ____ C0.3 ____
  .... .... .... .3C0 | .3__ ____ .4__ ____  .5__ ____ .6__ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ __.4 ____
  .... .... .... .4.. | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ __.3 ____
  .... .... .... .440 | 32__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... .480 | 31__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... .4C0 | 30__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  TT
  At:   C0                    length:    7,  data:  100,  nodes:  140,  first:   40, root, leaf,  trees:           100
    Index:    0    1    2    3    4    5    6
    Keys :  280  200  2C0  240   80  180  1C0
    Data :    1    2  38*    7    8    9   10
       At:  380               length:    4,  data:  3C0,  nodes:  400,  first:  300, root, leaf
         Index:    0    1    2    3
         Keys :  4C0  480  440  340
         Data :    3    4    5    6
       end
  end
  data   : .... .... .... ...1
  data   : .... .... .... ...2
  data   : .... .... .... ...3
  data   : .... .... .... ...4
  data   : .... .... .... ...5
  data   : .... .... .... ...6
  data   : .... .... .... ...7
  data   : .... .... .... ...8
  data   : .... .... .... ...9
  data   : .... .... .... ...A
  END

Nasm::X86::Tree::putKeyString($tree, $address, $size, $data)

Associate a string of any length with a double word.

     Parameter  Description
  1  $tree      Tree descriptor
  2  $address   Address of key
  3  $size      Length of key
  4  $data      Data associated with key

Example:

    my $a = CreateArea;
    my $t = $a->CreateTree(stringTree=>1);
    $t->putKeyString(constantString("dddd444"),  K(data => 8));
    $t->putKeyString(constantString("dddd4444"), K(data => 9));
    $t->putKeyString(constantString("eeee5555"), K(data =>10));
    $t->putKeyString(constantString("bbbb2222"), K(data => 2));
    $t->putKeyString(constantString("cccc3333"), K(data => 7));
    $t->putKeyString(constantString("aaaa1111"), K(data => 1));
    $t->putKeyString(constantString("cccc1111cccc2222cccc3333cccc4444cccc1111cccc2222cccc3333cccc44443"),  K data => 6);
    $t->putKeyString(constantString("cccc1111cccc2222cccc3333cccc4444cccc1111cccc2222cccc3333cccc44442"),  K data => 5);
    $t->putKeyString(constantString("cccc1111cccc2222cccc3333cccc4444cccc1111cccc2222cccc3333cccc44441"),  K data => 4);
    $t->putKeyString(constantString("cccc1111cccc2222cccc3333cccc4444cccc1111cccc2222cccc3333cccc44440"),  K data => 3);
    $a->dump("AA", K(depth => 20));
    $t->dump("TT");

    $t->getKeyString(constantString("aaaa1111"));                                                          $t->data->outNL;
    $t->getKeyString(constantString("bbbb2222"));                                                          $t->data->outNL;
    $t->getKeyString(constantString("cccc1111cccc2222cccc3333cccc4444cccc1111cccc2222cccc3333cccc44440")); $t->data->outNL;
    $t->getKeyString(constantString("cccc1111cccc2222cccc3333cccc4444cccc1111cccc2222cccc3333cccc44441")); $t->data->outNL;
    $t->getKeyString(constantString("cccc1111cccc2222cccc3333cccc4444cccc1111cccc2222cccc3333cccc44442")); $t->data->outNL;
    $t->getKeyString(constantString("cccc1111cccc2222cccc3333cccc4444cccc1111cccc2222cccc3333cccc44443")); $t->data->outNL;
    $t->getKeyString(constantString("cccc3333"));                                                          $t->data->outNL;
    $t->getKeyString(constantString("dddd444"));                                                           $t->data->outNL;
    $t->getKeyString(constantString("dddd4444"));                                                          $t->data->outNL;
    $t->getKeyString(constantString("eeee5555"));                                                          $t->data->outNL;

    ok Assemble eq => <<END, avx512=>1;
  AA
  Area     Size:     4096    Used:     1280
  .... .... .... ...0 | __10 ____ ____ ____  __.5 ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | C0__ ____ .1__ ____  .7__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | 6464 6464 3434 34__  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | 80.2 ____ __.2 ____  C0.2 ____ 40.2 ____  80__ ____ 80.1 ____  C0.1 ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  .7__ .4__ __.1 ____
  .... .... .... .1.. | .1__ ____ .2__ ____  __.3 ____ .7__ ____  .8__ ____ .9__ ____  .A__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ 40.1 ____
  .... .... .... .140 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ 40__ ____
  .... .... .... .180 | 6464 6464 3434 3434  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... .1C0 | 6565 6565 3535 3535  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... .2.. | 6262 6262 3232 3232  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... .240 | 6363 6363 3333 3333  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... .280 | 6161 6161 3131 3131  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... .2C0 | 6363 6363 3131 3131  6363 6363 3232 3232  6363 6363 3333 3333  6363 6363 3434 3434  6363 6363 3131 3131  6363 6363 3232 3232  6363 6363 3333 3333  6363 6363 3434 3434
  .... .... .... .3.. | 80.3 ____ .1__ ____  .4__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... .340 | 33__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... .380 | C0.4 ____ 80.4 ____  40.4 ____ 40.3 ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  .4__ ____ C0.3 ____
  .... .... .... .3C0 | .3__ ____ .4__ ____  .5__ ____ .6__ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ __.4 ____
  .... .... .... .4.. | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ __.3 ____
  .... .... .... .440 | 32__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... .480 | 31__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... .4C0 | 30__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  TT
  At:   C0                    length:    7,  data:  100,  nodes:  140,  first:   40, root, leaf,  trees:           100
    Index:    0    1    2    3    4    5    6
    Keys :  280  200  2C0  240   80  180  1C0
    Data :    1    2  38*    7    8    9   10
       At:  380               length:    4,  data:  3C0,  nodes:  400,  first:  300, root, leaf
         Index:    0    1    2    3
         Keys :  4C0  480  440  340
         Data :    3    4    5    6
       end
  end
  data   : .... .... .... ...1
  data   : .... .... .... ...2
  data   : .... .... .... ...3
  data   : .... .... .... ...4
  data   : .... .... .... ...5
  data   : .... .... .... ...6
  data   : .... .... .... ...7
  data   : .... .... .... ...8
  data   : .... .... .... ...9
  data   : .... .... .... ...A
  END

Nasm::X86::Tree::uniqueKeyString($tree, $address, $size)

Add a key string to a string tree if the key is not already present and return a unique number identifying the string (although currently there is no way to fast way to recover the string from the number). If the key string is already present in the string tree return the number associated with the original key string rather than creating a new entry.

     Parameter  Description
  1  $tree      Tree descriptor
  2  $address   Address of key
  3  $size      Length of key

Example:

    my $t = CreateArea->CreateTree(stringTree=>1);

    K(loop => 3)->for(sub
     {my $a = $t->uniqueKeyString(constantString("aaaa")); $a->outNL;
      my $b = $t->uniqueKeyString(constantString("bbbb")); $b->outNL;
     });

    for my $k(qw(aaaa bbbb ccccc))
     {PrintOutStringNL $k;
      $t->getKeyString(constantString $k); $t->found->outNL; $t->data->outNL;
     }

    ok Assemble eq => <<END, clocks=>4374;
  count: .... .... .... ...0
  count: .... .... .... ...1
  count: .... .... .... ...0
  count: .... .... .... ...1
  count: .... .... .... ...0
  count: .... .... .... ...1
  aaaa
  found  : .... .... .... ...1
  data   : .... .... .... ...0
  bbbb
  found  : .... .... .... ...2
  data   : .... .... .... ...1
  ccccc
  found  : .... .... .... ...0
  data   : .... .... .... ...0
  END

Print

Print a tree

Nasm::X86::Tree::printInOrder($tree, $title)

Print a tree in order.

     Parameter  Description
  1  $tree      Tree
  2  $title     Title

Example:

    my $a = CreateArea;
    my $t = $a->CreateTree;
    my $N = K count => 128;

    $N->for(sub
     {my ($index, $start, $next, $end) = @_;
      my $l0 = ($N-$index) / 2;
      my $l1 = ($N+$index) / 2;
      my $h0 =  $N-$index;
      my $h1 =  $N+$index;
      $t->put($l0, $l0 * 2);
      $t->put($h1, $h1 * 2);
      $t->put($l1, $l1 * 2);
      $t->put($h0, $h0 * 2);
     });

    $t->printInOrder("AAAA");

    ok Assemble eq => <<END, label=>'t3';
  AAAA 256:    0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F  10  11  12  13  14  15  16  17  18  19  1A  1B  1C  1D  1E  1F  20  21  22  23  24  25  26  27  28  29  2A  2B  2C  2D  2E  2F  30  31  32  33  34  35  36  37  38  39  3A  3B  3C  3D  3E  3F  40  41  42  43  44  45  46  47  48  49  4A  4B  4C  4D  4E  4F  50  51  52  53  54  55  56  57  58  59  5A  5B  5C  5D  5E  5F  60  61  62  63  64  65  66  67  68  69  6A  6B  6C  6D  6E  6F  70  71  72  73  74  75  76  77  78  79  7A  7B  7C  7D  7E  7F  80  81  82  83  84  85  86  87  88  89  8A  8B  8C  8D  8E  8F  90  91  92  93  94  95  96  97  98  99  9A  9B  9C  9D  9E  9F  A0  A1  A2  A3  A4  A5  A6  A7  A8  A9  AA  AB  AC  AD  AE  AF  B0  B1  B2  B3  B4  B5  B6  B7  B8  B9  BA  BB  BC  BD  BE  BF  C0  C1  C2  C3  C4  C5  C6  C7  C8  C9  CA  CB  CC  CD  CE  CF  D0  D1  D2  D3  D4  D5  D6  D7  D8  D9  DA  DB  DC  DD  DE  DF  E0  E1  E2  E3  E4  E5  E6  E7  E8  E9  EA  EB  EC  ED  EE  EF  F0  F1  F2  F3  F4  F5  F6  F7  F8  F9  FA  FB  FC  FD  FE  FF
  END

    my $a = CreateArea;
    my $t = $a->CreateTree;
    my $N = K count => 128;

    $N->for(sub
     {my ($index, $start, $next, $end) = @_;
      my $l0 = ($N-$index) / 2;
      my $l1 = ($N+$index) / 2;
      my $h0 =  $N-$index;
      my $h1 =  $N+$index;
      $t->put($l0, $l0 * 2);
      $t->put($h1, $h1 * 2);
      $t->put($l1, $l1 * 2);
      $t->put($h0, $h0 * 2);
     });
    $t->printInOrder("AAAA");

    ok Assemble eq => <<END, avx512=>1;
  AAAA 256:    0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F  10  11  12  13  14  15  16  17  18  19  1A  1B  1C  1D  1E  1F  20  21  22  23  24  25  26  27  28  29  2A  2B  2C  2D  2E  2F  30  31  32  33  34  35  36  37  38  39  3A  3B  3C  3D  3E  3F  40  41  42  43  44  45  46  47  48  49  4A  4B  4C  4D  4E  4F  50  51  52  53  54  55  56  57  58  59  5A  5B  5C  5D  5E  5F  60  61  62  63  64  65  66  67  68  69  6A  6B  6C  6D  6E  6F  70  71  72  73  74  75  76  77  78  79  7A  7B  7C  7D  7E  7F  80  81  82  83  84  85  86  87  88  89  8A  8B  8C  8D  8E  8F  90  91  92  93  94  95  96  97  98  99  9A  9B  9C  9D  9E  9F  A0  A1  A2  A3  A4  A5  A6  A7  A8  A9  AA  AB  AC  AD  AE  AF  B0  B1  B2  B3  B4  B5  B6  B7  B8  B9  BA  BB  BC  BD  BE  BF  C0  C1  C2  C3  C4  C5  C6  C7  C8  C9  CA  CB  CC  CD  CE  CF  D0  D1  D2  D3  D4  D5  D6  D7  D8  D9  DA  DB  DC  DD  DE  DF  E0  E1  E2  E3  E4  E5  E6  E7  E8  E9  EA  EB  EC  ED  EE  EF  F0  F1  F2  F3  F4  F5  F6  F7  F8  F9  FA  FB  FC  FD  FE  FF
  END

Nasm::X86::Tree::outAsUtf8($string)

Print the data values of the specified string on stdout assuming each data value is a utf32 character and that the output device supports utf8.

     Parameter  Description
  1  $string    Tree descriptor of string

Example:

    my $a = CreateArea;
    my $t = $a->CreateTree;

    $t->push(K alpha => 0x03b1);
    $t->push(K beta  => 0x03b2);
    $t->push(K gamma => 0x03b3);
    $t->push(K delta => 0x03b4);

    $t->outAsUtf8NL;

    $t->append($t);
    $t->outAsUtf8NL;

    $t->append($t);
    $t->outAsUtf8NL;

    my $T = $t->substring(K(key => 4), K(key => 8));
    $T->outAsUtf8NL;

    my $r = $T->reverse;
    $r->outAsUtf8NL;

    ok Assemble eq => <<END, avx512=>1;
  αβγδ
  αβγδαβγδ
  αβγδαβγδαβγδαβγδ
  αβγδ
  δγβα
  END

    my $f = "zzzOperators.lib";                                                   # Methods to be called against each syntactic item

    my $library = Subroutine                                                      # This subroutine and all of the subroutines it contains will be saved in an area and that area will be written to a file from where it can be included via L<incBin> in subsequent assemblies.
     {my ($p, $s, $sub) = @_;

      Subroutine                                                                  # A contained routine that we wish to export to a file
       {my ($p, $s, $sub) = @_;
        PrintOutString "Ascii: ";

        my $parse  = $$s{parse};                                                  # Parse
        my $source = $parse->source;                                              # Source

        $parse->area->getZmmBlock($$p{offset}, 1);                                # Load current parse tree node

        my $w = dSize;
        my $length   = dFromZ(1, $w * Nasm::X86::Unisyn::Lex::length);            # Length of ascii
        my $position = dFromZ(1, $w * Nasm::X86::Unisyn::Lex::position);          # Position in source

       ($source+$position)->printOutMemoryNL($length);                            # Print the ascii string

       } name => "Ascii",
         structures => {parse => Nasm::X86::Unisyn::DescribeParse},
         parameters => [qw(offset)];

      Subroutine                                                                  # Another subroutine that will be exported because it is within the subroutine that is being exported as a library
       {my ($p, $s, $sub) = @_;
        PrintOutStringNL "Add";
       } name => "+",
         structures => {parse => Nasm::X86::Unisyn::DescribeParse},
         parameters => [qw(offset)];

      Subroutine
       {my ($p, $s, $sub) = @_;
        PrintOutStringNL "Times";
       } name => "✕",
         structures => {parse => Nasm::X86::Unisyn::DescribeParse},
         parameters => [qw(offset)];

      Subroutine
       {my ($p, $s, $sub) = @_;
        PrintOutStringNL "And";
       } name => "𝕒𝕟𝕕",
         structures => {parse => Nasm::X86::Unisyn::DescribeParse},
         parameters => [qw(offset)];


      Subroutine
       {my ($p, $s, $sub) = @_;
        PrintOutString "Variable: ";

        my $parse  = $$s{parse};                                                  # Parse
        my $source = $parse->source;                                              # Source

        $parse->area->getZmmBlock($$p{offset}, 1);                                # Load current parse tree node

        my $w = dSize;
        my $length   = dFromZ(1, $w * Nasm::X86::Unisyn::Lex::length);            # Length of ascii
        my $position = dFromZ(1, $w * Nasm::X86::Unisyn::Lex::position);          # Position in source

       ($source+$position)->printOutMemoryNL($length);                            # Print the ascii string

       } name => "Variable",
         structures => {parse => Nasm::X86::Unisyn::DescribeParse},
         parameters => [qw(offset)];

     } name => "operators",  parameters=>[qw(a b c)], export => $f;

    ok Assemble eq => <<END, avx512=>1;
  END

    my $l = ReadArea $f;                                                          # Area containing subroutine library

    my ($A, $N) = constantString  qq(1+𝗔✕𝗕+𝗖𝕒𝕟𝕕2✕𝗔+𝗕+𝗖);                          # Utf8 string to parse

    my $p = ParseUnisyn($A, $N);                                                  # 10_445 Parse utf8 string  5_340 after single character lexical items, 4_950 after jump table

   $p->dumpParseResult;

   $p->traverseApplyingLibraryOperators($l);                                      # Traverse a parse tree applying a library of operators where they intersect with lexical items in the parse tree

  # ✕ 2715
  # + ff0b

    ok Assemble eq => <<END, clocks=>20_921;
  parseChar  : .... .... ...1 D5D6
  parseFail  : .... .... .... ...0
  position   : .... .... .... ..38
  parseMatch : .... .... .... ...0
  parseReason: .... .... .... ...0
  𝕒𝕟𝕕
  ._+
  ._._✕
  ._._._+
  ._._._._1
  ._._._._𝗔
  ._._._𝗕
  ._._𝗖
  ._+
  ._._+
  ._._._✕
  ._._._._2
  ._._._._𝗔
  ._._._𝗕
  ._._𝗖
  Ascii: 1
  Variable: 𝗔
  Add
  Variable: 𝗕
  Times
  Variable: 𝗖
  Add
  Ascii: 2
  Variable: 𝗔
  Times
  Variable: 𝗕
  Add
  Variable: 𝗖
  Add
  And
  END
    unlink $f;

Nasm::X86::Tree::outAsUtf8NL($string)

Print the data values of the specified string on stdout assuming each data value is a utf32 character and that the output device supports utf8. Follow the print with a new line character.

     Parameter  Description
  1  $string    Tree descriptor of string

Example:

    my $a = CreateArea;
    my $t = $a->CreateTree;
    my $b = Rb(0x41..0x51);
    $t->appendAscii(K(address=> $b), K(size => 1));
    $t->outAsUtf8NL;
    my $T = $a->CreateTree;
    $T->append($t);
    $T->append($t);
    $T->outAsUtf8NL;
    $T->appendAscii(K(address=> $b) + 1, K(size => 1));
    my $c = $T->clone;
    $c->outAsUtf8NL;
    my $d = $c->substring(1, 3);
    $d->outAsUtf8NL;
    ok Assemble eq => <<END, avx512=>1;
  A
  AA
  AAB
  AB
  END

Unisyn

Parse Unisyn language statements.

Lex

Lexical Analysis

Nasm::X86::Unisyn::Lex::composeUnisyn($words)

Compose phrases of Unisyn and return them as a string

     Parameter  Description
  1  $words     String of words

Example:

  if (1)

   {my $t = Nasm::X86::Unisyn::Lex::composeUnisyn "va w m+ w vb";  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    is_deeply $t, "𝗮 + 𝗯";
    my $p = &ParseUnisyn(constantString $t);
    $p->dumpPostOrder;
    ok Assemble eq => <<END;
  ._𝗮 
  ._𝗯
  + 
  END
   }

Nasm::X86::Unisyn::Lex::PermissibleTransitionsArray()

Create and load the table of lexical transitions.

Example:

    my $a = Nasm::X86::Unisyn::Lex::Number::a;                                    # Assign-2 - right to left
    my $b = Nasm::X86::Unisyn::Lex::Number::b;                                    # Open


    my ($N, $A) = Nasm::X86::Unisyn::Lex::PermissibleTransitionsArray;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    Mov rax, $A;
    Add rax, ($a << Nasm::X86::Unisyn::Lex::PermissibleTransitionsArrayBits) + $a;
    Mov al, "[rax]";
    And rax, 0xff;
    PrintOutRegisterInHex rax;

    Mov rax, $A;
    Add rax, ($b << Nasm::X86::Unisyn::Lex::PermissibleTransitionsArrayBits) + $b;
    Mov al, "[rax]";
    And rax, 0xff;
    PrintOutRegisterInHex rax;
    ok Assemble eq => <<END, avx512=>1;
     rax: .... .... .... ..FF
     rax: .... .... .... ...1
  END

  if (1)                                                                          # Place parser tables into an area
   {my $a = CreateArea;
    my ($alphabetN,    $alphabetA)    = Nasm::X86::Unisyn::Lex::AlphabetsArray;

    my ($transitionsN, $transitionsA) = Nasm::X86::Unisyn::Lex::PermissibleTransitionsArray;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲


    $a->appendVar(V address => "[$transitionsN]");
    $a->appendVar(V address => "[$alphabetN]");                                   # Save sizes at start if area where they can be easily found

    $a->appendMemory(V(address => $transitionsA), V size => "[$transitionsN]");   # Save transitions
    $a->appendMemory(V(address => $alphabetA),    V size => "[$alphabetN]");      # Save alphabets classification

    $a->write("z123.txt");                                                        # Save the area to the named file
    ok Assemble eq => <<END;
  END
   }

Nasm::X86::Unisyn::Lex::AlphabetsArray()

Create an array of utf32 to alphabet number.

Example:

    my ($N, $A) = Nasm::X86::Unisyn::Lex::AlphabetsArray;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    Mov rax, "[$N]";
    PrintOutRegisterInHex rax;
    Mov rax, $A;
    Add rax, ord('𝝰');
    Mov al, "[rax]";
    And rax, 0xff;
    PrintOutRegisterInHex rax;

    Mov rax, $A;
    Add rax, ord('𝔸');
    Mov al, "[rax]";
    And rax, 0xff;
    PrintOutRegisterInHex rax;

    my sub expect($)
     {my ($n) = @_;                                                               # Parameters
      $n >= 0x10 ? sprintf("%2X", $n) : sprintf(".%1X", $n)
     }

    my $a = expect Nasm::X86::Unisyn::Lex::Number::v;
    my $b = expect Nasm::X86::Unisyn::Lex::Number::d;
    ok Assemble eq => <<END, avx512=>1;
     rax: .... .... ...1 EEF2
     rax: .... .... .... ..$a
     rax: .... .... .... ..$b
  END

  if (1)                                                                          # Place parser tables into an area
   {my $a = CreateArea;

    my ($alphabetN,    $alphabetA)    = Nasm::X86::Unisyn::Lex::AlphabetsArray;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    my ($transitionsN, $transitionsA) = Nasm::X86::Unisyn::Lex::PermissibleTransitionsArray;

    $a->appendVar(V address => "[$transitionsN]");
    $a->appendVar(V address => "[$alphabetN]");                                   # Save sizes at start if area where they can be easily found

    $a->appendMemory(V(address => $transitionsA), V size => "[$transitionsN]");   # Save transitions
    $a->appendMemory(V(address => $alphabetA),    V size => "[$alphabetN]");      # Save alphabets classification

    $a->write("z123.txt");                                                        # Save the area to the named file
    ok Assemble eq => <<END;
  END
   }

Nasm::X86::Unisyn::Lex::letterToNumber()

Map each letter in the union of the alphabets to a sequential number

Example:

  if (1)

   {my ($n, $l) = Nasm::X86::Unisyn::Lex::letterToNumber;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    my ($N, $L) = Nasm::X86::Unisyn::Lex::numberToLetter;

    If $N > $n,
    Then
     {PrintErrTraceBack "Numbers to letters cannot be greater than letters to numbers";
     };

    $l->setReg(rax);
    $L->setReg(rbx);

    $n->for(sub
     {my ($i, $start, $next, $end) = @_;
      $i->setReg(rsi);                                                            # The character we want to test as utf32

      Mov edx, "[rax+4*rsi]";                                                     # The unisyn number of a letter
      Cmp edx, -1;
      Je $next;                                                                   # Not a unisyn chaarcter

      Mov r15d, "[rbx+4*rdx]";                                                    # r15 contains the utf32 representation of a unisyn letter

      Cmp r15, rsi;                                                               # Check that we retirved th chaarcter westarted with
      IfNe
      Then
       {$i->outNL("Mismatch: ");
        PrintOutRegisterInHex rsi, r15;
       }
     });

    ok Assemble eq => <<END;
  END
   }

Nasm::X86::Unisyn::Lex::numberToLetter()

Recover a letter from its unique number

Example:

  if (1)
   {my ($n, $l) = Nasm::X86::Unisyn::Lex::letterToNumber;

    my ($N, $L) = Nasm::X86::Unisyn::Lex::numberToLetter;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲


    If $N > $n,
    Then
     {PrintErrTraceBack "Numbers to letters cannot be greater than letters to numbers";
     };

    $l->setReg(rax);
    $L->setReg(rbx);

    $n->for(sub
     {my ($i, $start, $next, $end) = @_;
      $i->setReg(rsi);                                                            # The character we want to test as utf32

      Mov edx, "[rax+4*rsi]";                                                     # The unisyn number of a letter
      Cmp edx, -1;
      Je $next;                                                                   # Not a unisyn chaarcter

      Mov r15d, "[rbx+4*rdx]";                                                    # r15 contains the utf32 representation of a unisyn letter

      Cmp r15, rsi;                                                               # Check that we retirved th chaarcter westarted with
      IfNe
      Then
       {$i->outNL("Mismatch: ");
        PrintOutRegisterInHex rsi, r15;
       }
     });

    ok Assemble eq => <<END;
  END
   }

Parse

Parse Unisyn language statements.

ParseUnisyn($a8, $s8)

Parse a string of utf8 characters.

     Parameter  Description
  1  $a8        Address of utf8 source string
  2  $s8        Size of utf8 source string in bytes

Example:

    my $f = "zzzOperators.lib";                                                   # Methods to be called against each syntactic item

    my $library = Subroutine                                                      # This subroutine and all of the subroutines it contains will be saved in an area and that area will be written to a file from where it can be included via L<incBin> in subsequent assemblies.
     {my ($p, $s, $sub) = @_;

      Subroutine                                                                  # A contained routine that we wish to export to a file
       {my ($p, $s, $sub) = @_;
        PrintOutString "Ascii: ";

        my $parse  = $$s{parse};                                                  # Parse
        my $source = $parse->source;                                              # Source

        $parse->area->getZmmBlock($$p{offset}, 1);                                # Load current parse tree node

        my $w = dSize;
        my $length   = dFromZ(1, $w * Nasm::X86::Unisyn::Lex::length);            # Length of ascii
        my $position = dFromZ(1, $w * Nasm::X86::Unisyn::Lex::position);          # Position in source

       ($source+$position)->printOutMemoryNL($length);                            # Print the ascii string

       } name => "Ascii",
         structures => {parse => Nasm::X86::Unisyn::DescribeParse},
         parameters => [qw(offset)];

      Subroutine                                                                  # Another subroutine that will be exported because it is within the subroutine that is being exported as a library
       {my ($p, $s, $sub) = @_;
        PrintOutStringNL "Add";
       } name => "+",
         structures => {parse => Nasm::X86::Unisyn::DescribeParse},
         parameters => [qw(offset)];

      Subroutine
       {my ($p, $s, $sub) = @_;
        PrintOutStringNL "Times";
       } name => "✕",
         structures => {parse => Nasm::X86::Unisyn::DescribeParse},
         parameters => [qw(offset)];

      Subroutine
       {my ($p, $s, $sub) = @_;
        PrintOutStringNL "And";
       } name => "𝕒𝕟𝕕",
         structures => {parse => Nasm::X86::Unisyn::DescribeParse},
         parameters => [qw(offset)];


      Subroutine
       {my ($p, $s, $sub) = @_;
        PrintOutString "Variable: ";

        my $parse  = $$s{parse};                                                  # Parse
        my $source = $parse->source;                                              # Source

        $parse->area->getZmmBlock($$p{offset}, 1);                                # Load current parse tree node

        my $w = dSize;
        my $length   = dFromZ(1, $w * Nasm::X86::Unisyn::Lex::length);            # Length of ascii
        my $position = dFromZ(1, $w * Nasm::X86::Unisyn::Lex::position);          # Position in source

       ($source+$position)->printOutMemoryNL($length);                            # Print the ascii string

       } name => "Variable",
         structures => {parse => Nasm::X86::Unisyn::DescribeParse},
         parameters => [qw(offset)];

     } name => "operators",  parameters=>[qw(a b c)], export => $f;

    ok Assemble eq => <<END, avx512=>1;
  END

    my $l = ReadArea $f;                                                          # Area containing subroutine library

    my ($A, $N) = constantString  qq(1+𝗔✕𝗕+𝗖𝕒𝕟𝕕2✕𝗔+𝗕+𝗖);                          # Utf8 string to parse


    my $p = ParseUnisyn($A, $N);                                                  # 10_445 Parse utf8 string  5_340 after single character lexical items, 4_950 after jump table  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲


   $p->dumpParseResult;

   $p->traverseApplyingLibraryOperators($l);                                      # Traverse a parse tree applying a library of operators where they intersect with lexical items in the parse tree

  # ✕ 2715
  # + ff0b

    ok Assemble eq => <<END, clocks=>20_921;
  parseChar  : .... .... ...1 D5D6
  parseFail  : .... .... .... ...0
  position   : .... .... .... ..38
  parseMatch : .... .... .... ...0
  parseReason: .... .... .... ...0
  𝕒𝕟𝕕
  ._+
  ._._✕
  ._._._+
  ._._._._1
  ._._._._𝗔
  ._._._𝗕
  ._._𝗖
  ._+
  ._._+
  ._._._✕
  ._._._._2
  ._._._._𝗔
  ._._._𝗕
  ._._𝗖
  Ascii: 1
  Variable: 𝗔
  Add
  Variable: 𝗕
  Times
  Variable: 𝗖
  Add
  Ascii: 2
  Variable: 𝗔
  Times
  Variable: 𝗕
  Add
  Variable: 𝗖
  Add
  And
  END
    unlink $f;

Nasm::X86::Unisyn::Parse::dumpParseResult($parse)

Dump the result of a parse

     Parameter  Description
  1  $parse     Parse

Example:

    my $f = "zzzOperators.lib";                                                   # Methods to be called against each syntactic item

    my $library = Subroutine                                                      # This subroutine and all of the subroutines it contains will be saved in an area and that area will be written to a file from where it can be included via L<incBin> in subsequent assemblies.
     {my ($p, $s, $sub) = @_;

      Subroutine                                                                  # A contained routine that we wish to export to a file
       {my ($p, $s, $sub) = @_;
        PrintOutString "Ascii: ";

        my $parse  = $$s{parse};                                                  # Parse
        my $source = $parse->source;                                              # Source

        $parse->area->getZmmBlock($$p{offset}, 1);                                # Load current parse tree node

        my $w = dSize;
        my $length   = dFromZ(1, $w * Nasm::X86::Unisyn::Lex::length);            # Length of ascii
        my $position = dFromZ(1, $w * Nasm::X86::Unisyn::Lex::position);          # Position in source

       ($source+$position)->printOutMemoryNL($length);                            # Print the ascii string

       } name => "Ascii",
         structures => {parse => Nasm::X86::Unisyn::DescribeParse},
         parameters => [qw(offset)];

      Subroutine                                                                  # Another subroutine that will be exported because it is within the subroutine that is being exported as a library
       {my ($p, $s, $sub) = @_;
        PrintOutStringNL "Add";
       } name => "+",
         structures => {parse => Nasm::X86::Unisyn::DescribeParse},
         parameters => [qw(offset)];

      Subroutine
       {my ($p, $s, $sub) = @_;
        PrintOutStringNL "Times";
       } name => "✕",
         structures => {parse => Nasm::X86::Unisyn::DescribeParse},
         parameters => [qw(offset)];

      Subroutine
       {my ($p, $s, $sub) = @_;
        PrintOutStringNL "And";
       } name => "𝕒𝕟𝕕",
         structures => {parse => Nasm::X86::Unisyn::DescribeParse},
         parameters => [qw(offset)];


      Subroutine
       {my ($p, $s, $sub) = @_;
        PrintOutString "Variable: ";

        my $parse  = $$s{parse};                                                  # Parse
        my $source = $parse->source;                                              # Source

        $parse->area->getZmmBlock($$p{offset}, 1);                                # Load current parse tree node

        my $w = dSize;
        my $length   = dFromZ(1, $w * Nasm::X86::Unisyn::Lex::length);            # Length of ascii
        my $position = dFromZ(1, $w * Nasm::X86::Unisyn::Lex::position);          # Position in source

       ($source+$position)->printOutMemoryNL($length);                            # Print the ascii string

       } name => "Variable",
         structures => {parse => Nasm::X86::Unisyn::DescribeParse},
         parameters => [qw(offset)];

     } name => "operators",  parameters=>[qw(a b c)], export => $f;

    ok Assemble eq => <<END, avx512=>1;
  END

    my $l = ReadArea $f;                                                          # Area containing subroutine library

    my ($A, $N) = constantString  qq(1+𝗔✕𝗕+𝗖𝕒𝕟𝕕2✕𝗔+𝗕+𝗖);                          # Utf8 string to parse

    my $p = ParseUnisyn($A, $N);                                                  # 10_445 Parse utf8 string  5_340 after single character lexical items, 4_950 after jump table

   $p->dumpParseResult;

   $p->traverseApplyingLibraryOperators($l);                                      # Traverse a parse tree applying a library of operators where they intersect with lexical items in the parse tree

  # ✕ 2715
  # + ff0b

    ok Assemble eq => <<END, clocks=>20_921;
  parseChar  : .... .... ...1 D5D6
  parseFail  : .... .... .... ...0
  position   : .... .... .... ..38
  parseMatch : .... .... .... ...0
  parseReason: .... .... .... ...0
  𝕒𝕟𝕕
  ._+
  ._._✕
  ._._._+
  ._._._._1
  ._._._._𝗔
  ._._._𝗕
  ._._𝗖
  ._+
  ._._+
  ._._._✕
  ._._._._2
  ._._._._𝗔
  ._._._𝗕
  ._._𝗖
  Ascii: 1
  Variable: 𝗔
  Add
  Variable: 𝗕
  Times
  Variable: 𝗖
  Add
  Ascii: 2
  Variable: 𝗔
  Times
  Variable: 𝗕
  Add
  Variable: 𝗖
  Add
  And
  END
    unlink $f;

Nasm::X86::Unisyn::Parse::dumpPostOrder($parse)

Dump a parse tree in post order.

     Parameter  Description
  1  $parse     Parse

Example:

    my $u = Nasm::X86::Unisyn::Lex::composeUnisyn("va w m+ vb");
    my $t = '𝗮 +𝗯';
    is_deeply $u, $t;

    my $p = &ParseUnisyn(constantString $t);                                      # Parse the utf8 string minus the final new line

    $p->dumpPostOrder;
    ok Assemble eq <<END;
  ._𝗮 
  ._𝗯
  +
  END

  if (1)
   {my $t = Nasm::X86::Unisyn::Lex::composeUnisyn "va w m+ w vb";
    is_deeply $t, "𝗮 + 𝗯";
    my $p = &ParseUnisyn(constantString $t);
    $p->dumpPostOrder;
    ok Assemble eq => <<END;
  ._𝗮 
  ._𝗯
  + 
  END
   }

Nasm::X86::Unisyn::Parse::traverseApplyingLibraryOperators($parse, $library)

Traverse a parse tree, in post order, applying a library of operators.

     Parameter  Description
  1  $parse     Parse tree
  2  $library   Area containing a library

Example:

    my $f = "zzzOperators.lib";                                                   # Methods to be called against each syntactic item

    my $library = Subroutine                                                      # This subroutine and all of the subroutines it contains will be saved in an area and that area will be written to a file from where it can be included via L<incBin> in subsequent assemblies.
     {my ($p, $s, $sub) = @_;

      Subroutine                                                                  # A contained routine that we wish to export to a file
       {my ($p, $s, $sub) = @_;
        PrintOutString "Ascii: ";

        my $parse  = $$s{parse};                                                  # Parse
        my $source = $parse->source;                                              # Source

        $parse->area->getZmmBlock($$p{offset}, 1);                                # Load current parse tree node

        my $w = dSize;
        my $length   = dFromZ(1, $w * Nasm::X86::Unisyn::Lex::length);            # Length of ascii
        my $position = dFromZ(1, $w * Nasm::X86::Unisyn::Lex::position);          # Position in source

       ($source+$position)->printOutMemoryNL($length);                            # Print the ascii string

       } name => "Ascii",
         structures => {parse => Nasm::X86::Unisyn::DescribeParse},
         parameters => [qw(offset)];

      Subroutine                                                                  # Another subroutine that will be exported because it is within the subroutine that is being exported as a library
       {my ($p, $s, $sub) = @_;
        PrintOutStringNL "Add";
       } name => "+",
         structures => {parse => Nasm::X86::Unisyn::DescribeParse},
         parameters => [qw(offset)];

      Subroutine
       {my ($p, $s, $sub) = @_;
        PrintOutStringNL "Times";
       } name => "✕",
         structures => {parse => Nasm::X86::Unisyn::DescribeParse},
         parameters => [qw(offset)];

      Subroutine
       {my ($p, $s, $sub) = @_;
        PrintOutStringNL "And";
       } name => "𝕒𝕟𝕕",
         structures => {parse => Nasm::X86::Unisyn::DescribeParse},
         parameters => [qw(offset)];


      Subroutine
       {my ($p, $s, $sub) = @_;
        PrintOutString "Variable: ";

        my $parse  = $$s{parse};                                                  # Parse
        my $source = $parse->source;                                              # Source

        $parse->area->getZmmBlock($$p{offset}, 1);                                # Load current parse tree node

        my $w = dSize;
        my $length   = dFromZ(1, $w * Nasm::X86::Unisyn::Lex::length);            # Length of ascii
        my $position = dFromZ(1, $w * Nasm::X86::Unisyn::Lex::position);          # Position in source

       ($source+$position)->printOutMemoryNL($length);                            # Print the ascii string

       } name => "Variable",
         structures => {parse => Nasm::X86::Unisyn::DescribeParse},
         parameters => [qw(offset)];

     } name => "operators",  parameters=>[qw(a b c)], export => $f;

    ok Assemble eq => <<END, avx512=>1;
  END

    my $l = ReadArea $f;                                                          # Area containing subroutine library

    my ($A, $N) = constantString  qq(1+𝗔✕𝗕+𝗖𝕒𝕟𝕕2✕𝗔+𝗕+𝗖);                          # Utf8 string to parse

    my $p = ParseUnisyn($A, $N);                                                  # 10_445 Parse utf8 string  5_340 after single character lexical items, 4_950 after jump table

   $p->dumpParseResult;

   $p->traverseApplyingLibraryOperators($l);                                      # Traverse a parse tree applying a library of operators where they intersect with lexical items in the parse tree

  # ✕ 2715
  # + ff0b

    ok Assemble eq => <<END, clocks=>20_921;
  parseChar  : .... .... ...1 D5D6
  parseFail  : .... .... .... ...0
  position   : .... .... .... ..38
  parseMatch : .... .... .... ...0
  parseReason: .... .... .... ...0
  𝕒𝕟𝕕
  ._+
  ._._✕
  ._._._+
  ._._._._1
  ._._._._𝗔
  ._._._𝗕
  ._._𝗖
  ._+
  ._._+
  ._._._✕
  ._._._._2
  ._._._._𝗔
  ._._._𝗕
  ._._𝗖
  Ascii: 1
  Variable: 𝗔
  Add
  Variable: 𝗕
  Times
  Variable: 𝗖
  Add
  Ascii: 2
  Variable: 𝗔
  Times
  Variable: 𝗕
  Add
  Variable: 𝗖
  Add
  And
  END
    unlink $f;

Assemble

Assemble generated code

CallC($sub, @parameters)

Call a C subroutine.

     Parameter    Description
  1  $sub         Name of the sub to call
  2  @parameters  Parameters

Example:

    my $format = Rs "Hello %s
";
    my $data   = Rs "World";

    Extern qw(printf exit malloc strcpy); Link 'c';


    CallC 'malloc', length($format)+1;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    Mov r15, rax;

    CallC 'strcpy', r15, $format;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲


    CallC 'printf', r15, $data;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲


    CallC 'exit', 0;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲


    ok Assemble avx512=>0, eq => <<END;
  Hello World
  END

Extern(@externalReferences)

Name external references.

     Parameter            Description
  1  @externalReferences  External references

Example:

    my $format = Rs "Hello %s
";
    my $data   = Rs "World";


    Extern qw(printf exit malloc strcpy); Link 'c';  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲


    CallC 'malloc', length($format)+1;
    Mov r15, rax;
    CallC 'strcpy', r15, $format;
    CallC 'printf', r15, $data;
    CallC 'exit', 0;

    ok Assemble avx512=>0, eq => <<END;
  Hello World
  END

Link(@libraries)

Libraries to link with.

     Parameter   Description
  1  @libraries  Link library names which will be looked for on "LIBPATH"

Example:

    my $format = Rs "Hello %s
";
    my $data   = Rs "World";


    Extern qw(printf exit malloc strcpy); Link 'c';  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲


    CallC 'malloc', length($format)+1;
    Mov r15, rax;
    CallC 'strcpy', r15, $format;
    CallC 'printf', r15, $data;
    CallC 'exit', 0;

    ok Assemble avx512=>0, eq => <<END;
  Hello World
  END

Start()

Initialize the assembler.

Example:

    Start;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    Exit(0);
    ok Assemble eq => <<END;
  END

Exit($c)

Exit with the specified return code or zero if no return code supplied. Assemble() automatically adds a call to Exit(0) if the last operation in the program is not a call to Exit.

     Parameter  Description
  1  $c         Return code

Example:

    Start;

    Exit(0);  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    ok Assemble eq => <<END;
  END

    Comment "Print a string from memory";
    my $s = "Hello World";
    Mov rax, Rs($s);
    Mov rdi, length $s;
    PrintOutMemory;

    Exit(0);  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲


    ok Assemble(avx512=>0) =~ m(Hello World);

Assemble(%options)

Assemble the generated code.

     Parameter  Description
  1  %options   Options

Example:

    PrintOutStringNL "Hello World";
    PrintOutStringNL "Hello
World";
    PrintErrStringNL "Hello World";


    ok Assemble eq => <<END, avx512=>0, label=>'t1';  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

  Hello World
  Hello
  World
  END


    ok Assemble eq => <<END, mix=>1;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

  END

Awaiting Classification

Routines that have not yet been classified.

Hash Definitions

Nasm::X86 Definition

Tree

Output fields

B

Log2 of size of initial allocation

N

Initial allocation

address

Variable that addresses the memory containing the area

area

Area definition.

block

Block used to generate this subroutine

constant

Constant if true

data

Variable containing the current data

dataOffset

The start of the data

end

End label for this subroutine

export

File this subroutine was exported to if any

expr

Expression that initializes the variable

fcArray

Offset of cached array in first block

fcControl

Offset of the tree bits and present bits in the first cache of low key values for this tree.

fcDWidth

Number of dwords available in the first cache. The first cache supplies an alternate area to store the values of keys less than this value to fill the otherwise unused space in a way that improves the performance of trees when used to represent small arrays, stacks or structures.

fcPresent

Offset of the present bits in the control dword

fcPresentOff

Byte offset of word containing present bits

fcTreeBits

Offset of the tree bits in bits in the control dword

fcTreeBitsOff

Byte offset of word containing tree bits

first

Variable addressing offset to first block of the tree which is the header block

found

Variable indicating whether the last find was successful or not

freeOffset

Free chain offset

key

Variable containing the current key

keyDataMask

Key data mask

label

Address in memory

length

Number of keys in a maximal block

lengthLeft

Left minimal number of keys

lengthMiddle

Number of splitting key counting from 1

lengthMin

The smallest number of keys we are allowed in any node other than a root node.

lengthOffset

Offset of length in keys block. The length field is a word - see: "MultiWayTree.svg"

lengthRight

Right minimal number of keys

loop

Offset of keys, data, node loop.

maxKeys

Maximum number of keys allowed in this tree which might well ne less than the maximum we can store in a zmm.

maxKeysZ

The maximum possible number of keys in a zmm register

maxNodesZ

The maximum possible number of nodes in a zmm register

middleOffset

Offset of the middle slot in bytes

name

Optional name

nextOffset

Position of next offset on free chain

nodeMask

Node mask

offset

Variable containing the offset of the block containing the current key

options

Options used by the author of the subroutine

optionsOffset

Offset of the options double word in the first block

parameters

Parameters definitions supplied by the author of the subroutine which get mapped in to parameter variables.

position

Position in stack frame

reference

Reference to another variable

rightOffset

Offset of the first right slot in bytes

rootOffset

Offset of the root field in the first block - the root field contains the offset of the block containing the keys of the root of the tree

sizeOffset

Offset of the size field in the first block - tells us the number of keys in the tree

splittingKey

Offset at which to split a full block

stack

MArk the area as being used as a stack

start

Start label for this subroutine which includes the enter instruction used to create a new stack frame

stringTree

String tree - now obsolete

stringTreeBit

Bit indicating string key tree

stringTreeCountOff

This field is used to count the total number of keys in a string tree so that we can assign unique numbers when pushing.

structureCopies

Copies of the structures passed to this subroutine with their variables replaced with references

structureVariables

Map structure variables to references at known positions in the sub

subTree

Variable indicating whether the last find found a sub tree

treeBits

Offset of tree bits in keys block. The tree bits field is a word, each bit of which tells us whether the corresponding data element is the offset (or not) to a sub tree of this tree .

treeBitsMask

Total of 14 tree bits

treeOffset

Yggdrasil - a tree of global variables in this area

up

Offset of up in data block.

usedOffset

Used field offset

variables

Map parameters to references at known positions in the sub

vars

Number of variables in subroutine

width

Width of a key or data slot.

zWidth

Width of a zmm register

zWidthD

Width of a zmm in double words being the element size

zmmBlock

Size of a zmm block - 64 bytes

Attributes

The following is a list of all the attributes in this package. A method coded with the same name in your package will over ride the method of the same name in this package and thus provide your value for the attribute in place of the default value supplied for this attribute by this package.

Replaceable Attribute List

Pi32 Pi64 bSize dSize qSize wSize

Pi32

Pi as a 32 bit float.

Pi64

Pi as a 64 bit float.

bSize

Size of a byte in bytes

dSize

Size of a double word in bytes

qSize

Size of a quad word in bytes

wSize

Size of a word in bytes

Private Methods

Dbwdq($s, @d)

Layout data.

     Parameter  Description
  1  $s         Element size
  2  @d         Data to be laid out

Rbwdq($s, @d)

Layout data.

     Parameter  Description
  1  $s         Element size
  2  @d         Data to be laid out

PushRR(@r)

Push registers onto the stack without tracking.

     Parameter  Description
  1  @r         Register

PopRR(@r)

Pop registers from the stack without tracking.

     Parameter  Description
  1  @r         Register

registerNameFromNumber($r)

Register name from number where possible.

     Parameter  Description
  1  $r         Register number

ChooseRegisters($number, @registers)

Choose the specified numbers of registers excluding those on the specified list.

     Parameter   Description
  1  $number     Number of registers needed
  2  @registers  Registers not to choose

checkZmmRegister($z)

Check that a register is a zmm register.

     Parameter  Description
  1  $z         Parameters

LoadRegFromMm($mm, $offset, $reg)

Load the specified register from the numbered zmm at the quad offset specified as a constant number.

     Parameter  Description
  1  $mm        Mm register
  2  $offset    Offset in quads
  3  $reg       General purpose register to load

Example:

    Mov rax, 1; SaveRegIntoMm(zmm0, 0, rax);
    Mov rax, 2; SaveRegIntoMm(zmm0, 1, rax);
    Mov rax, 3; SaveRegIntoMm(zmm0, 2, rax);
    Mov rax, 4; SaveRegIntoMm(zmm0, 3, rax);


    LoadRegFromMm(zmm0, 0, r15);  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲


    LoadRegFromMm(zmm0, 1, r14);  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲


    LoadRegFromMm(zmm0, 2, r13);  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲


    LoadRegFromMm(zmm0, 3, r12);  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲


    PrintOutRegisterInHex ymm0, r15, r14, r13, r12;
    ok Assemble(debug => 0, eq => <<END, avx512=>1);
    ymm0: .... .... .... ...4  .... .... .... ...3 - .... .... .... ...2  .... .... .... ...1
     r15: .... .... .... ...1
     r14: .... .... .... ...2
     r13: .... .... .... ...3
     r12: .... .... .... ...4
  END

extractRegisterNumberFromMM($mm)

Extract the register number from an *mm register.

     Parameter  Description
  1  $mm        Mmm register

getBwdqFromMm($xyz, $size, $mm, $offset, %options)

Get the numbered byte|word|double word|quad word from the numbered zmm register and return it in a variable.

     Parameter  Description
  1  $xyz       Size of mm
  2  $size      Size of get
  3  $mm        Mm register
  4  $offset    Offset in bytes either as a constant or as a variable
  5  %options   Options

LoadConstantIntoMaskRegister($mask, $value)

Set a mask register equal to a constant.

     Parameter  Description
  1  $mask      Number of mask register to load
  2  $value     Constant to load

createBitNumberFromAlternatingPattern($prefix, @values)

Create a number from a bit pattern.

     Parameter  Description
  1  $prefix    Prefix bits
  2  @values    +n 1 bits -n 0 bits

opposingJump($j)

Return the opposite of a jump.

     Parameter  Description
  1  $j         Jump

Example:

    is_deeply opposingJump(q(Jl)), q(Jge);  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲


    is_deeply opposingJump(q(Jg)), q(Jle);  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

IfS($then, $else)

If signed greater than or equal execute the then block else the else block.

     Parameter  Description
  1  $then      Then - required
  2  $else      Else - optional

IfNs($then, $else)

If signed less than execute the then block else the else block.

     Parameter  Description
  1  $then      Then - required
  2  $else      Else - optional

SubroutineStartStack()

Initialize a new stack frame. The first quad of each frame has the address of the name of the sub in the low dword, and the parameter count in the upper byte of the quad. This field is all zeroes in the initial frame.

copyStructureMinusVariables($s)

Copy a non recursive structure ignoring variables.

     Parameter  Description
  1  $s         Structure to copy

Nasm::X86::Subroutine::writeLibraryToArea($s, $subs)

Write a subroutine library to an area then save the area in a file so that the subroutine can be reloaded at a later date either as separate file or via incorporation into a thing. A thing was originally an assembly of people as in "The Allthing" or the "Stort Thing".

     Parameter  Description
  1  $s         Sub definition of containing subroutine
  2  $subs      Definitions of contained subroutines

Nasm::X86::Area::readLibraryHeader($area, $uniqueStrings, $singleLetterArray)

Create a tree mapping the numbers assigned to subroutine names to the offsets of the corresponding routines in a library returning the intersection so formed mapping the lexical item numbers (not names) encountered during parsing with the matching routines in the library. Optionally a subroutine (like Nasm::X86::Unisyn::Lex::letterToNumber) can be provided that returns details of an array that maps a single utf32 character to a smaller number which will be assumed to be the number of the routine with that single letter as its name.

     Parameter           Description
  1  $area               Area containing subroutine library
  2  $uniqueStrings      Unique strings from parse
  3  $singleLetterArray  Subroutine returning details of a single character mapping array

Example:

    my $a = CreateArea;

    my $u = $a->CreateTree(stringTree=>1);
    $u->putKeyString(constantString("ab"), K key => 1);
    $u->putKeyString(constantString("ac"), K key => 3);
    $u->putKeyString(constantString("𝕒𝕒"), K key => 4);

    my %s = (ab => 2, 𝕒𝕒 =>8, 𝗮𝗮𝗮=>12, 𝝰𝝰𝝰𝝰=>16);                                 # Subroutine names and offsets

    $a->writeLibraryHeader({%s});
    my ($inter, $subroutines) = $a->readLibraryHeader($u);

    $inter->dump("TT");

    ok Assemble eq => <<END, clocks=>4374;
  TT
  At:  1C0                    length:    2,  data:  200,  nodes:  240,  first:   40, root, leaf
    Index:    0    1
    Keys :    1    4
    Data :    2    8
  end
  END

    my $a = CreateArea;
    my $t = $a->CreateTree;

    K(loop => 16)->for(sub
     {my ($i, $start, $next, $end) = @_;
      my $T = $a->CreateTree;
      $t->put($i, $T);
      $t->size->outNL;
     });

    K(loop => 16)->for(sub
     {my ($i, $start, $next, $end) = @_;
      $t->popSubTree;
      $t->size->outNL;
     });

    ok Assemble eq => <<END, avx512=>1;
  size of tree: .... .... .... ...1
  size of tree: .... .... .... ...2
  size of tree: .... .... .... ...3
  size of tree: .... .... .... ...4
  size of tree: .... .... .... ...5
  size of tree: .... .... .... ...6
  size of tree: .... .... .... ...7
  size of tree: .... .... .... ...8
  size of tree: .... .... .... ...9
  size of tree: .... .... .... ...A
  size of tree: .... .... .... ...B
  size of tree: .... .... .... ...C
  size of tree: .... .... .... ...D
  size of tree: .... .... .... ...E
  size of tree: .... .... .... ...F
  size of tree: .... .... .... ..10
  size of tree: .... .... .... ...F
  size of tree: .... .... .... ...E
  size of tree: .... .... .... ...D
  size of tree: .... .... .... ...C
  size of tree: .... .... .... ...B
  size of tree: .... .... .... ...A
  size of tree: .... .... .... ...9
  size of tree: .... .... .... ...8
  size of tree: .... .... .... ...7
  size of tree: .... .... .... ...6
  size of tree: .... .... .... ...5
  size of tree: .... .... .... ...4
  size of tree: .... .... .... ...3
  size of tree: .... .... .... ...2
  size of tree: .... .... .... ...1
  size of tree: .... .... .... ...0
  END

    my $a = CreateArea;
    my $t = $a->CreateTree;
    my $T = $a->CreateTree;
    $t->push($T);
    $a->dump("AA");
    $t->popSubTree;
    $a->dump("BB");

    ok Assemble eq => <<END, avx512=>1;
  AA
  Area     Size:     4096    Used:      384
  .... .... .... ...0 | __10 ____ ____ ____  80.1 ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | C0__ ____ ____ ____  .1__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  .1__ .1__ __.1 ____
  BB
  Area     Size:     4096    Used:      384
  .... .... .... ...0 | __10 ____ ____ ____  80.1 ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  .1__ .1__ __.1 ____
  END

Nasm::X86::Subroutine::subroutineDefinition($area, $file, $name)

Get the definition of a subroutine from an area.

     Parameter  Description
  1  $area      Area - but only to get easy access to this routine
  2  $file      File containing area
  3  $name      Name of subroutine whose details we want

Nasm::X86::Subroutine::mapStructureVariables($sub, $S, @P)

Find the paths to variables in the copies of the structures passed as parameters and replace those variables with references so that in the subroutine we can refer to these variables regardless of where they are actually defined.

     Parameter  Description
  1  $sub       Sub definition
  2  $S         Copies of source structures
  3  @P         Path through copies of source structures to a variable that becomes a reference

Nasm::X86::Subroutine::uploadStructureVariablesToNewStackFrame($sub, $sv, $S, @P)

Create references to variables in parameter structures from variables in the stack frame of the subroutine.

     Parameter  Description
  1  $sub       Sub definition
  2  $sv        Structure variables
  3  $S         Source tree of input structures
  4  @P         Path through source structures tree

Nasm::X86::Subroutine::uploadToNewStackFrame($sub, $sv, $source, $target)

Map a variable in the current stack into a reference in the next stack frame being the one that will be used by this sub.

     Parameter  Description
  1  $sub       Subroutine descriptor
  2  $sv        Structure variables
  3  $source    Source variable in the current stack frame
  4  $target    The reference in the new stack frame

Nasm::X86::Subroutine::validateParameters($sub, %options)

Check that the parameters and structures presented in a call to a subroutine math those defined for the subroutine.

     Parameter  Description
  1  $sub       Subroutine descriptor
  2  %options   Options

PrintTraceBack($channel)

Trace the call stack.

     Parameter  Description
  1  $channel   Channel to write on

PrintErrTraceBack($message)

Print sub routine track back on stderr and then exit with a message.

     Parameter  Description
  1  $message   Reason why we are printing the trace back and then stopping

PrintNL($channel)

Print a new line to stdout or stderr.

     Parameter  Description
  1  $channel   Channel to write on

PrintErrNL()

Print a new line to stderr.

PrintString($channel, @string)

Print a constant string to the specified channel.

     Parameter  Description
  1  $channel   Channel
  2  @string    Strings

PrintStringNL($channel, @string)

Print a constant string to the specified channel followed by a new line.

     Parameter  Description
  1  $channel   Channel
  2  @string    Strings

PrintErrString(@string)

Print a constant string to stderr.

     Parameter  Description
  1  @string    String

PrintErrStringNL(@string)

Print a constant string to stderr followed by a new line.

     Parameter  Description
  1  @string    String

Example:

    PrintOutStringNL "Hello World";
    PrintOutStringNL "Hello
World";

    PrintErrStringNL "Hello World";  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲


    ok Assemble eq => <<END, avx512=>0, label=>'t1';
  Hello World
  Hello
  World
  END

PrintCString($channel, $string)

Print a zero terminated C style string addressed by a variable on the specified channel.

     Parameter  Description
  1  $channel   Channel
  2  $string    String

PrintCStringNL($channel, $string)

Print a zero terminated C style string addressed by a variable on the specified channel followed by a new line.

     Parameter  Description
  1  $channel   Channel
  2  $string    Strings

PrintSpace($channel, $spaces)

Print a constant number of spaces to the specified channel.

     Parameter  Description
  1  $channel   Channel
  2  $spaces    Number of spaces if not one.

PrintErrSpace($spaces)

Print a constant number of spaces to stderr.

     Parameter  Description
  1  $spaces    Number of spaces if not one.

hexTranslateTable()

Create/address a hex translate table and return its label.

PrintRaxInHex($channel, $end)

Write the content of register rax in hexadecimal in big endian notation to the specified channel.

     Parameter  Description
  1  $channel   Channel
  2  $end       Optional end byte

PrintErrRaxInHex()

Write the content of register rax in hexadecimal in big endian notation to stderr.

PrintErrRaxInHexNL()

Write the content of register rax in hexadecimal in big endian notation to stderr followed by a new line.

PrintRax_InHex($channel, $end)

Write the content of register rax in hexadecimal in big endian notation to the specified channel replacing zero bytes with __.

     Parameter  Description
  1  $channel   Channel
  2  $end       Optional end byte

PrintErrRax_InHex()

Write the content of register rax in hexadecimal in big endian notation to stderr.

PrintErrRax_InHexNL()

Write the content of register rax in hexadecimal in big endian notation to stderr followed by a new line.

PrintOneRegisterInHex($channel, $r)

Print the named register as a hex string.

     Parameter  Description
  1  $channel   Channel to print on
  2  $r         Register to print

PrintErrOneRegisterInHex($r)

Print the named register as a hex string on stderr.

     Parameter  Description
  1  $r         Register to print

PrintErrOneRegisterInHexNL($r)

Print the named register as a hex string on stderr followed by new line.

     Parameter  Description
  1  $r         Register to print

PrintRegisterInHex($channel, @r)

Print the named registers as hex strings.

     Parameter  Description
  1  $channel   Channel to print on
  2  @r         Names of the registers to print

PrintErrRegisterInHex(@r)

Print the named registers as hex strings on stderr.

     Parameter  Description
  1  @r         Names of the registers to print

PrintOutRipInHex()

Print the instruction pointer in hex.

PrintOutRflagsInHex()

Print the flags register in hex.

PrintErrZF()

Print the zero flag without disturbing it on stderr.

PrintRightInHex($channel, $number, $width)

Print out a number in hex right justified in a field of specified width on the specified channel.

     Parameter  Description
  1  $channel   Channel
  2  $number    Number as a variable or register
  3  $width     Width of output field as a constant

PrintErrRightInHex($number, $width)

Write the specified variable in hexadecimal right justified in a field of specified width on stderr.

     Parameter  Description
  1  $number    Number as a variable
  2  $width     Width of output field as a variable

PrintErrRightInHexNL($number, $width)

Write the specified variable in hexadecimal right justified in a field of specified width on stderr followed by a new line.

     Parameter  Description
  1  $number    Number as a variable
  2  $width     Width of output field as a variable

PrintRightInBin($channel, $Number, $Width)

Print out a number in binary right justified in a field of specified width on the specified channel.

     Parameter  Description
  1  $channel   Channel
  2  $Number    Number as a variable or register
  3  $Width     Width of output field as a variable or constant

PrintErrRightInBin($number, $width)

Write the specified variable in binary right justified in a field of specified width on stderr.

     Parameter  Description
  1  $number    Number as a variable
  2  $width     Width of output field as a variable

PrintErrRightInBinNL($number, $width)

Write the specified variable in binary right justified in a field of specified width on stderr followed by a new line.

     Parameter  Description
  1  $number    Number as a variable
  2  $width     Width of output field as a variable

PrintRaxInDec($channel)

Print rax in decimal on the specified channel.

     Parameter  Description
  1  $channel   Channel to write on

PrintErrRaxInDec()

Print rax in decimal on stderr.

PrintErrRaxInDecNL()

Print rax in decimal on stderr followed by a new line.

PrintRaxRightInDec($Width, $channel)

Print rax in decimal right justified in a field of the specified width on the specified channel.

     Parameter  Description
  1  $Width     Width as a variable or a constant
  2  $channel   Channel

PrintRightInDec($channel, $Number, $width)

Print out a number in decimal right justified in a field of specified width on the specified channel.

     Parameter  Description
  1  $channel   Channel
  2  $Number    Number as a variable or register
  3  $width     Width of output field as a variable or constant

PrintErrRightInDec($number, $width)

Print a variable or register in decimal right justified in a field of the specified width on stderr.

     Parameter  Description
  1  $number    Number as a variable or a register
  2  $width     Width as a variable or constant

PrintErrRightInDecNL($number, $width)

Print a variable or register in decimal right justified in a field of the specified width on stderr followed by a new line.

     Parameter  Description
  1  $number    Number as a variable or a register
  2  $width     Width as a variable or constant

PrintRaxAsText($channel)

Print the string in rax on the specified channel.

     Parameter  Description
  1  $channel   Channel to write on

PrintErrRaxAsText()

Print rax as text on stderr.

PrintErrRaxAsTextNL()

Print rax as text on stderr followed by a new line.

PrintRaxAsChar($channel)

Print the ascii character in rax on the specified channel.

     Parameter  Description
  1  $channel   Channel to write on

PrintErrRaxAsChar()

Print the character in rax on stderr.

PrintErrRaxAsCharNL()

Print the character in rax on stderr followed by a new line.

Variable($name, $expr, %options)

Create a new variable with the specified name initialized via an optional expression.

     Parameter  Description
  1  $name      Name of variable
  2  $expr      Optional expression initializing variable
  3  %options   Options

R($name)

Define a reference variable.

     Parameter  Description
  1  $name      Name of variable

Nasm::X86::Variable::dump($left, $channel, $newLine, $title1, $title2)

Dump the value of a variable to the specified channel adding an optional title and new line if requested.

     Parameter  Description
  1  $left      Left variable
  2  $channel   Channel
  3  $newLine   New line required
  4  $title1    Optional leading title
  5  $title2    Optional trailing title

Example:

    PrintCString  ($stdout, V(str => Rs("abc\0def")));
    PrintCStringNL($stdout, V(str => Rs("ABC\0DEF")));
    ok Assemble eq => <<END;
  abcABC
  END

    my $a = V(a => 3);  $a->outNL;
    my $b = K(b => 2);  $b->outNL;
    my $c = $a +  $b; $c->outNL;
    my $d = $c -  $a; $d->outNL;
    my $g = $a *  $b; $g->outNL;
    my $h = $g /  $b; $h->outNL;
    my $i = $a %  $b; $i->outNL;

    If ($a == 3,
    Then
     {PrintOutStringNL "a == 3"
     },
    Else
     {PrintOutStringNL "a != 3"
     });

    ++$a; $a->outNL;
    --$a; $a->outNL;

    ok Assemble eq => <<END, avx512=>0;
  a: .... .... .... ...3
  b: .... .... .... ...2
  (a add b): .... .... .... ...5
  ((a add b) sub a): .... .... .... ...2
  (a times b): .... .... .... ...6
  ((a times b) / b): .... .... .... ...3
  (a % b): .... .... .... ...1
  a == 3
  a: .... .... .... ...4
  a: .... .... .... ...3
  END

Nasm::X86::Variable::err($left, $title1, $title2)

Dump the value of a variable on stderr.

     Parameter  Description
  1  $left      Left variable
  2  $title1    Optional leading title
  3  $title2    Optional trailing title

Nasm::X86::Variable::errNL($left, $title1, $title2)

Dump the value of a variable on stderr and append a new line.

     Parameter  Description
  1  $left      Left variable
  2  $title1    Optional leading title
  3  $title2    Optional trailing title

Nasm::X86::Variable::d($left, $title1, $title2)

Dump the value of a variable on stderr and append the source file calling line in a format that Geany understands.

     Parameter  Description
  1  $left      Left variable
  2  $title1    Optional leading title
  3  $title2    Optional trailing title

Nasm::X86::Variable::errInDec($number, $title1, $title2)

Dump the value of a variable on stderr in decimal.

     Parameter  Description
  1  $number    Number as variable
  2  $title1    Optional leading title
  3  $title2    Optional trailing title

Nasm::X86::Variable::errInDecNL($number, $title1, $title2)

Dump the value of a variable on stderr in decimal followed by a new line.

     Parameter  Description
  1  $number    Number as variable
  2  $title1    Optional leading title
  3  $title2    Optional trailing title

Nasm::X86::Variable::rightInDec($number, $channel, $width)

Dump the value of a variable on the specified channel as a decimal number right adjusted in a field of specified width.

     Parameter  Description
  1  $number    Number as variable
  2  $channel   Channel
  3  $width     Width

Nasm::X86::Variable::errRightInDec($number, $width)

Dump the value of a variable on stderr as a decimal number right adjusted in a field of specified width.

     Parameter  Description
  1  $number    Number
  2  $width     Width

Nasm::X86::Variable::errRightInDecNL($number, $width)

Dump the value of a variable on stderr as a decimal number right adjusted in a field of specified width followed by a new line.

     Parameter  Description
  1  $number    Number
  2  $width     Width

Nasm::X86::Variable::rightInHex($number, $channel, $width)

Write the specified variable number in hexadecimal right justified in a field of specified width to the specified channel.

     Parameter  Description
  1  $number    Number to print as a variable
  2  $channel   Channel to print on
  3  $width     Width of output field

Nasm::X86::Variable::errRightInHex($number, $width)

Write the specified variable number in hexadecimal right justified in a field of specified width to stderr.

     Parameter  Description
  1  $number    Number to print as a variable
  2  $width     Width of output field

Nasm::X86::Variable::errRightInHexNL($number, $width)

Write the specified variable number in hexadecimal right justified in a field of specified width to stderr followed by a new line.

     Parameter  Description
  1  $number    Number to print as a variable
  2  $width     Width of output field

Nasm::X86::Variable::rightInBin($number, $channel, $width)

Write the specified variable number in binary right justified in a field of specified width to the specified channel.

     Parameter  Description
  1  $number    Number to print as a variable
  2  $channel   Channel to print on
  3  $width     Width of output field

Nasm::X86::Variable::errRightInBin($number, $width)

Write the specified variable number in binary right justified in a field of specified width to stderr.

     Parameter  Description
  1  $number    Number to print as a variable
  2  $width     Width of output field

Nasm::X86::Variable::errRightInBinNL($number, $width)

Write the specified variable number in binary right justified in a field of specified width to stderr followed by a new line.

     Parameter  Description
  1  $number    Number to print as a variable
  2  $width     Width of output field

Nasm::X86::Variable::errSpaces($count)

Print the specified number of spaces to stderr.

     Parameter  Description
  1  $count     Number of spaces

Nasm::X86::Variable::errCString($string)

Print a zero terminated C style string addressed by a variable on stderr.

     Parameter  Description
  1  $string    String

Nasm::X86::Variable::errCStringNL($string)

Print a zero terminated C style string addressed by a variable on stderr followed by a new line.

     Parameter  Description
  1  $string    String

Nasm::X86::Variable::equals($op, $left, $right)

Equals operator.

     Parameter  Description
  1  $op        Operator
  2  $left      Left variable
  3  $right     Right variable

Nasm::X86::Variable::assign($left, $op, $right)

Assign to the left hand side the value of the right hand side.

     Parameter  Description
  1  $left      Left variable
  2  $op        Operator
  3  $right     Right variable

Nasm::X86::Variable::plusAssign($left, $right)

Implement plus and assign.

     Parameter  Description
  1  $left      Left variable
  2  $right     Right variable

Nasm::X86::Variable::minusAssign($left, $right)

Implement minus and assign.

     Parameter  Description
  1  $left      Left variable
  2  $right     Right variable

Nasm::X86::Variable::arithmetic($op, $name, $left, $right)

Return a variable containing the result of an arithmetic operation on the left hand and right hand side variables.

     Parameter  Description
  1  $op        Operator
  2  $name      Operator name
  3  $left      Left variable
  4  $right     Right variable

Nasm::X86::Variable::add($left, $right)

Add the right hand variable to the left hand variable and return the result as a new variable.

     Parameter  Description
  1  $left      Left variable
  2  $right     Right variable

Nasm::X86::Variable::sub($left, $right)

Subtract the right hand variable from the left hand variable and return the result as a new variable.

     Parameter  Description
  1  $left      Left variable
  2  $right     Right variable

Nasm::X86::Variable::times($left, $right)

Multiply the left hand variable by the right hand variable and return the result as a new variable.

     Parameter  Description
  1  $left      Left variable
  2  $right     Right variable

Nasm::X86::Variable::division($op, $left, $right)

Return a variable containing the result or the remainder that occurs when the left hand side is divided by the right hand side.

     Parameter  Description
  1  $op        Operator
  2  $left      Left variable
  3  $right     Right variable

Nasm::X86::Variable::divide($left, $right)

Divide the left hand variable by the right hand variable and return the result as a new variable.

     Parameter  Description
  1  $left      Left variable
  2  $right     Right variable

Nasm::X86::Variable::mod($left, $right)

Divide the left hand variable by the right hand variable and return the remainder as a new variable.

     Parameter  Description
  1  $left      Left variable
  2  $right     Right variable

Nasm::X86::Variable::shiftLeft($left, $right)

Shift the left hand variable left by the number of bits specified in the right hand variable and return the result as a new variable.

     Parameter  Description
  1  $left      Left variable
  2  $right     Right variable

Example:

    K(loop=>16)->for(sub
     {my ($index, $start, $next, $end) = @_;
     (K(one => 1)     << $index)->outRightInBinNL(16);
     (K(one => 1<<15) >> $index)->outRightInBinNL(16);
     });

    ok Assemble eq => <<END, avx512=>1;
                 1
  1000000000000000
                10
   100000000000000
               100
    10000000000000
              1000
     1000000000000
             10000
      100000000000
            100000
       10000000000
           1000000
        1000000000
          10000000
         100000000
         100000000
          10000000
        1000000000
           1000000
       10000000000
            100000
      100000000000
             10000
     1000000000000
              1000
    10000000000000
               100
   100000000000000
                10
  1000000000000000
                 1
  END

Nasm::X86::Variable::shiftRight($left, $right)

Shift the left hand variable right by the number of bits specified in the right hand variable and return the result as a new variable.

     Parameter  Description
  1  $left      Left variable
  2  $right     Right variable

Example:

    K(loop=>16)->for(sub
     {my ($index, $start, $next, $end) = @_;
     (K(one => 1)     << $index)->outRightInBinNL(16);
     (K(one => 1<<15) >> $index)->outRightInBinNL(16);
     });

    ok Assemble eq => <<END, avx512=>1;
                 1
  1000000000000000
                10
   100000000000000
               100
    10000000000000
              1000
     1000000000000
             10000
      100000000000
            100000
       10000000000
           1000000
        1000000000
          10000000
         100000000
         100000000
          10000000
        1000000000
           1000000
       10000000000
            100000
      100000000000
             10000
     1000000000000
              1000
    10000000000000
               100
   100000000000000
                10
  1000000000000000
                 1
  END

Nasm::X86::Variable::not($left)

Form two complement of left hand side and return it as a variable.

     Parameter  Description
  1  $left      Left variable

Nasm::X86::Variable::booleanZF($sub, $op, $left, $right)

Combine the left hand variable with the right hand variable via a boolean operator and indicate the result by setting the zero flag if the result is true.

     Parameter  Description
  1  $sub       Operator
  2  $op        Operator name
  3  $left      Left variable
  4  $right     Right variable

Nasm::X86::Variable::eq($left, $right)

Check whether the left hand variable is equal to the right hand variable.

     Parameter  Description
  1  $left      Left variable
  2  $right     Right variable

Nasm::X86::Variable::ne($left, $right)

Check whether the left hand variable is not equal to the right hand variable.

     Parameter  Description
  1  $left      Left variable
  2  $right     Right variable

Nasm::X86::Variable::ge($left, $right)

Check whether the left hand variable is greater than or equal to the right hand variable.

     Parameter  Description
  1  $left      Left variable
  2  $right     Right variable

Nasm::X86::Variable::gt($left, $right)

Check whether the left hand variable is greater than the right hand variable.

     Parameter  Description
  1  $left      Left variable
  2  $right     Right variable

Nasm::X86::Variable::le($left, $right)

Check whether the left hand variable is less than or equal to the right hand variable.

     Parameter  Description
  1  $left      Left variable
  2  $right     Right variable

Nasm::X86::Variable::lt($left, $right)

Check whether the left hand variable is less than the right hand variable.

     Parameter  Description
  1  $left      Left variable
  2  $right     Right variable

Nasm::X86::Variable::incDec($left, $op)

Increment or decrement a variable.

     Parameter  Description
  1  $left      Left variable operator
  2  $op        Address of operator to perform inc or dec

Nasm::X86::Variable::inc($left)

Increment a variable.

     Parameter  Description
  1  $left      Variable

Nasm::X86::Variable::dec($left)

Decrement a variable.

     Parameter  Description
  1  $left      Variable

Nasm::X86::Variable::str($left)

The name of the variable.

     Parameter  Description
  1  $left      Variable

Example:

  if (1)
   {my $a = V(key => 0x123);
    is_deeply $a->at,           "[rbp-8*(2)]";
    is_deeply $a->addressExpr, "[rbp-8*(2)]";

    ok !$a->isRef;

    Mov rax, -1;
    Kmovq k1, rax;
    PrintOutRegisterInHex k1;

    K(key => 2)->clearBit(rax);
    PrintOutRegisterInHex rax;

    K(key => 2)->setBit(rax);
    PrintOutRegisterInHex rax;

    K(key => 3)->clearMaskBit(k1);
    PrintOutRegisterInHex k1;

    K(key => 3)->setMaskBit(k1);
    PrintOutRegisterInHex k1;

    K(key => 0)->clearMaskBit(k1);
    PrintOutRegisterInHex k1;

    ClearRegisters k1;
    K(key => 7)->setMaskFirst(k1);
    PrintOutRegisterInHex k1;

    K(key => 3)->spaces($stdout);
    PrintOutRegisterInHex k1;

    my $N = K size => 4096;
    my $A = $N->allocateMemory;
    $A->clearMemory($N);
    ClearMemory($A, $N);

    $A->setReg(rax);
    Mov "dword[rax]",   0x61626364;
    Mov "dword[rax+4]", 0x65666768;

    ($A+8)->copyMemory($A, K key => 8);

    $A->printOutMemory  (K(key => 16));
    $A->printOutMemoryNL(K(key => 16));

    K(K => Rd(0..63))->loadZmm(1);
    PrintOutRegisterInHex zmm1;

    ok Assemble eq => <<END;
      k1: .... .... .... ..-1
     rax: FFFF FFFF FFFF FFFB
     rax: .... .... .... ..-1
      k1: FFFF FFFF FFFF FFF7
      k1: .... .... .... ..-1
      k1: FFFF FFFF FFFF FFFE
      k1: .... .... .... ..7F
         k1: .... .... .... ..7F
  dcbahgfedcbahgfedcbahgfedcbahgfe
    zmm1: .... ...F .... ...E  .... ...D .... ...C - .... ...B .... ...A  .... ...9 .... ...8 + .... ...7 .... ...6  .... ...5 .... ...4 - .... ...3 .... ...2  .... ...1 .... ....
  END
   }

Nasm::X86::Variable::and($left, $right)

And two variables.

     Parameter  Description
  1  $left      Left variable
  2  $right     Right variable

Nasm::X86::Variable::or($left, $right)

Or two variables.

     Parameter  Description
  1  $left      Left variable
  2  $right     Right variable

Nasm::X86::Variable::putBwdqIntoMm($content, $size, $mm, $offset)

Place the value of the content variable at the byte|word|double word|quad word in the numbered zmm register.

     Parameter  Description
  1  $content   Variable with content
  2  $size      Size of put
  3  $mm        Numbered zmm
  4  $offset    Offset in bytes

dFromPointInZ($point, $zmm, %options)

Get the double word from the numbered zmm register at a point specified by the variable or register and return it in a variable.

     Parameter  Description
  1  $point     Point
  2  $zmm       Numbered zmm
  3  %options   Options

Example:

    Mov r15, 0x12345678;
    bRegIntoZmm(r15, 1,  0);
    bRegIntoZmm(r15, 1,  1);
    dRegIntoZmm(r15, 1,  4);
    dRegIntoZmm(r15, 1,  8);
    dRegIntoZmm(r15, 1, 12);
    PrintOutRegisterInHex xmm(1);
    PrintOutRegisterInHex zmm(1);

    bRegFromZmm(r15, 1, 1);
    PrintOutRegisterInHex r15;

    bFromX(1, 0)->outNL;
    bFromZ(1, 0)->outNL;

    dRegFromZmm(r14, 1, 3);
    PrintOutRegisterInHex r14;

    wRegFromZmm(r14, 1, 3);
    PrintOutRegisterInHex r14;

    bFromX(1, 0)->outNL;
    bFromZ(1, 1)->outNL;
    bFromZ(1, 2)->outNL;

    wFromX(1, 0)->outNL;
    wFromZ(1, 1)->outNL;
    wFromZ(1, 2)->outNL;

    dFromX(1, 0)->outNL;
    dFromZ(1, 1)->outNL;
    dFromZ(1, 2)->outNL;

    qFromX(1, 0)->outNL;
    qFromZ(1, 1)->outNL;
    dFromZ(1, 2)->outNL;


    K( offset => 1 << 5)->dFromPointInZ(zmm(1))->outNL;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲


    Mov       r15, 2;
    Kmovq k7, r15;
    LoadZmm 2, map {0xff} 1..64;
    PrintOutRegisterInHex zmm2;
    Vmovdqu8 zmmM (2, 7), zmm(1);
    Vmovdqu8 zmmMZ(3, 7), zmm(1);
    PrintOutRegisterInHex zmm1, zmm2, zmm3;

    ok Assemble eq => <<END;
    xmm1: 1234 5678 1234 5678  1234 5678 .... 7878
    zmm1: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - 1234 5678 1234 5678  1234 5678 .... 7878
     r15: .... .... 1234 5678
  b at offset 0 in xmm1: .... .... .... ..78
  b at offset 0 in zmm1: .... .... .... ..78
     r14: .... .... 3456 78..
     r14: .... .... 3456 78..
  b at offset 0 in xmm1: .... .... .... ..78
  b at offset 1 in zmm1: .... .... .... ..78
  b at offset 2 in zmm1: .... .... .... ...0
  w at offset 0 in xmm1: .... .... .... 7878
  w at offset 1 in zmm1: .... .... .... ..78
  w at offset 2 in zmm1: .... .... .... ...0
  d at offset 0 in xmm1: .... .... .... 7878
  d at offset 1 in zmm1: .... .... 78.. ..78
  d at offset 2 in zmm1: .... .... 5678 ....
  q at offset 0 in xmm1: 1234 5678 .... 7878
  q at offset 1 in zmm1: 7812 3456 78.. ..78
  d at offset 2 in zmm1: .... .... 5678 ....
  d: .... .... .... ...0
    zmm2: .... .... .... ..-1  .... .... .... ..-1 - .... .... .... ..-1  .... .... .... ..-1 + .... .... .... ..-1  .... .... .... ..-1 - .... .... .... ..-1  .... .... .... ..-1
    zmm1: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - 1234 5678 1234 5678  1234 5678 .... 7878
    zmm2: .... .... .... ..-1  .... .... .... ..-1 - .... .... .... ..-1  .... .... .... ..-1 + .... .... .... ..-1  .... .... .... ..-1 - .... .... .... ..-1  FFFF FFFF FFFF 78FF
    zmm3: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... 78..
  END

Nasm::X86::Variable::printMemory($address, $channel, $size)

Print the specified number of bytes from the memory addressed by the variable on the specified channel.

     Parameter  Description
  1  $address   Address of memory
  2  $channel   Channel to print on as a constant
  3  $size      Number of bytes to print

Nasm::X86::Variable::printErrMemory($address, $size)

Print the specified number of bytes of the memory addressed by the variable on stdout.

     Parameter  Description
  1  $address   Address of memory
  2  $size      Number of bytes to print

Nasm::X86::Variable::printErrMemoryNL($address, $size)

Print the specified number of bytes of the memory addressed by the variable on stdout followed by a new line.

     Parameter  Description
  1  $address   Address of memory
  2  $size      Number of bytes to print

Nasm::X86::Variable::printMemoryInHexNL($address, $channel, $size)

Write, in hexadecimal, the memory addressed by a variable to stdout or stderr.

     Parameter  Description
  1  $address   Address of memory
  2  $channel   Channel to print on
  3  $size      Number of bytes to print

Nasm::X86::Variable::printErrMemoryInHexNL($address, $size)

Write the memory addressed by a variable to stderr.

     Parameter  Description
  1  $address   Address of memory
  2  $size      Number of bytes to print

PrintMemoryInHex($channel)

Dump memory from the address in rax for the length in rdi on the specified channel. As this method prints in blocks of 8 up to 7 bytes will be missing from the end unless the length is a multiple of 8 .

     Parameter  Description
  1  $channel   Channel

PrintErrMemoryInHex()

Dump memory from the address in rax for the length in rdi on stderr.

PrintErrMemoryInHexNL()

Dump memory from the address in rax for the length in rdi and then print a new line.

PrintMemory_InHex($channel)

Dump memory from the address in rax for the length in rdi on the specified channel. As this method prints in blocks of 8 up to 7 bytes will be missing from the end unless the length is a multiple of 8 .

     Parameter  Description
  1  $channel   Channel

PrintErrMemory_InHex()

Dump memory from the address in rax for the length in rdi on stderr.

PrintErrMemory_InHexNL()

Dump memory from the address in rax for the length in rdi and then print a new line.

PrintMemory($channel)

Print the memory addressed by rax for a length of rdi on the specified channel where channel can be a constant number or a register expression using a bound register.

     Parameter  Description
  1  $channel   Channel

Example:

  if (1)
   {my $s = "zzzCreated.data";
    my $f = Rs $s;
    Mov rax, $f;
    OpenWrite;
    Mov r15, rax;
    Mov rax, $f;
    Mov rdi, length $s;

    PrintMemory r15;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    CloseFile;
    ok Assemble eq=><<END, avx512=>1;
  END
    ok -e $s;
    unlink $s;
   }

  if (!!onGitHub) {

PrintMemoryNL()

Print the memory addressed by rax for a length of rdi on the specified channel followed by a new line.

PrintErrMemory()

Print the memory addressed by rax for a length of rdi on stderr.

PrintErrMemoryNL()

Print the memory addressed by rax for a length of rdi followed by a new line on stderr.

CopyMemory4K($source, $target, $size)

Copy memory in 4K byte blocks.

     Parameter  Description
  1  $source    Source address variable
  2  $target    Target address variable
  3  $size      Number of 4K byte blocks to move

convert_rax_from_utf32_to_utf8()

Convert a utf32 character held in rax to a utf8 character held in rax.

Example:

  # $   U+0024                 010 0100                00100100                     24
  # £   U+00A3            000 1010 0011                11000010 10100011            C2 A3
  # ह     U+0939        0000 1001 0011 1001                11100000 10100100 10111001   E0 A4 B9
  # €   U+20AC          0010 0000 1010 1100                11100010 10000010 10101100   E2 82 AC
  # 한   U+D55C          1101 0101 0101 1100                11101101 10010101 10011100   ED 95 9C
  # 𐍈           U+10348         0 0001 0000 0011 0100 1000      11110000 10010000 10001101 10001000   F0 90 8D 88
    Mov rax, 0x40;                                                                # 0x40

    convert_rax_from_utf32_to_utf8;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    PrintOutRegisterInHex rax;

    Mov rax, 0x03b1;                                                              # 0xCE 0xB1

    convert_rax_from_utf32_to_utf8;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    PrintOutRegisterInHex rax;

    Mov rax, 0x20ac;                                                              # 0xE2 0x82 0xAC;

    convert_rax_from_utf32_to_utf8;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    PrintOutRegisterInHex rax;

    Mov rax, 0x10348;                                                             # 0xf0 0x90 0x8d 0x88

    convert_rax_from_utf32_to_utf8;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    PrintOutRegisterInHex rax;

    ok Assemble eq => <<END, avx512=>1;
     rax: .... .... .... ..40
     rax: .... .... .... B1CE
     rax: .... .... ..AC 82E2
     rax: .... .... 888D 90F0
  END

Cstrlen()

Length of the C style string addressed by rax returning the length in r15.

DescribeArea(%options)

Describe a relocatable area. By describing an areas, we allocate space with which to describe it in the current stack frame but we do not allocate memory for the area itself in the heap.

     Parameter  Description
  1  %options   Optional variable addressing the start of the area

Nasm::X86::Area::copyDescriptor($target, $source)

Copy the description of one area into another

     Parameter  Description
  1  $target    Target area
  2  $source    Source area

Nasm::X86::Area::updateSpace($area, $size)

Make sure that a variable addressed area has enough space to accommodate content of a variable size.

     Parameter  Description
  1  $area      Area descriptor
  2  $size      Variable size needed

Nasm::X86::Area::allocZmmBlock3($area)

Allocate three zmm blocks in one go and return their offsets.

     Parameter  Description
  1  $area      Area

Nasm::X86::Yggdrasil::UniqueStrings {K key => 0}(sub Nasm::X86::Yggdrasil::SubroutineOffsets {K key => 1})

A tree of strings that assigns unique numbers to strings.

     Parameter                                                    Description
  1  sub Nasm::X86::Yggdrasil::SubroutineOffsets    {K key => 1}  P Translates a string number into the offset of a subroutine in an area.

Nasm::X86::Yggdrasil::SubroutineOffsets {K key => 1}(sub Nasm::X86::Yggdrasil::SubroutineDefinitions{K key => 2})

Translates a string number into the offset of a subroutine in an area.

     Parameter                                                    Description
  1  sub Nasm::X86::Yggdrasil::SubroutineDefinitions{K key => 2}  P Maps the unique string number for a subroutine name to the offset in the are that contains the length (as a dword) followed by the string content of the Perl data structure describing the subroutine in question.

Nasm::X86::Yggdrasil::SubroutineDefinitions{K key => 2}(sub Nasm::X86::Yggdrasil::Unisyn::Alphabets {K key => 3})

Maps the unique string number for a subroutine name to the offset in the are that contains the length (as a dword) followed by the string content of the Perl data structure describing the subroutine in question.

     Parameter                                                    Description
  1  sub Nasm::X86::Yggdrasil::Unisyn::Alphabets    {K key => 3}  P Unisyn alphabets.

Nasm::X86::Yggdrasil::Unisyn::Alphabets {K key => 3}(sub Nasm::X86::Yggdrasil::Unisyn::Open {K key => 4})

Unisyn alphabets.

     Parameter                                                    Description
  1  sub Nasm::X86::Yggdrasil::Unisyn::Open         {K key => 4}  P Open bracket to close bracket

Nasm::X86::Yggdrasil::Unisyn::Open {K key => 4}(sub Nasm::X86::Yggdrasil::Unisyn::Close {K key => 5})

Open bracket to close bracket

     Parameter                                                    Description
  1  sub Nasm::X86::Yggdrasil::Unisyn::Close        {K key => 5}  P Close bracket to open bracket

Nasm::X86::Yggdrasil::Unisyn::Close {K key => 5}(sub Nasm::X86::Yggdrasil::Unisyn::Transitions {K key => 6})

Close bracket to open bracket

     Parameter                                                    Description
  1  sub Nasm::X86::Yggdrasil::Unisyn::Transitions  {K key => 6}  P Permissible transitions from alphabet to alphabet

Nasm::X86::Yggdrasil::Unisyn::Transitions {K key => 6}()

Permissible transitions from alphabet to alphabet

Nasm::X86::Area::checkYggdrasilCreated($area)

Return a tree descriptor for the Yggdrasil world tree for an area. If Yggdrasil has not been created the found field of the returned descriptor will have zero in it else one.

     Parameter  Description
  1  $area      Area descriptor

Example:

    my $A = CreateArea;
    my $t = $A->checkYggdrasilCreated;
       $t->found->outNL;
    my $y = $A->yggdrasil;
    my $T = $A->checkYggdrasilCreated;
       $T->found->outNL;
    ok Assemble debug => 0, eq => <<END, avx512=>1;
  found  : .... .... .... ...0
  found  : .... .... .... ...1
  END

Nasm::X86::Area::zero($area)

Append a trailing zero to the area addressed by rax.

     Parameter  Description
  1  $area      Area descriptor

DescribeTree(%options)

Return a descriptor for a tree with the specified options. The options from one tree get inherited by any sub trees they contain

     Parameter  Description
  1  %options   Tree description options

Nasm::X86::Area::DescribeTree($area, %options)

Return a descriptor for a tree in the specified area with the specified options.

     Parameter  Description
  1  $area      Area descriptor
  2  %options   Options for tree

Nasm::X86::Tree::DescribeTree($tree, %options)

Create a description of a tree.

     Parameter  Description
  1  $tree      Tree descriptor
  2  %options   {first=>first node of tree if not the existing first node; area=>area used by tree if not the existing area}

Nasm::X86::Tree::position($tree, $first)

Create a new tree description for a tree positioned at the specified location.

     Parameter  Description
  1  $tree      Tree descriptor
  2  $first     Offset of tree

Nasm::X86::Tree::firstFromMemory($tree, $zmm)

Load the first block for a tree into the numbered zmm.

     Parameter  Description
  1  $tree      Tree descriptor
  2  $zmm       Number of zmm to contain first block

Nasm::X86::Tree::firstIntoMemory($tree, $zmm)

Save the first block of a tree in the numbered zmm back into memory.

     Parameter  Description
  1  $tree      Tree descriptor
  2  $zmm       Number of zmm containing first block

Nasm::X86::Tree::rootIntoFirst($tree, $zmm, $value)

Put the contents of a variable into the root field of the first block of a tree when held in a zmm register.

     Parameter  Description
  1  $tree      Tree descriptor
  2  $zmm       Number of zmm containing first block
  3  $value     Variable containing value to put

Nasm::X86::Tree::rootFromFirst($tree, $zmm, %options)

Return a variable containing the offset of the root block of a tree from the first block when held in a zmm register.

     Parameter  Description
  1  $tree      Tree descriptor
  2  $zmm       Number of zmm containing first block
  3  %options   Options

Nasm::X86::Tree::root($t, $F, $offset)

Check whether the specified offset refers to the root of a tree when the first block is held in a zmm register. The result is returned by setting the zero flag to one if the offset is the root, else to zero.

     Parameter  Description
  1  $t         Tree descriptor
  2  $F         Zmm register holding first block
  3  $offset    Offset of block as a variable

Example:

    my $a = CreateArea;
    my $t = $a->CreateTree;
    my $b = $t->allocBlock(31, 30, 29);
    K(data => 0x33)->dIntoZ(31, 4);
    $t->lengthIntoKeys(31, K length =>0x9);
    $t->putBlock($b, 31, 30, 29);
    $t->getBlock($b, 25, 24, 23);
    PrintOutRegisterInHex 25;
    $t->lengthFromKeys(25)->outNL;


    $t->firstFromMemory(28);
    $t->incSizeInFirst (28);
    $t->rootIntoFirst  (28, K value => 0x2222);
    $t->root           (28, K value => 0x2222);  PrintOutZF;
    $t->root           (28, K value => 0x2221);  PrintOutZF;
    $t->root           (28, K value => 0x2222);  PrintOutZF;
    $t->firstIntoMemory(28);

    $t->first->outNL;
    $b->outNL;
    $a->dump("1111");
    PrintOutRegisterInHex 31, 30, 29, 28;

    If $t->leafFromNodes(29) > 0, Then {PrintOutStringNL "29 Leaf"}, Else {PrintOutStringNL "29 Branch"};
    If $t->leafFromNodes(28) > 0, Then {PrintOutStringNL "28 Leaf"}, Else {PrintOutStringNL "28 Branch"};


    ok Assemble eq => <<END, avx512=>1;
   zmm25: .... ..C0 .... ...9  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... ..33 .... ....
  b at offset 56 in zmm25: .... .... .... ...9
  ZF=1
  ZF=0
  ZF=1
  first  : .... .... .... ..40
  address: .... .... .... ..80
  1111
  Area     Size:     4096    Used:      320
  .... .... .... ...0 | __10 ____ ____ ____  40.1 ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 2222 ____ ____ ____  .1__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | ____ ____ 33__ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  .9__ ____ C0__ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ __.1 ____
   zmm31: .... ..C0 .... ...9  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... ..33 .... ....
   zmm30: .... .1.. .... ....  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0
   zmm29: .... ..40 .... ....  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0
   zmm28: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...1  .... .... .... 2222
  29 Leaf
  28 Branch
  END

Nasm::X86::Tree::optionsFromFirst($tree, $zmm, %options)

Return a variable containing the options double word from the first block zmm register.

     Parameter  Description
  1  $tree      Tree descriptor
  2  $zmm       Number of zmm containing first block
  3  %options   Options

Nasm::X86::Tree::optionsIntoFirst($tree, $zmm, $value, %options)

Put the contents of a variable into the options field of the first block of a tree when the first block is held in a zmm register.

     Parameter  Description
  1  $tree      Tree descriptor
  2  $zmm       Number of zmm containing first block
  3  $value     Variable containing options to put
  4  %options   Options

Nasm::X86::Tree::sizeFromFirst($tree, $zmm)

Return a variable containing the number of keys in the specified tree when the first block is held in a zmm register..

     Parameter  Description
  1  $tree      Tree descriptor
  2  $zmm       Number of zmm containing first block

Nasm::X86::Tree::sizeIntoFirst($tree, $zmm, $value)

Put the contents of a variable into the size field of the first block of a tree when the first block is held in a zmm register.

     Parameter  Description
  1  $tree      Tree descriptor
  2  $zmm       Number of zmm containing first block
  3  $value     Variable containing value to put

Nasm::X86::Tree::incSizeInFirst($tree, $zmm)

Increment the size field in the first block of a tree when the first block is held in a zmm register.

     Parameter  Description
  1  $tree      Tree descriptor
  2  $zmm       Number of zmm containing first block

Example:

    my $t = DescribeTree();

    my $F = 31;
    K(key => 0xff)->dIntoZ($F, 60);
    K(key => 0xee)->dIntoZ($F, 56);
    PrintOutRegisterInHex $F;
    $t->incSizeInFirst($F); PrintOutRegisterInHex $F;
    $t->incSizeInFirst($F); PrintOutRegisterInHex $F;
    $t->incSizeInFirst($F); PrintOutRegisterInHex $F;
    $t->decSizeInFirst($F); PrintOutRegisterInHex $F;
    $t->decSizeInFirst($F); PrintOutRegisterInHex $F;
    $t->decSizeInFirst($F); PrintOutRegisterInHex $F;

    ok Assemble eq => <<END, avx512=>1;                                           # Once we know the insertion point we can add the key/data/subTree triple, increase the length and update the tree bits
   zmm31: .... ..FF .... ..EE  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0
   zmm31: .... ..FF .... ..EE  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...1  .... .... .... ...0
   zmm31: .... ..FF .... ..EE  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...2  .... .... .... ...0
   zmm31: .... ..FF .... ..EE  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...3  .... .... .... ...0
   zmm31: .... ..FF .... ..EE  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...2  .... .... .... ...0
   zmm31: .... ..FF .... ..EE  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...1  .... .... .... ...0
   zmm31: .... ..FF .... ..EE  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0
  END

Nasm::X86::Tree::decSizeInFirst($tree, $zmm)

Decrement the size field in the first block of a tree when the first block is held in a zmm register.

     Parameter  Description
  1  $tree      Tree descriptor
  2  $zmm       Number of zmm containing first block

Nasm::X86::Tree::incSize($tree)

Increment the size of a tree.

     Parameter  Description
  1  $tree      Tree descriptor

Nasm::X86::Tree::decSize($tree)

Decrement the size of a tree.

     Parameter  Description
  1  $tree      Tree descriptor

Nasm::X86::Tree::allocBlock($tree, $K, $D, $N)

Allocate a keys/data/node block and place it in the numbered zmm registers.

     Parameter  Description
  1  $tree      Tree descriptor
  2  $K         Numbered zmm for keys
  3  $D         Numbered zmm for data
  4  $N         Numbered zmm for children

Example:

    my $a = CreateArea;
    my $t = $a->CreateTree;
    my $b = $t->allocBlock(31, 30, 29);
    K(data => 0x33)->dIntoZ(31, 4);
    $t->lengthIntoKeys(31, K length =>0x9);
    $t->putBlock($b, 31, 30, 29);
    $t->getBlock($b, 25, 24, 23);
    PrintOutRegisterInHex 25;
    $t->lengthFromKeys(25)->outNL;


    $t->firstFromMemory(28);
    $t->incSizeInFirst (28);
    $t->rootIntoFirst  (28, K value => 0x2222);
    $t->root           (28, K value => 0x2222);  PrintOutZF;
    $t->root           (28, K value => 0x2221);  PrintOutZF;
    $t->root           (28, K value => 0x2222);  PrintOutZF;
    $t->firstIntoMemory(28);

    $t->first->outNL;
    $b->outNL;
    $a->dump("1111");
    PrintOutRegisterInHex 31, 30, 29, 28;

    If $t->leafFromNodes(29) > 0, Then {PrintOutStringNL "29 Leaf"}, Else {PrintOutStringNL "29 Branch"};
    If $t->leafFromNodes(28) > 0, Then {PrintOutStringNL "28 Leaf"}, Else {PrintOutStringNL "28 Branch"};


    ok Assemble eq => <<END, avx512=>1;
   zmm25: .... ..C0 .... ...9  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... ..33 .... ....
  b at offset 56 in zmm25: .... .... .... ...9
  ZF=1
  ZF=0
  ZF=1
  first  : .... .... .... ..40
  address: .... .... .... ..80
  1111
  Area     Size:     4096    Used:      320
  .... .... .... ...0 | __10 ____ ____ ____  40.1 ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 2222 ____ ____ ____  .1__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | ____ ____ 33__ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  .9__ ____ C0__ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ __.1 ____
   zmm31: .... ..C0 .... ...9  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... ..33 .... ....
   zmm30: .... .1.. .... ....  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0
   zmm29: .... ..40 .... ....  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0
   zmm28: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...1  .... .... .... 2222
  29 Leaf
  28 Branch
  END

Nasm::X86::Tree::freeBlock($tree, $k, $K, $D, $N)

Free a keys/data/node block whose keys block entry is located at the specified offset.

     Parameter  Description
  1  $tree      Tree descriptor
  2  $k         Offset of keys block
  3  $K         Numbered zmm for keys
  4  $D         Numbered zmm for data
  5  $N         Numbered zmm for children

Nasm::X86::Tree::upFromData($tree, $zmm, %options)

Up from the data zmm in a block in a tree.

     Parameter  Description
  1  $tree      Tree descriptor
  2  $zmm       Number of zmm containing data block
  3  %options   Options

Nasm::X86::Tree::upIntoData($tree, $value, $zmm)

Up into the data zmm in a block in a tree.

     Parameter  Description
  1  $tree      Tree descriptor
  2  $value     Variable containing value to put
  3  $zmm       Number of zmm containing first block

Nasm::X86::Tree::lengthFromKeys($t, $zmm, %options)

Get the length of the keys block in the numbered zmm and return it as a variable.

     Parameter  Description
  1  $t         Tree descriptor
  2  $zmm       Zmm number
  3  %options   Options

Nasm::X86::Tree::lengthIntoKeys($t, $zmm, $length)

Get the length of the block in the numbered zmm from the specified variable.

     Parameter  Description
  1  $t         Tree
  2  $zmm       Zmm number
  3  $length    Length variable

Nasm::X86::Tree::incLengthInKeys($t, $K)

Increment the number of keys in a keys block or complain if such is not possible.

     Parameter  Description
  1  $t         Tree
  2  $K         Zmm number

Nasm::X86::Tree::decLengthInKeys($t, $K)

Decrement the number of keys in a keys block or complain if such is not possible.

     Parameter  Description
  1  $t         Tree
  2  $K         Zmm number

Nasm::X86::Tree::leafFromNodes($tree, $zmm, %options)

Return a variable containing true if we are on a leaf. We determine whether we are on a leaf by checking the offset of the first sub node. If it is zero we are on a leaf otherwise not.

     Parameter  Description
  1  $tree      Tree descriptor
  2  $zmm       Number of zmm containing node block
  3  %options   Options

Nasm::X86::Tree::getLoop($t, $zmm, %options)

Return the value of the loop field as a variable.

     Parameter  Description
  1  $t         Tree descriptor
  2  $zmm       Numbered zmm
  3  %options   Options

Nasm::X86::Tree::putLoop($t, $value, $zmm)

Set the value of the loop field from a variable.

     Parameter  Description
  1  $t         Tree descriptor
  2  $value     Variable containing offset of next loop entry
  3  $zmm       Numbered zmm

Nasm::X86::Tree::maskForFullKeyArea()

Place a mask for the full key area in the numbered mask register.

Nasm::X86::Tree::maskForFullNodesArea()

Place a mask for the full nodes area in the numbered mask register.

Nasm::X86::Tree::getBlock($tree, $offset, $K, $D, $N)

Get the keys, data and child nodes for a tree node from the specified offset in the area for the tree.

     Parameter  Description
  1  $tree      Tree descriptor
  2  $offset    Offset of block as a variable
  3  $K         Numbered zmm for keys
  4  $D         Numbered data for keys
  5  $N         Numbered zmm for nodes

Example:

    my $a = CreateArea;
    my $t = $a->CreateTree;
    my $b = $t->allocBlock(31, 30, 29);
    K(data => 0x33)->dIntoZ(31, 4);
    $t->lengthIntoKeys(31, K length =>0x9);
    $t->putBlock($b, 31, 30, 29);
    $t->getBlock($b, 25, 24, 23);
    PrintOutRegisterInHex 25;
    $t->lengthFromKeys(25)->outNL;


    $t->firstFromMemory(28);
    $t->incSizeInFirst (28);
    $t->rootIntoFirst  (28, K value => 0x2222);
    $t->root           (28, K value => 0x2222);  PrintOutZF;
    $t->root           (28, K value => 0x2221);  PrintOutZF;
    $t->root           (28, K value => 0x2222);  PrintOutZF;
    $t->firstIntoMemory(28);

    $t->first->outNL;
    $b->outNL;
    $a->dump("1111");
    PrintOutRegisterInHex 31, 30, 29, 28;

    If $t->leafFromNodes(29) > 0, Then {PrintOutStringNL "29 Leaf"}, Else {PrintOutStringNL "29 Branch"};
    If $t->leafFromNodes(28) > 0, Then {PrintOutStringNL "28 Leaf"}, Else {PrintOutStringNL "28 Branch"};


    ok Assemble eq => <<END, avx512=>1;
   zmm25: .... ..C0 .... ...9  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... ..33 .... ....
  b at offset 56 in zmm25: .... .... .... ...9
  ZF=1
  ZF=0
  ZF=1
  first  : .... .... .... ..40
  address: .... .... .... ..80
  1111
  Area     Size:     4096    Used:      320
  .... .... .... ...0 | __10 ____ ____ ____  40.1 ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 2222 ____ ____ ____  .1__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | ____ ____ 33__ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  .9__ ____ C0__ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ __.1 ____
   zmm31: .... ..C0 .... ...9  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... ..33 .... ....
   zmm30: .... .1.. .... ....  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0
   zmm29: .... ..40 .... ....  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0
   zmm28: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...1  .... .... .... 2222
  29 Leaf
  28 Branch
  END

Nasm::X86::Tree::putBlock($t, $offset, $K, $D, $N)

Put a tree block held in three zmm registers back into the area holding the tree at the specified offset.

     Parameter  Description
  1  $t         Tree descriptor
  2  $offset    Offset of block as a variable
  3  $K         Numbered zmm for keys
  4  $D         Numbered data for keys
  5  $N         Numbered zmm for nodes

Example:

    my $a = CreateArea;
    my $t = $a->CreateTree;
    my $b = $t->allocBlock(31, 30, 29);
    K(data => 0x33)->dIntoZ(31, 4);
    $t->lengthIntoKeys(31, K length =>0x9);
    $t->putBlock($b, 31, 30, 29);
    $t->getBlock($b, 25, 24, 23);
    PrintOutRegisterInHex 25;
    $t->lengthFromKeys(25)->outNL;


    $t->firstFromMemory(28);
    $t->incSizeInFirst (28);
    $t->rootIntoFirst  (28, K value => 0x2222);
    $t->root           (28, K value => 0x2222);  PrintOutZF;
    $t->root           (28, K value => 0x2221);  PrintOutZF;
    $t->root           (28, K value => 0x2222);  PrintOutZF;
    $t->firstIntoMemory(28);

    $t->first->outNL;
    $b->outNL;
    $a->dump("1111");
    PrintOutRegisterInHex 31, 30, 29, 28;

    If $t->leafFromNodes(29) > 0, Then {PrintOutStringNL "29 Leaf"}, Else {PrintOutStringNL "29 Branch"};
    If $t->leafFromNodes(28) > 0, Then {PrintOutStringNL "28 Leaf"}, Else {PrintOutStringNL "28 Branch"};


    ok Assemble eq => <<END, avx512=>1;
   zmm25: .... ..C0 .... ...9  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... ..33 .... ....
  b at offset 56 in zmm25: .... .... .... ...9
  ZF=1
  ZF=0
  ZF=1
  first  : .... .... .... ..40
  address: .... .... .... ..80
  1111
  Area     Size:     4096    Used:      320
  .... .... .... ...0 | __10 ____ ____ ____  40.1 ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..40 | 2222 ____ ____ ____  .1__ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____
  .... .... .... ..80 | ____ ____ 33__ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  .9__ ____ C0__ ____
  .... .... .... ..C0 | ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ ____ ____  ____ ____ __.1 ____
   zmm31: .... ..C0 .... ...9  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... ..33 .... ....
   zmm30: .... .1.. .... ....  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0
   zmm29: .... ..40 .... ....  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0
   zmm28: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...1  .... .... .... 2222
  29 Leaf
  28 Branch
  END

Nasm::X86::Tree::firstNode($tree, $K, $D, $N)

Return as a variable the last node block in the specified tree node held in a zmm.

     Parameter  Description
  1  $tree      Tree definition
  2  $K         Key zmm
  3  $D         Data zmm
  4  $N         Node zmm for a node block

Example:

    my $a = CreateArea;
    my $t = $a->CreateTree;

    my ($K, $D, $N) = (31, 30, 29);

    K(K => Rd( 1..16))->loadZmm($K);
    K(K => Rd( 1..16))->loadZmm($N);

    $t->lengthIntoKeys($K, K length => $t->length);

    PrintOutRegisterInHex 31, 29;
    my $f = $t->firstNode($K, $D, $N);
    my $l = $t-> lastNode($K, $D, $N);
    $f->outNL;
    $l->outNL;

    ok Assemble eq => <<END, avx512=>1;
   zmm31: .... ..10 .... ...D  .... ...E .... ...D - .... ...C .... ...B  .... ...A .... ...9 + .... ...8 .... ...7  .... ...6 .... ...5 - .... ...4 .... ...3  .... ...2 .... ...1
   zmm29: .... ..10 .... ...F  .... ...E .... ...D - .... ...C .... ...B  .... ...A .... ...9 + .... ...8 .... ...7  .... ...6 .... ...5 - .... ...4 .... ...3  .... ...2 .... ...1
  d at offset 0 in zmm29: .... .... .... ...1
  d at offset (b at offset 56 in zmm31 times 4) in zmm29: .... .... .... ...E
  END

    my $a = CreateArea;
    my $t = $a->CreateTree;

    my ($K, $D, $N) = (31, 30, 29);

    K(K => Rd( 1..16))->loadZmm($K);
    K(K => Rd( 1..16))->loadZmm($N);

    $t->lengthIntoKeys($K, K length => $t->length);

    PrintOutRegisterInHex 31, 29;
    my $f = $t->firstNode($K, $D, $N);
    my $l = $t-> lastNode($K, $D, $N);
    $f->outNL;
    $l->outNL;

    ok Assemble eq => <<END, avx512=>1;
   zmm31: .... ..10 .... ...D  .... ...E .... ...D - .... ...C .... ...B  .... ...A .... ...9 + .... ...8 .... ...7  .... ...6 .... ...5 - .... ...4 .... ...3  .... ...2 .... ...1
   zmm29: .... ..10 .... ...F  .... ...E .... ...D - .... ...C .... ...B  .... ...A .... ...9 + .... ...8 .... ...7  .... ...6 .... ...5 - .... ...4 .... ...3  .... ...2 .... ...1
  d at offset 0 in zmm29: .... .... .... ...1
  d at offset (b at offset 56 in zmm31 times 4) in zmm29: .... .... .... ...E
  END

Nasm::X86::Tree::lastNode($tree, $K, $D, $N)

Return as a variable the last node block in the specified tree node held in a zmm.

     Parameter  Description
  1  $tree      Tree definition
  2  $K         Key zmm
  3  $D         Data zmm
  4  $N         Node zmm for a node block

Example:

    my $a = CreateArea;
    my $t = $a->CreateTree;

    my ($K, $D, $N) = (31, 30, 29);

    K(K => Rd( 1..16))->loadZmm($K);
    K(K => Rd( 1..16))->loadZmm($N);

    $t->lengthIntoKeys($K, K length => $t->length);

    PrintOutRegisterInHex 31, 29;
    my $f = $t->firstNode($K, $D, $N);
    my $l = $t-> lastNode($K, $D, $N);
    $f->outNL;
    $l->outNL;

    ok Assemble eq => <<END, avx512=>1;
   zmm31: .... ..10 .... ...D  .... ...E .... ...D - .... ...C .... ...B  .... ...A .... ...9 + .... ...8 .... ...7  .... ...6 .... ...5 - .... ...4 .... ...3  .... ...2 .... ...1
   zmm29: .... ..10 .... ...F  .... ...E .... ...D - .... ...C .... ...B  .... ...A .... ...9 + .... ...8 .... ...7  .... ...6 .... ...5 - .... ...4 .... ...3  .... ...2 .... ...1
  d at offset 0 in zmm29: .... .... .... ...1
  d at offset (b at offset 56 in zmm31 times 4) in zmm29: .... .... .... ...E
  END

    my $a = CreateArea;
    my $t = $a->CreateTree;

    my ($K, $D, $N) = (31, 30, 29);

    K(K => Rd( 1..16))->loadZmm($K);
    K(K => Rd( 1..16))->loadZmm($N);

    $t->lengthIntoKeys($K, K length => $t->length);

    PrintOutRegisterInHex 31, 29;
    my $f = $t->firstNode($K, $D, $N);
    my $l = $t-> lastNode($K, $D, $N);
    $f->outNL;
    $l->outNL;

    ok Assemble eq => <<END, avx512=>1;
   zmm31: .... ..10 .... ...D  .... ...E .... ...D - .... ...C .... ...B  .... ...A .... ...9 + .... ...8 .... ...7  .... ...6 .... ...5 - .... ...4 .... ...3  .... ...2 .... ...1
   zmm29: .... ..10 .... ...F  .... ...E .... ...D - .... ...C .... ...B  .... ...A .... ...9 + .... ...8 .... ...7  .... ...6 .... ...5 - .... ...4 .... ...3  .... ...2 .... ...1
  d at offset 0 in zmm29: .... .... .... ...1
  d at offset (b at offset 56 in zmm31 times 4) in zmm29: .... .... .... ...E
  END

Nasm::X86::Tree::relativeNode($tree, $offset, $relative, $K, $N)

Return as a variable a node offset relative (specified as ac constant) to another offset in the same node in the specified zmm.

     Parameter  Description
  1  $tree      Tree definition
  2  $offset    Offset
  3  $relative  Relative location
  4  $K         Key zmm
  5  $N         Node zmm

Nasm::X86::Tree::nextNode($tree, $offset, $K, $N)

Return as a variable the next node block offset after the specified one in the specified zmm.

     Parameter  Description
  1  $tree      Tree definition
  2  $offset    Offset
  3  $K         Key zmm
  4  $N         Node zmm

Example:

    my $a = CreateArea;
    my $t = $a->CreateTree;

    K(loop => 66)->for(sub
     {my ($index, $start, $next, $end) = @_;
      $t->put($index, 2 * $index);
     });
    $t->getBlock(K(offset=>0x200), 31, 30, 29);
    $t->nextNode(K(offset=>0x440), 31, 29)->outRightInHexNL(K width => 3);
    $t->prevNode(K(offset=>0x440), 31, 29)->outRightInHexNL(K width => 3);

    ok Assemble eq => <<END, avx512=>1;
  500
  380
  END

Nasm::X86::Tree::prevNode($tree, $offset, $K, $N)

Return as a variable the previous node block offset after the specified one in the specified zmm.

     Parameter  Description
  1  $tree      Tree definition
  2  $offset    Offset
  3  $K         Key zmm
  4  $N         Node zmm

Example:

    my $a = CreateArea;
    my $t = $a->CreateTree;

    K(loop => 66)->for(sub
     {my ($index, $start, $next, $end) = @_;
      $t->put($index, 2 * $index);
     });
    $t->getBlock(K(offset=>0x200), 31, 30, 29);
    $t->nextNode(K(offset=>0x440), 31, 29)->outRightInHexNL(K width => 3);
    $t->prevNode(K(offset=>0x440), 31, 29)->outRightInHexNL(K width => 3);

    ok Assemble eq => <<END, avx512=>1;
  500
  380
  END

Nasm::X86::Tree::indexNode($tree, $offset, $K, $N)

Return, as a variable, the point mask obtained by testing the nodes in a block for specified offset. We have to supply the keys as well so that we can find the number of nodes. We need the number of nodes so that we only search the valid area not all possible node positions in the zmm.

     Parameter  Description
  1  $tree      Tree definition
  2  $offset    Key as a variable
  3  $K         Zmm containing keys
  4  $N         Comparison from B<Vpcmp>

Nasm::X86::Tree::expand($tree, $offset)

Expand the node at the specified offset in the specified tree if it needs to be expanded and is not the root node (which cannot be expanded because it has no siblings to take substance from whereas as all other nodes do). Set tree.found to the offset of the left sibling if the node at the specified offset was merged into it and freed else set tree.found to zero.

     Parameter  Description
  1  $tree      Tree descriptor
  2  $offset    Offset of node block to expand

Nasm::X86::Tree::replace($tree, $point, $K, $D)

Replace the key/data/subTree at the specified point in the specified zmm with the values found in the tree key/data/sub tree fields.

     Parameter  Description
  1  $tree      Tree descriptor
  2  $point     Point at which to extract
  3  $K         Keys zmm
  4  $D         Data zmm

Example:

    my ($K, $D) = (31, 30);

    K(K => Rd(reverse 1..16))->loadZmm($K);
    K(K => Rd(reverse 1..16))->loadZmm($D);
    PrintOutStringNL "Start";
    PrintOutRegisterInHex $K, $D;

    my $a = CreateArea;
    my $t = $a->CreateTree;

    K(loop => 14)->for(sub
     {my ($index, $start, $next, $end) = @_;

      $t->key    ->copy($index);
      $t->data   ->copy($index * 2);
      $t->subTree->copy($index % 2);

      $t->replace(K(one=>1)<<$index, $K, $D);

      $index->outNL;
      PrintOutRegisterInHex $K, $D;
     });

    ok Assemble eq => <<END, avx512=>1;
  Start
   zmm31: .... ...1 .... ...2  .... ...3 .... ...4 - .... ...5 .... ...6  .... ...7 .... ...8 + .... ...9 .... ...A  .... ...B .... ...C - .... ...D .... ...E  .... ...F .... ..10
   zmm30: .... ...1 .... ...2  .... ...3 .... ...4 - .... ...5 .... ...6  .... ...7 .... ...8 + .... ...9 .... ...A  .... ...B .... ...C - .... ...D .... ...E  .... ...F .... ..10
  index: .... .... .... ...0
   zmm31: .... ...1 .... ...2  .... ...3 .... ...4 - .... ...5 .... ...6  .... ...7 .... ...8 + .... ...9 .... ...A  .... ...B .... ...C - .... ...D .... ...E  .... ...F .... ....
   zmm30: .... ...1 .... ...2  .... ...3 .... ...4 - .... ...5 .... ...6  .... ...7 .... ...8 + .... ...9 .... ...A  .... ...B .... ...C - .... ...D .... ...E  .... ...F .... ....
  index: .... .... .... ...1
   zmm31: .... ...1 ...2 ...2  .... ...3 .... ...4 - .... ...5 .... ...6  .... ...7 .... ...8 + .... ...9 .... ...A  .... ...B .... ...C - .... ...D .... ...E  .... ...1 .... ....
   zmm30: .... ...1 .... ...2  .... ...3 .... ...4 - .... ...5 .... ...6  .... ...7 .... ...8 + .... ...9 .... ...A  .... ...B .... ...C - .... ...D .... ...E  .... ...2 .... ....
  index: .... .... .... ...2
   zmm31: .... ...1 ...2 ...2  .... ...3 .... ...4 - .... ...5 .... ...6  .... ...7 .... ...8 + .... ...9 .... ...A  .... ...B .... ...C - .... ...D .... ...2  .... ...1 .... ....
   zmm30: .... ...1 .... ...2  .... ...3 .... ...4 - .... ...5 .... ...6  .... ...7 .... ...8 + .... ...9 .... ...A  .... ...B .... ...C - .... ...D .... ...4  .... ...2 .... ....
  index: .... .... .... ...3
   zmm31: .... ...1 ...A ...2  .... ...3 .... ...4 - .... ...5 .... ...6  .... ...7 .... ...8 + .... ...9 .... ...A  .... ...B .... ...C - .... ...3 .... ...2  .... ...1 .... ....
   zmm30: .... ...1 .... ...2  .... ...3 .... ...4 - .... ...5 .... ...6  .... ...7 .... ...8 + .... ...9 .... ...A  .... ...B .... ...C - .... ...6 .... ...4  .... ...2 .... ....
  index: .... .... .... ...4
   zmm31: .... ...1 ...A ...2  .... ...3 .... ...4 - .... ...5 .... ...6  .... ...7 .... ...8 + .... ...9 .... ...A  .... ...B .... ...4 - .... ...3 .... ...2  .... ...1 .... ....
   zmm30: .... ...1 .... ...2  .... ...3 .... ...4 - .... ...5 .... ...6  .... ...7 .... ...8 + .... ...9 .... ...A  .... ...B .... ...8 - .... ...6 .... ...4  .... ...2 .... ....
  index: .... .... .... ...5
   zmm31: .... ...1 ..2A ...2  .... ...3 .... ...4 - .... ...5 .... ...6  .... ...7 .... ...8 + .... ...9 .... ...A  .... ...5 .... ...4 - .... ...3 .... ...2  .... ...1 .... ....
   zmm30: .... ...1 .... ...2  .... ...3 .... ...4 - .... ...5 .... ...6  .... ...7 .... ...8 + .... ...9 .... ...A  .... ...A .... ...8 - .... ...6 .... ...4  .... ...2 .... ....
  index: .... .... .... ...6
   zmm31: .... ...1 ..2A ...2  .... ...3 .... ...4 - .... ...5 .... ...6  .... ...7 .... ...8 + .... ...9 .... ...6  .... ...5 .... ...4 - .... ...3 .... ...2  .... ...1 .... ....
   zmm30: .... ...1 .... ...2  .... ...3 .... ...4 - .... ...5 .... ...6  .... ...7 .... ...8 + .... ...9 .... ...C  .... ...A .... ...8 - .... ...6 .... ...4  .... ...2 .... ....
  index: .... .... .... ...7
   zmm31: .... ...1 ..AA ...2  .... ...3 .... ...4 - .... ...5 .... ...6  .... ...7 .... ...8 + .... ...7 .... ...6  .... ...5 .... ...4 - .... ...3 .... ...2  .... ...1 .... ....
   zmm30: .... ...1 .... ...2  .... ...3 .... ...4 - .... ...5 .... ...6  .... ...7 .... ...8 + .... ...E .... ...C  .... ...A .... ...8 - .... ...6 .... ...4  .... ...2 .... ....
  index: .... .... .... ...8
   zmm31: .... ...1 ..AA ...2  .... ...3 .... ...4 - .... ...5 .... ...6  .... ...7 .... ...8 + .... ...7 .... ...6  .... ...5 .... ...4 - .... ...3 .... ...2  .... ...1 .... ....
   zmm30: .... ...1 .... ...2  .... ...3 .... ...4 - .... ...5 .... ...6  .... ...7 .... ..10 + .... ...E .... ...C  .... ...A .... ...8 - .... ...6 .... ...4  .... ...2 .... ....
  index: .... .... .... ...9
   zmm31: .... ...1 .2AA ...2  .... ...3 .... ...4 - .... ...5 .... ...6  .... ...9 .... ...8 + .... ...7 .... ...6  .... ...5 .... ...4 - .... ...3 .... ...2  .... ...1 .... ....
   zmm30: .... ...1 .... ...2  .... ...3 .... ...4 - .... ...5 .... ...6  .... ..12 .... ..10 + .... ...E .... ...C  .... ...A .... ...8 - .... ...6 .... ...4  .... ...2 .... ....
  index: .... .... .... ...A
   zmm31: .... ...1 .2AA ...2  .... ...3 .... ...4 - .... ...5 .... ...A  .... ...9 .... ...8 + .... ...7 .... ...6  .... ...5 .... ...4 - .... ...3 .... ...2  .... ...1 .... ....
   zmm30: .... ...1 .... ...2  .... ...3 .... ...4 - .... ...5 .... ..14  .... ..12 .... ..10 + .... ...E .... ...C  .... ...A .... ...8 - .... ...6 .... ...4  .... ...2 .... ....
  index: .... .... .... ...B
   zmm31: .... ...1 .AAA ...2  .... ...3 .... ...4 - .... ...B .... ...A  .... ...9 .... ...8 + .... ...7 .... ...6  .... ...5 .... ...4 - .... ...3 .... ...2  .... ...1 .... ....
   zmm30: .... ...1 .... ...2  .... ...3 .... ...4 - .... ..16 .... ..14  .... ..12 .... ..10 + .... ...E .... ...C  .... ...A .... ...8 - .... ...6 .... ...4  .... ...2 .... ....
  index: .... .... .... ...C
   zmm31: .... ...1 .AAA ...2  .... ...3 .... ...C - .... ...B .... ...A  .... ...9 .... ...8 + .... ...7 .... ...6  .... ...5 .... ...4 - .... ...3 .... ...2  .... ...1 .... ....
   zmm30: .... ...1 .... ...2  .... ...3 .... ..18 - .... ..16 .... ..14  .... ..12 .... ..10 + .... ...E .... ...C  .... ...A .... ...8 - .... ...6 .... ...4  .... ...2 .... ....
  index: .... .... .... ...D
   zmm31: .... ...1 2AAA ...2  .... ...D .... ...C - .... ...B .... ...A  .... ...9 .... ...8 + .... ...7 .... ...6  .... ...5 .... ...4 - .... ...3 .... ...2  .... ...1 .... ....
   zmm30: .... ...1 .... ...2  .... ..1A .... ..18 - .... ..16 .... ..14  .... ..12 .... ..10 + .... ...E .... ...C  .... ...A .... ...8 - .... ...6 .... ...4  .... ...2 .... ....
  END

Nasm::X86::Tree::overWriteKeyDataTreeInLeaf($tree, $point, $K, $D, $IK, $ID, $subTree)

Over write an existing key/data/sub tree triple in a set of zmm registers and set the tree bit as indicated.

     Parameter  Description
  1  $tree      Tree descriptor
  2  $point     Register point at which to overwrite formatted as a one in a sea of zeros
  3  $K         Key
  4  $D         Data
  5  $IK        Insert key
  6  $ID        Insert data
  7  $subTree   Sub tree if tree.

Nasm::X86::Tree::indexXX($tree, $key, $K, $cmp, $inc, %options)

Return, as a variable, the mask obtained by performing a specified comparison on the key area of a node against a specified key.

     Parameter  Description
  1  $tree      Tree definition
  2  $key       Key to search for as a variable or a zmm containing a copy of the key to be searched for in each slot
  3  $K         Zmm containing keys
  4  $cmp       Comparison from B<Vpcmp>
  5  $inc       Whether to increment the result by one
  6  %options   Options

Nasm::X86::Tree::indexEq($tree, $key, $K, %options)

Return the position of a key in a zmm equal to the specified key as a point in a variable.

     Parameter  Description
  1  $tree      Tree definition
  2  $key       Key as a variable
  3  $K         Zmm containing keys
  4  %options   Options

Example:

    my $tree = DescribeTree;

    my $K = 31;

    K(K => Rd(0..15))->loadZmm($K);
    $tree->lengthIntoKeys($K, K length => 13);

    K(loop => 16)->for(sub
     {my ($index, $start, $next, $end) = @_;
      my $f = $tree->indexEq ($index, $K);
      $index->outRightInDec( 2);
      $f    ->outRightInBin(14);
      PrintOutStringNL " |"
     });

    ok Assemble eq => <<END, avx512=>1;
   0             1 |
   1            10 |
   2           100 |
   3          1000 |
   4         10000 |
   5        100000 |
   6       1000000 |
   7      10000000 |
   8     100000000 |
   9    1000000000 |
  10   10000000000 |
  11  100000000000 |
  12 1000000000000 |
  13               |
  14               |
  15               |
  END

    my $tree = DescribeTree();
    $tree->maskForFullKeyArea(7);                                                 # Mask for full key area
    PrintOutRegisterInHex k7;
    $tree->maskForFullNodesArea(7);                                               # Mask for full nodes area
    PrintOutRegisterInHex k7;
    ok Assemble eq => <<END, avx512=>1;
      k7: .... .... .... 3FFF
      k7: .... .... .... 7FFF
  END

Nasm::X86::Tree::insertionPoint($tree, $key, $K, %options)

Return the position at which a key should be inserted into a zmm as a point in a variable.

     Parameter  Description
  1  $tree      Tree definition
  2  $key       Key as a variable
  3  $K         Zmm containing keys
  4  %options   Options

Example:

    my $tree = DescribeTree(length => 7);

    my $K = 31;

    K(K => Rd(map {2*$_} 1..16))->loadZmm($K);
    $tree->lengthIntoKeys($K, K length => 13);

    K(loop => 32)->for(sub
     {my ($index, $start, $next, $end) = @_;
      my $f = $tree->insertionPoint($index, $K);
      $index->outRightInDec( 2);
      $f    ->outRightInBin(16);
      PrintOutStringNL " |"
     });

    ok Assemble eq => <<END, avx512=>1;
   0               1 |
   1               1 |
   2              10 |
   3              10 |
   4             100 |
   5             100 |
   6            1000 |
   7            1000 |
   8           10000 |
   9           10000 |
  10          100000 |
  11          100000 |
  12         1000000 |
  13         1000000 |
  14        10000000 |
  15        10000000 |
  16       100000000 |
  17       100000000 |
  18      1000000000 |
  19      1000000000 |
  20     10000000000 |
  21     10000000000 |
  22    100000000000 |
  23    100000000000 |
  24   1000000000000 |
  25   1000000000000 |
  26  10000000000000 |
  27  10000000000000 |
  28  10000000000000 |
  29  10000000000000 |
  30  10000000000000 |
  31  10000000000000 |
  END

Nasm::X86::Tree::indexEqLt($tree, $key, $K, $setEq, $setLt)

Set the specified registers with the equals point and the insertion point for the specified key in the specified zmm.

     Parameter  Description
  1  $tree      Tree definition
  2  $key       Zmm containing a copy of the key to be searched for in each slot
  3  $K         Zmm to check
  4  $setEq     Bound register to set with equals point
  5  $setLt     Bound register to set with insertion point.

Example:

    my $tree = DescribeTree;

    my $K = 31, my $key = 30;

    K(K => Rd(0..15))->loadZmm($K);
    $tree->lengthIntoKeys($K, K length => 13);

    K(loop => 16)->for(sub
     {my ($index, $start, $next, $end) = @_;
      $index->setReg(rdi);
      Vpbroadcastd zmm($key), edi;

      $tree->indexEqLt ($key, $K, r15, r14);
      Pushfq;
      my $f = V key => r15;
      $index->outRightInDec( 2);
      $f    ->outRightInBin(14);
      PrintOutString   " ";
      Popfq;
      PrintOutZF;
     });

    ok Assemble eq => <<END, avx512=>1;
   0             1 ZF=0
   1            10 ZF=0
   2           100 ZF=0
   3          1000 ZF=0
   4         10000 ZF=0
   5        100000 ZF=0
   6       1000000 ZF=0
   7      10000000 ZF=0
   8     100000000 ZF=0
   9    1000000000 ZF=0
  10   10000000000 ZF=0
  11  100000000000 ZF=0
  12 1000000000000 ZF=0
  13               ZF=1
  14               ZF=1
  15               ZF=1
  END

Nasm::X86::Tree::insertKeyDataTreeIntoLeaf($tree, $point, $F, $K, $D, $IK, $ID, $subTree)

Insert a new key/data/sub tree triple into a set of zmm registers if there is room, increment the length of the node and set the tree bit as indicated and increment the number of elements in the tree.

     Parameter  Description
  1  $tree      Tree descriptor
  2  $point     Register point at which to insert formatted as a one in a sea of zeros
  3  $F         First
  4  $K         Key
  5  $D         Data
  6  $IK        Insert key
  7  $ID        Insert data
  8  $subTree   Sub tree if tree.

Nasm::X86::Tree::splitNode($tree, $offset)

Split a node if it it is full returning a variable that indicates whether a split occurred or not.

     Parameter  Description
  1  $tree      Tree descriptor
  2  $offset    Offset of block in area of tree as a variable

Nasm::X86::Tree::splitNotRoot($tree, $newRight, $PK, $PD, $PN, $LK, $LD, $LN, $RK, $RD, $RN)

Split a non root left node pushing its excess right and up.

      Parameter  Description
   1  $tree      Tree definition
   2  $newRight  Variable offset in area of right node block
   3  $PK        Parent keys zmm
   4  $PD        Data zmm
   5  $PN        Nodes zmm
   6  $LK        Left keys zmm
   7  $LD        Data zmm
   8  $LN        Nodes zmm
   9  $RK        Right keys
  10  $RD        Data
  11  $RN        Node zmm

Nasm::X86::Tree::splitRoot($tree, $nLeft, $nRight, $PK, $PD, $PN, $LK, $LD, $LN, $RK, $RD, $RN)

Split a non root node into left and right nodes with the left half left in the left node and splitting key/data pushed into the parent node with the remainder pushed into the new right node.

      Parameter  Description
   1  $tree      Tree definition
   2  $nLeft     Variable offset in area of new left node block
   3  $nRight    Variable offset in area of new right node block
   4  $PK        Parent keys zmm
   5  $PD        Data zmm
   6  $PN        Nodes zmm
   7  $LK        Left keys zmm
   8  $LD        Data zmm
   9  $LN        Nodes zmm
  10  $RK        Right keys
  11  $RD        Data
  12  $RN        Nodes zmm

Nasm::X86::Tree::zero($tree)

Zero the return fields of a tree descriptor.

     Parameter  Description
  1  $tree      Tree descriptor

Nasm::X86::Tree::findAndReload($t, $key)

Find a key in the specified tree and clone it is it is a sub tree.

     Parameter  Description
  1  $t         Tree descriptor
  2  $key       Key as a dword

Nasm::X86::Tree::leftOrRightMost($tree, $dir, $node, $offset)

Return the offset of the left most or right most node.

     Parameter  Description
  1  $tree      Tree descriptor
  2  $dir       Direction: left = 0 or right = 1
  3  $node      Start node
  4  $offset    Offset of located node

Nasm::X86::Tree::leftMost($t, $node, $offset)

Return the offset of the left most node from the specified node.

     Parameter  Description
  1  $t         Tree descriptor
  2  $node      Start node
  3  $offset    Returned offset

Nasm::X86::Tree::rightMost($t, $node, $offset)

Return the offset of the left most node from the specified node.

     Parameter  Description
  1  $t         Tree descriptor
  2  $node      Start node
  3  $offset    Returned offset

Nasm::X86::Tree::depth($tree, $node)

Return the depth of a node within a tree.

     Parameter  Description
  1  $tree      Tree descriptor
  2  $node      Node

Nasm::X86::Tree::isTree($t, $zmm, $point)

Set the Zero Flag to oppose the tree bit in the numbered zmm register holding the keys of a node to indicate whether the data element indicated by the specified register is an offset to a sub tree in the containing area or not.

     Parameter  Description
  1  $t         Tree descriptor
  2  $zmm       Numbered zmm register holding the keys for a node in the tree
  3  $point     Register showing point to test

Example:

    my $t = DescribeTree;
    Mov r8, 0b100; $t->setTreeBit(31, r8);              PrintOutRegisterInHex 31;
    Mov r8, 0b010; $t->setTreeBit(31, r8);              PrintOutRegisterInHex 31;
    Mov r8, 0b001; $t->setTreeBit(31, r8);              PrintOutRegisterInHex 31;
    Mov r8, 0b010; $t->clearTreeBit(31, r8);            PrintOutRegisterInHex 31;

                                                       $t->getTreeBits(31, r8); V(TreeBits => r8)->outRightInBinNL(16);
    Mov r8, 0b010; $t->insertZeroIntoTreeBits(31, r8); $t->getTreeBits(31, r8); V(TreeBits => r8)->outRightInBinNL(16);
    Mov r8, 0b010; $t->insertOneIntoTreeBits (31, r8); $t->getTreeBits(31, r8); V(TreeBits => r8)->outRightInBinNL(16);

    $t->getTreeBits(31, r8);
    V(TreeBits => r8)->outRightInHexNL(4);
    PrintOutRegisterInHex 31;

    Mov r8, 1; $t->isTree(31, r8); PrintOutZF;
    Shl r8, 1; $t->isTree(31, r8); PrintOutZF;
    Shl r8, 1; $t->isTree(31, r8); PrintOutZF;
    Shl r8, 1; $t->isTree(31, r8); PrintOutZF;

    Shl r8, 1; $t->isTree(31, r8); PrintOutZF;
    Shl r8, 1; $t->isTree(31, r8); PrintOutZF;
    Shl r8, 1; $t->isTree(31, r8); PrintOutZF;
    Shl r8, 1; $t->isTree(31, r8); PrintOutZF;

    Shl r8, 1; $t->isTree(31, r8); PrintOutZF;
    Shl r8, 1; $t->isTree(31, r8); PrintOutZF;
    Shl r8, 1; $t->isTree(31, r8); PrintOutZF;
    Shl r8, 1; $t->isTree(31, r8); PrintOutZF;

    Shl r8, 1; $t->isTree(31, r8); PrintOutZF;
    Shl r8, 1; $t->isTree(31, r8); PrintOutZF;
    Shl r8, 1; $t->isTree(31, r8); PrintOutZF;
    Shl r8, 1; $t->isTree(31, r8); PrintOutZF;

    Not r8; $t->setTreeBits(31, r8); PrintOutRegisterInHex 31;

    ok Assemble eq => <<END, avx512=>1;
   zmm31: .... .... ...4 ....  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0
   zmm31: .... .... ...6 ....  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0
   zmm31: .... .... ...7 ....  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0
   zmm31: .... .... ...5 ....  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0
               101
              1001
             10011
    13
   zmm31: .... .... ..13 ....  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0
  ZF=0
  ZF=0
  ZF=1
  ZF=1
  ZF=0
  ZF=1
  ZF=1
  ZF=1
  ZF=1
  ZF=1
  ZF=1
  ZF=1
  ZF=1
  ZF=1
  ZF=1
  ZF=1
   zmm31: .... .... 3FFF ....  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0
  END

Nasm::X86::Tree::getTreeBit($t, $zmm, $point, %options)

Get the tree bit from the numbered zmm at the specified point and return it in a variable as a one or a zero.

     Parameter  Description
  1  $t         Tree descriptor
  2  $zmm       Register showing point to test
  3  $point     Numbered zmm register holding the keys for a node in the tree
  4  %options   Options

Nasm::X86::Tree::setOrClearTreeBit($t, $set, $point, $zmm)

Set or clear the tree bit selected by the specified point in the numbered zmm register holding the keys of a node to indicate that the data element indicated by the specified register is an offset to a sub tree in the containing area.

     Parameter  Description
  1  $t         Tree descriptor
  2  $set       Set if true else clear
  3  $point     Register holding point to set
  4  $zmm       Numbered zmm register holding the keys for a node in the tree

Nasm::X86::Tree::setTreeBit($t, $zmm, $point)

Set the tree bit in the numbered zmm register holding the keys of a node to indicate that the data element indexed by the specified register is an offset to a sub tree in the containing area.

     Parameter  Description
  1  $t         Tree descriptor
  2  $zmm       Numbered zmm register holding the keys for a node in the tree
  3  $point     Register holding the point to clear

Nasm::X86::Tree::clearTreeBit($t, $zmm, $point)

Clear the tree bit in the numbered zmm register holding the keys of a node to indicate that the data element indexed by the specified register is an offset to a sub tree in the containing area.

     Parameter  Description
  1  $t         Tree descriptor
  2  $zmm       Numbered zmm register holding the keys for a node in the tree
  3  $point     Register holding register holding the point to set

Nasm::X86::Tree::setOrClearTreeBitToMatchContent($t, $zmm, $point, $content)

Set or clear the tree bit pointed to by the specified register depending on the content of the specified variable.

     Parameter  Description
  1  $t         Tree descriptor
  2  $zmm       Numbered keys zmm
  3  $point     Register indicating point
  4  $content   Content indicating zero or one

Nasm::X86::Tree::getTreeBits($t, $zmm, $register)

Load the tree bits from the numbered zmm into the specified register.

     Parameter  Description
  1  $t         Tree descriptor
  2  $zmm       Numbered zmm
  3  $register  Target register

Example:

    my $t = DescribeTree;
    Mov r8, 0b100; $t->setTreeBit(31, r8);              PrintOutRegisterInHex 31;
    Mov r8, 0b010; $t->setTreeBit(31, r8);              PrintOutRegisterInHex 31;
    Mov r8, 0b001; $t->setTreeBit(31, r8);              PrintOutRegisterInHex 31;
    Mov r8, 0b010; $t->clearTreeBit(31, r8);            PrintOutRegisterInHex 31;

                                                       $t->getTreeBits(31, r8); V(TreeBits => r8)->outRightInBinNL(16);
    Mov r8, 0b010; $t->insertZeroIntoTreeBits(31, r8); $t->getTreeBits(31, r8); V(TreeBits => r8)->outRightInBinNL(16);
    Mov r8, 0b010; $t->insertOneIntoTreeBits (31, r8); $t->getTreeBits(31, r8); V(TreeBits => r8)->outRightInBinNL(16);

    $t->getTreeBits(31, r8);
    V(TreeBits => r8)->outRightInHexNL(4);
    PrintOutRegisterInHex 31;

    Mov r8, 1; $t->isTree(31, r8); PrintOutZF;
    Shl r8, 1; $t->isTree(31, r8); PrintOutZF;
    Shl r8, 1; $t->isTree(31, r8); PrintOutZF;
    Shl r8, 1; $t->isTree(31, r8); PrintOutZF;

    Shl r8, 1; $t->isTree(31, r8); PrintOutZF;
    Shl r8, 1; $t->isTree(31, r8); PrintOutZF;
    Shl r8, 1; $t->isTree(31, r8); PrintOutZF;
    Shl r8, 1; $t->isTree(31, r8); PrintOutZF;

    Shl r8, 1; $t->isTree(31, r8); PrintOutZF;
    Shl r8, 1; $t->isTree(31, r8); PrintOutZF;
    Shl r8, 1; $t->isTree(31, r8); PrintOutZF;
    Shl r8, 1; $t->isTree(31, r8); PrintOutZF;

    Shl r8, 1; $t->isTree(31, r8); PrintOutZF;
    Shl r8, 1; $t->isTree(31, r8); PrintOutZF;
    Shl r8, 1; $t->isTree(31, r8); PrintOutZF;
    Shl r8, 1; $t->isTree(31, r8); PrintOutZF;

    Not r8; $t->setTreeBits(31, r8); PrintOutRegisterInHex 31;

    ok Assemble eq => <<END, avx512=>1;
   zmm31: .... .... ...4 ....  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0
   zmm31: .... .... ...6 ....  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0
   zmm31: .... .... ...7 ....  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0
   zmm31: .... .... ...5 ....  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0
               101
              1001
             10011
    13
   zmm31: .... .... ..13 ....  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0
  ZF=0
  ZF=0
  ZF=1
  ZF=1
  ZF=0
  ZF=1
  ZF=1
  ZF=1
  ZF=1
  ZF=1
  ZF=1
  ZF=1
  ZF=1
  ZF=1
  ZF=1
  ZF=1
   zmm31: .... .... 3FFF ....  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0
  END

Nasm::X86::Tree::setTreeBits($t, $zmm, $register)

Put the tree bits in the specified register into the numbered zmm.

     Parameter  Description
  1  $t         Tree descriptor
  2  $zmm       Numbered zmm
  3  $register  Target register

Example:

    my $t = DescribeTree;
    Mov r8, 0b100; $t->setTreeBit(31, r8);              PrintOutRegisterInHex 31;
    Mov r8, 0b010; $t->setTreeBit(31, r8);              PrintOutRegisterInHex 31;
    Mov r8, 0b001; $t->setTreeBit(31, r8);              PrintOutRegisterInHex 31;
    Mov r8, 0b010; $t->clearTreeBit(31, r8);            PrintOutRegisterInHex 31;

                                                       $t->getTreeBits(31, r8); V(TreeBits => r8)->outRightInBinNL(16);
    Mov r8, 0b010; $t->insertZeroIntoTreeBits(31, r8); $t->getTreeBits(31, r8); V(TreeBits => r8)->outRightInBinNL(16);
    Mov r8, 0b010; $t->insertOneIntoTreeBits (31, r8); $t->getTreeBits(31, r8); V(TreeBits => r8)->outRightInBinNL(16);

    $t->getTreeBits(31, r8);
    V(TreeBits => r8)->outRightInHexNL(4);
    PrintOutRegisterInHex 31;

    Mov r8, 1; $t->isTree(31, r8); PrintOutZF;
    Shl r8, 1; $t->isTree(31, r8); PrintOutZF;
    Shl r8, 1; $t->isTree(31, r8); PrintOutZF;
    Shl r8, 1; $t->isTree(31, r8); PrintOutZF;

    Shl r8, 1; $t->isTree(31, r8); PrintOutZF;
    Shl r8, 1; $t->isTree(31, r8); PrintOutZF;
    Shl r8, 1; $t->isTree(31, r8); PrintOutZF;
    Shl r8, 1; $t->isTree(31, r8); PrintOutZF;

    Shl r8, 1; $t->isTree(31, r8); PrintOutZF;
    Shl r8, 1; $t->isTree(31, r8); PrintOutZF;
    Shl r8, 1; $t->isTree(31, r8); PrintOutZF;
    Shl r8, 1; $t->isTree(31, r8); PrintOutZF;

    Shl r8, 1; $t->isTree(31, r8); PrintOutZF;
    Shl r8, 1; $t->isTree(31, r8); PrintOutZF;
    Shl r8, 1; $t->isTree(31, r8); PrintOutZF;
    Shl r8, 1; $t->isTree(31, r8); PrintOutZF;

    Not r8; $t->setTreeBits(31, r8); PrintOutRegisterInHex 31;

    ok Assemble eq => <<END, avx512=>1;
   zmm31: .... .... ...4 ....  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0
   zmm31: .... .... ...6 ....  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0
   zmm31: .... .... ...7 ....  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0
   zmm31: .... .... ...5 ....  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0
               101
              1001
             10011
    13
   zmm31: .... .... ..13 ....  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0
  ZF=0
  ZF=0
  ZF=1
  ZF=1
  ZF=0
  ZF=1
  ZF=1
  ZF=1
  ZF=1
  ZF=1
  ZF=1
  ZF=1
  ZF=1
  ZF=1
  ZF=1
  ZF=1
   zmm31: .... .... 3FFF ....  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0
  END

Nasm::X86::Tree::insertTreeBit($t, $onz, $zmm, $point)

Insert a zero or one into the tree bits field in the numbered zmm at the specified point moving the bits at and beyond point one position to the right.

     Parameter  Description
  1  $t         Tree descriptor
  2  $onz       0 - zero or 1 - one
  3  $zmm       Numbered zmm
  4  $point     Register indicating point

Nasm::X86::Tree::insertZeroIntoTreeBits($t, $zmm, $point)

Insert a zero into the tree bits field in the numbered zmm at the specified point moving the bits at and beyond point one position to the right.

     Parameter  Description
  1  $t         Tree descriptor
  2  $zmm       Numbered zmm
  3  $point     Register indicating point

Example:

    my $t = DescribeTree;
    Mov r8, 0b100; $t->setTreeBit(31, r8);              PrintOutRegisterInHex 31;
    Mov r8, 0b010; $t->setTreeBit(31, r8);              PrintOutRegisterInHex 31;
    Mov r8, 0b001; $t->setTreeBit(31, r8);              PrintOutRegisterInHex 31;
    Mov r8, 0b010; $t->clearTreeBit(31, r8);            PrintOutRegisterInHex 31;

                                                       $t->getTreeBits(31, r8); V(TreeBits => r8)->outRightInBinNL(16);
    Mov r8, 0b010; $t->insertZeroIntoTreeBits(31, r8); $t->getTreeBits(31, r8); V(TreeBits => r8)->outRightInBinNL(16);
    Mov r8, 0b010; $t->insertOneIntoTreeBits (31, r8); $t->getTreeBits(31, r8); V(TreeBits => r8)->outRightInBinNL(16);

    $t->getTreeBits(31, r8);
    V(TreeBits => r8)->outRightInHexNL(4);
    PrintOutRegisterInHex 31;

    Mov r8, 1; $t->isTree(31, r8); PrintOutZF;
    Shl r8, 1; $t->isTree(31, r8); PrintOutZF;
    Shl r8, 1; $t->isTree(31, r8); PrintOutZF;
    Shl r8, 1; $t->isTree(31, r8); PrintOutZF;

    Shl r8, 1; $t->isTree(31, r8); PrintOutZF;
    Shl r8, 1; $t->isTree(31, r8); PrintOutZF;
    Shl r8, 1; $t->isTree(31, r8); PrintOutZF;
    Shl r8, 1; $t->isTree(31, r8); PrintOutZF;

    Shl r8, 1; $t->isTree(31, r8); PrintOutZF;
    Shl r8, 1; $t->isTree(31, r8); PrintOutZF;
    Shl r8, 1; $t->isTree(31, r8); PrintOutZF;
    Shl r8, 1; $t->isTree(31, r8); PrintOutZF;

    Shl r8, 1; $t->isTree(31, r8); PrintOutZF;
    Shl r8, 1; $t->isTree(31, r8); PrintOutZF;
    Shl r8, 1; $t->isTree(31, r8); PrintOutZF;
    Shl r8, 1; $t->isTree(31, r8); PrintOutZF;

    Not r8; $t->setTreeBits(31, r8); PrintOutRegisterInHex 31;

    ok Assemble eq => <<END, avx512=>1;
   zmm31: .... .... ...4 ....  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0
   zmm31: .... .... ...6 ....  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0
   zmm31: .... .... ...7 ....  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0
   zmm31: .... .... ...5 ....  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0
               101
              1001
             10011
    13
   zmm31: .... .... ..13 ....  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0
  ZF=0
  ZF=0
  ZF=1
  ZF=1
  ZF=0
  ZF=1
  ZF=1
  ZF=1
  ZF=1
  ZF=1
  ZF=1
  ZF=1
  ZF=1
  ZF=1
  ZF=1
  ZF=1
   zmm31: .... .... 3FFF ....  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0
  END

Nasm::X86::Tree::insertOneIntoTreeBits($t, $zmm, $point)

Insert a one into the tree bits field in the numbered zmm at the specified point moving the bits at and beyond point one position to the right.

     Parameter  Description
  1  $t         Tree descriptor
  2  $zmm       Numbered zmm
  3  $point     Register indicating point

Example:

    my $t = DescribeTree;
    Mov r8, 0b100; $t->setTreeBit(31, r8);              PrintOutRegisterInHex 31;
    Mov r8, 0b010; $t->setTreeBit(31, r8);              PrintOutRegisterInHex 31;
    Mov r8, 0b001; $t->setTreeBit(31, r8);              PrintOutRegisterInHex 31;
    Mov r8, 0b010; $t->clearTreeBit(31, r8);            PrintOutRegisterInHex 31;

                                                       $t->getTreeBits(31, r8); V(TreeBits => r8)->outRightInBinNL(16);
    Mov r8, 0b010; $t->insertZeroIntoTreeBits(31, r8); $t->getTreeBits(31, r8); V(TreeBits => r8)->outRightInBinNL(16);
    Mov r8, 0b010; $t->insertOneIntoTreeBits (31, r8); $t->getTreeBits(31, r8); V(TreeBits => r8)->outRightInBinNL(16);

    $t->getTreeBits(31, r8);
    V(TreeBits => r8)->outRightInHexNL(4);
    PrintOutRegisterInHex 31;

    Mov r8, 1; $t->isTree(31, r8); PrintOutZF;
    Shl r8, 1; $t->isTree(31, r8); PrintOutZF;
    Shl r8, 1; $t->isTree(31, r8); PrintOutZF;
    Shl r8, 1; $t->isTree(31, r8); PrintOutZF;

    Shl r8, 1; $t->isTree(31, r8); PrintOutZF;
    Shl r8, 1; $t->isTree(31, r8); PrintOutZF;
    Shl r8, 1; $t->isTree(31, r8); PrintOutZF;
    Shl r8, 1; $t->isTree(31, r8); PrintOutZF;

    Shl r8, 1; $t->isTree(31, r8); PrintOutZF;
    Shl r8, 1; $t->isTree(31, r8); PrintOutZF;
    Shl r8, 1; $t->isTree(31, r8); PrintOutZF;
    Shl r8, 1; $t->isTree(31, r8); PrintOutZF;

    Shl r8, 1; $t->isTree(31, r8); PrintOutZF;
    Shl r8, 1; $t->isTree(31, r8); PrintOutZF;
    Shl r8, 1; $t->isTree(31, r8); PrintOutZF;
    Shl r8, 1; $t->isTree(31, r8); PrintOutZF;

    Not r8; $t->setTreeBits(31, r8); PrintOutRegisterInHex 31;

    ok Assemble eq => <<END, avx512=>1;
   zmm31: .... .... ...4 ....  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0
   zmm31: .... .... ...6 ....  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0
   zmm31: .... .... ...7 ....  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0
   zmm31: .... .... ...5 ....  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0
               101
              1001
             10011
    13
   zmm31: .... .... ..13 ....  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0
  ZF=0
  ZF=0
  ZF=1
  ZF=1
  ZF=0
  ZF=1
  ZF=1
  ZF=1
  ZF=1
  ZF=1
  ZF=1
  ZF=1
  ZF=1
  ZF=1
  ZF=1
  ZF=1
   zmm31: .... .... 3FFF ....  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0
  END

Nasm::X86::Tree::insertIntoTreeBits($t, $zmm, $point, $content)

Insert a one into the tree bits field in the numbered zmm at the specified point moving the bits at and beyond point one position to the right.

     Parameter  Description
  1  $t         Tree descriptor
  2  $zmm       Numbered zmm
  3  $point     Register indicating point
  4  $content   Bit to insert

Nasm::X86::Tree::extract($tree, $point, $K, $D, $N)

Extract the key/data/node and tree bit at the specified point from the block held in the specified zmm registers.

     Parameter  Description
  1  $tree      Tree descriptor
  2  $point     Point at which to extract
  3  $K         Keys zmm
  4  $D         Data zmm
  5  $N         Node zmm

Example:

    my ($K, $D, $N) = (31, 30, 29);

    K(K => Rd( 1..16))->loadZmm($K);
    K(K => Rd( 1..16))->loadZmm($D);
    K(K => Rd(map {0} 1..16))->loadZmm($N);

    my $a = CreateArea;
    my $t = $a->CreateTree;

    my $p = K(one => 1) << K three => 3;
    Mov r15, 0xAAAA;
    $t->setTreeBits($K, r15);

    PrintOutStringNL "Start";
    PrintOutRegisterInHex 31, 30, 29;

    $t->extract($p, $K, $D, $N);

    PrintOutStringNL "Finish";
    PrintOutRegisterInHex 31, 30, 29;

    ok Assemble eq => <<END, avx512=>1;
  Start
   zmm31: .... ..10 2AAA ...F  .... ...E .... ...D - .... ...C .... ...B  .... ...A .... ...9 + .... ...8 .... ...7  .... ...6 .... ...5 - .... ...4 .... ...3  .... ...2 .... ...1
   zmm30: .... ..10 .... ...F  .... ...E .... ...D - .... ...C .... ...B  .... ...A .... ...9 + .... ...8 .... ...7  .... ...6 .... ...5 - .... ...4 .... ...3  .... ...2 .... ...1
   zmm29: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0
  Finish
   zmm31: .... ..10 2AAA ...E  .... ...E .... ...E - .... ...D .... ...C  .... ...B .... ...A + .... ...9 .... ...8  .... ...7 .... ...6 - .... ...5 .... ...3  .... ...2 .... ...1
   zmm30: .... ..10 .... ...F  .... ...E .... ...E - .... ...D .... ...C  .... ...B .... ...A + .... ...9 .... ...8  .... ...7 .... ...6 - .... ...5 .... ...3  .... ...2 .... ...1
   zmm29: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0
  END

Nasm::X86::Tree::extractFirst($tree, $K, $D, $N)

Extract the first key/data and tree bit at the specified point from the block held in the specified zmm registers and place the extracted data/bit in tree data/subTree.

     Parameter  Description
  1  $tree      Tree descriptor
  2  $K         Keys zmm
  3  $D         Data zmm
  4  $N         Node zmm

Example:

    my ($K, $D, $N) = (31, 30, 29);

    K(K => Rd( 1..16))       ->loadZmm($K);
    K(K => Rd( 1..16))       ->loadZmm($D);
    K(K => Rd(map {0} 1..16))->loadZmm($N);

    my $a = CreateArea;
    my $t = $a->CreateTree;

    my $p = K(one => 1) << K three => 3;
    Mov r15, 0xAAAA;
    $t->setTreeBits($K, r15);

    PrintOutStringNL "Start";
    PrintOutRegisterInHex 31, 30, 29;

    K(n=>4)->for(sub
     {my ($index, $start, $next, $end) = @_;

      $t->extractFirst($K, $D, $N);

      PrintOutStringNL "-------------";
      $index->outNL;
      PrintOutRegisterInHex 31, 30, 29;

      $t->data->outNL;
      $t->subTree->outNL;
      $t->lengthFromKeys($K)->outNL;
     });

    ok Assemble eq => <<END, avx512=>1;
  Start
   zmm31: .... ..10 2AAA ...F  .... ...E .... ...D - .... ...C .... ...B  .... ...A .... ...9 + .... ...8 .... ...7  .... ...6 .... ...5 - .... ...4 .... ...3  .... ...2 .... ...1
   zmm30: .... ..10 .... ...F  .... ...E .... ...D - .... ...C .... ...B  .... ...A .... ...9 + .... ...8 .... ...7  .... ...6 .... ...5 - .... ...4 .... ...3  .... ...2 .... ...1
   zmm29: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0
  -------------
  index: .... .... .... ...0
   zmm31: .... ..10 1555 ...E  .... ...E .... ...E - .... ...D .... ...C  .... ...B .... ...A + .... ...9 .... ...8  .... ...7 .... ...6 - .... ...5 .... ...4  .... ...3 .... ...2
   zmm30: .... ..10 .... ...F  .... ...E .... ...E - .... ...D .... ...C  .... ...B .... ...A + .... ...9 .... ...8  .... ...7 .... ...6 - .... ...5 .... ...4  .... ...3 .... ...2
   zmm29: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0
  data   : .... .... .... ...1
  subTree: .... .... .... ...0
  b at offset 56 in zmm31: .... .... .... ...E
  -------------
  index: .... .... .... ...1
   zmm31: .... ..10 .AAA ...D  .... ...E .... ...E - .... ...E .... ...D  .... ...C .... ...B + .... ...A .... ...9  .... ...8 .... ...7 - .... ...6 .... ...5  .... ...4 .... ...3
   zmm30: .... ..10 .... ...F  .... ...E .... ...E - .... ...E .... ...D  .... ...C .... ...B + .... ...A .... ...9  .... ...8 .... ...7 - .... ...6 .... ...5  .... ...4 .... ...3
   zmm29: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0
  data   : .... .... .... ...2
  subTree: .... .... .... ...1
  b at offset 56 in zmm31: .... .... .... ...D
  -------------
  index: .... .... .... ...2
   zmm31: .... ..10 .555 ...C  .... ...E .... ...E - .... ...E .... ...E  .... ...D .... ...C + .... ...B .... ...A  .... ...9 .... ...8 - .... ...7 .... ...6  .... ...5 .... ...4
   zmm30: .... ..10 .... ...F  .... ...E .... ...E - .... ...E .... ...E  .... ...D .... ...C + .... ...B .... ...A  .... ...9 .... ...8 - .... ...7 .... ...6  .... ...5 .... ...4
   zmm29: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0
  data   : .... .... .... ...3
  subTree: .... .... .... ...0
  b at offset 56 in zmm31: .... .... .... ...C
  -------------
  index: .... .... .... ...3
   zmm31: .... ..10 .2AA ...B  .... ...E .... ...E - .... ...E .... ...E  .... ...E .... ...D + .... ...C .... ...B  .... ...A .... ...9 - .... ...8 .... ...7  .... ...6 .... ...5
   zmm30: .... ..10 .... ...F  .... ...E .... ...E - .... ...E .... ...E  .... ...E .... ...D + .... ...C .... ...B  .... ...A .... ...9 - .... ...8 .... ...7  .... ...6 .... ...5
   zmm29: .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0 + .... .... .... ...0  .... .... .... ...0 - .... .... .... ...0  .... .... .... ...0
  data   : .... .... .... ...4
  subTree: .... .... .... ...1
  b at offset 56 in zmm31: .... .... .... ...B
  END

Nasm::X86::Tree::mergeOrSteal($tree, $offset)

Merge the block at the specified offset with its right sibling or steal from it. If there is no right sibling then do the same thing but with the left sibling. The supplied block must not be the root. The key we are looking for must be in the tree key field.

     Parameter  Description
  1  $tree      Tree descriptor
  2  $offset    Offset of non root block that might need to merge or steal

Nasm::X86::Tree::stealFromRight($tree, $PK, $PD, $PN, $LK, $LD, $LN, $RK, $RD, $RN)

Steal one key from the node on the right where the current left node,parent node and right node are held in zmm registers and return one if the steal was performed, else zero.

      Parameter  Description
   1  $tree      Tree definition
   2  $PK        Parent keys zmm
   3  $PD        Data zmm
   4  $PN        Nodes zmm
   5  $LK        Left keys zmm
   6  $LD        Data zmm
   7  $LN        Nodes zmm
   8  $RK        Right keys
   9  $RD        Data
  10  $RN        Nodes zmm.

Nasm::X86::Tree::stealFromLeft($tree, $PK, $PD, $PN, $LK, $LD, $LN, $RK, $RD, $RN)

Steal one key from the node on the left where the current left node,parent node and right node are held in zmm registers and return one if the steal was performed, else zero.

      Parameter  Description
   1  $tree      Tree definition
   2  $PK        Parent keys zmm
   3  $PD        Data zmm
   4  $PN        Nodes zmm
   5  $LK        Left keys zmm
   6  $LD        Data zmm
   7  $LN        Nodes zmm
   8  $RK        Right keys
   9  $RD        Data
  10  $RN        Nodes zmm.

Nasm::X86::Tree::merge($tree, $PK, $PD, $PN, $LK, $LD, $LN, $RK, $RD, $RN)

Merge a left and right node if they are at minimum size.

      Parameter  Description
   1  $tree      Tree definition
   2  $PK        Parent keys zmm
   3  $PD        Data zmm
   4  $PN        Nodes zmm
   5  $LK        Left keys zmm
   6  $LD        Data zmm
   7  $LN        Nodes zmm
   8  $RK        Right keys
   9  $RD        Data
  10  $RN        Nodes zmm.

Nasm::X86::Tree::deleteFirstKeyAndData($tree, $K, $D)

Delete the first element of a leaf mode returning its characteristics in the calling tree descriptor.

     Parameter  Description
  1  $tree      Tree definition
  2  $K         Keys zmm
  3  $D         Data zmm

Nasm::X86::Tree::push($tree, $data)

Push a data value onto a tree. If the data is a reference to a tree then the offset of the first block of the tree is pushed.

     Parameter  Description
  1  $tree      Tree descriptor
  2  $data      Variable data

Example:

    my $a = CreateArea;
    my $t = $a->CreateTree;
    my $N = K loop => 16;
    $N->for(sub
     {my ($i) = @_;
      $t->push($i);
     });

    $t->peek(1)->data ->outNL;
    $t->peek(2)->data ->outNL;
    $t->peek(3)->found->outNL;
    $t->peek(2 * $N    )->found->outNL;

    $t->size->outNL;
    $t->get(8); $t->found->out("f: ", " ");  $t->key->out("i: ", " "); $t->data->outNL;

    $N->for(sub
     {my ($i) = @_;
      $t->pop; $t->found->out("f: ", " ");  $t->key->out("i: ", " "); $t->data->outNL;
     });
  # $t->pop; $t->found->outNL("f: ");

    ok Assemble eq => <<END, clocks => 29_852;
  data   : .... .... .... ...F
  data   : .... .... .... ...E
  found  : .... .... .... ..40
  found  : .... .... .... ...0
  size of tree: .... .... .... ..10
  f: .... .... .... ...2 i: .... .... .... ...8 data   : .... .... .... ...8
  f: .... .... .... ...1 i: .... .... .... ...F data   : .... .... .... ...F
  f: .... .... .... ...1 i: .... .... .... ...E data   : .... .... .... ...E
  f: .... .... .... ...1 i: .... .... .... ...D data   : .... .... .... ...D
  f: .... .... .... ...1 i: .... .... .... ...C data   : .... .... .... ...C
  f: .... .... .... ...1 i: .... .... .... ...B data   : .... .... .... ...B
  f: .... .... .... ...1 i: .... .... .... ...A data   : .... .... .... ...A
  f: .... .... .... ...1 i: .... .... .... ...9 data   : .... .... .... ...9
  f: .... .... .... ...1 i: .... .... .... ...8 data   : .... .... .... ...8
  f: .... .... .... ...1 i: .... .... .... ...7 data   : .... .... .... ...7
  f: .... .... .... ...1 i: .... .... .... ...6 data   : .... .... .... ...6
  f: .... .... .... ...1 i: .... .... .... ...5 data   : .... .... .... ...5
  f: .... .... .... ...1 i: .... .... .... ...4 data   : .... .... .... ...4
  f: .... .... .... ...1 i: .... .... .... ...3 data   : .... .... .... ...3
  f: .... .... .... ...1 i: .... .... .... ...2 data   : .... .... .... ...2
  f: .... .... .... ...1 i: .... .... .... ...1 data   : .... .... .... ...1
  f: .... .... .... ...1 i: .... .... .... ...0 data   : .... .... .... ...0
  END

    my $b = Rb(0x41..0x51);
    my $a = CreateArea;
    my $T;
    for my $i(1..8)
     {my $t = $a->CreateTree;
      $t->appendAscii(K(address=> $b), K(size => 1));
      $t->push($T) if $T;
      $T = $t;
     }

    $T->dump8xx("T");
    ok Assemble eq => <<END, trace=>0;
  T
  Tree: .... .... .... .740
  At:      780                                                                                length:        2,  data:      7C0,  nodes:      800,  first:      740, root, leaf,  trees:            10
    Index:        0        1
    Keys :        0        1
    Data :       41      64*
     Tree:      640
       At:      680                                                                           length:        2,  data:      6C0,  nodes:      700,  first:      640, root, leaf,  trees:            10
         Index:        0        1
         Keys :        0        1
         Data :       41      54*
          Tree:      540
            At:      580                                                                      length:        2,  data:      5C0,  nodes:      600,  first:      540, root, leaf,  trees:            10
              Index:        0        1
              Keys :        0        1
              Data :       41      44*
               Tree:      440
                 At:      480                                                                 length:        2,  data:      4C0,  nodes:      500,  first:      440, root, leaf,  trees:            10
                   Index:        0        1
                   Keys :        0        1
                   Data :       41      34*
                    Tree:      340
                      At:      380                                                            length:        2,  data:      3C0,  nodes:      400,  first:      340, root, leaf,  trees:            10
                        Index:        0        1
                        Keys :        0        1
                        Data :       41      24*
                         Tree:      240
                           At:      280                                                       length:        2,  data:      2C0,  nodes:      300,  first:      240, root, leaf,  trees:            10
                             Index:        0        1
                             Keys :        0        1
                             Data :       41      14*
                              Tree:      140
                                At:      180                                                  length:        2,  data:      1C0,  nodes:      200,  first:      140, root, leaf,  trees:            10
                                  Index:        0        1
                                  Keys :        0        1
                                  Data :       41       4*
                                   Tree:       40
                                     At:       80                                             length:        1,  data:       C0,  nodes:      100,  first:       40, root, leaf
                                       Index:        0
                                       Keys :        0
                                       Data :       41
                                     end
                                end
                           end
                      end
                 end
            end
       end
  end
  END

Nasm::X86::Tree::dumpWithWidth($tree, $title, $width, $margin, $first, $keyX, $dataX)

Dump a tree and all its sub trees.

     Parameter  Description
  1  $tree      Tree
  2  $title     Title
  3  $width     Width of offset field
  4  $margin    The maximum width of the indented area
  5  $first     Whether to print the offset of the tree
  6  $keyX      Whether to print the key field in hex or decimal
  7  $dataX     Whether to print the data field in hex or decimal

Nasm::X86::Tree::dump($tree, $title)

Dump a tree and all its sub trees.

     Parameter  Description
  1  $tree      Tree
  2  $title     Title

Nasm::X86::Tree::dump8($tree, $title)

Dump a tree and all its sub trees using 8 character fields for numbers.

     Parameter  Description
  1  $tree      Tree
  2  $title     Title

Nasm::X86::Tree::dump8xx($tree, $title)

Dump a tree and all its sub trees using 8 character fields for numbers printing the keys and data in hexadecimal.

     Parameter  Description
  1  $tree      Tree
  2  $title     Title

Example:

    my $a = CreateArea;
    my $t = $a->CreateTree;
    my $T = $a->CreateTree;

    $T->push(K key => 1);
    $t->push($T);
    $t->dump8xx('AA');
    my $s = $t->popSubTree;
    $t->dump8xx('BB');
    $s->dump8xx('CC');
    ok Assemble eq => <<END, avx512=>1;
  AA
  Tree: .... .... .... ..40
  At:      180                                                                                length:        1,  data:      1C0,  nodes:      200,  first:       40, root, leaf,  trees:             1
    Index:        0
    Keys :        0
    Data :       8*
     Tree:       80
       At:       C0                                                                           length:        1,  data:      100,  nodes:      140,  first:       80, root, leaf
         Index:        0
         Keys :        0
         Data :        1
       end
  end
  BB
  - empty
  CC
  Tree: .... .... .... ..80
  At:       C0                                                                                length:        1,  data:      100,  nodes:      140,  first:       80, root, leaf
    Index:        0
    Keys :        0
    Data :        1
  end
  END

compactRangeIntoHex(@P)

Compact a range of numbers into hexadecimal.

     Parameter  Description
  1  @P         Numbers to compact

Example:

  ok compactRangeIntoHex(qw(0x1 0x2 0x3 0x5 0x7 0x8 0x9 0xb)) eq                    # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

Nasm::X86::Unisyn::Lex::Number::S {0}(sub Nasm::X86::Unisyn::Lex::Number::F {1})

Start symbol.

     Parameter                                  Description
  1  sub Nasm::X86::Unisyn::Lex::Number::F {1}  P End symbol.

Nasm::X86::Unisyn::Lex::Number::F {1}()

End symbol.

Nasm::X86::Unisyn::Lex::Number::A {2}(sub Nasm::X86::Unisyn::Lex::Letter::A {(0x0..0x7f, 0x24b6..0x24e9)})

ASCII characters extended with circled characters to act as escape sequences.

     Parameter                                          Description
  1  sub Nasm::X86::Unisyn::Lex::Letter::A {(0x0..0x7f  P
  2  0x24b6..0x24e9)}

Nasm::X86::Unisyn::Lex::Number::p {3}(sub Nasm::X86::Unisyn::Lex::Letter::p {(0x1d468...0x1d49b, 0x1d71c..0x1d755, map {ord} qw(₁ ₂ ₃ ₄ ₅ ₆ ₇ ₈ ₉ ₀))})

Prefix operator - applies only to the following variable or bracketed term.

     Parameter                                                  Description
  1  sub Nasm::X86::Unisyn::Lex::Letter::p {(0x1d468...0x1d49b  P
  2  0x1d71c..0x1d755
  3  map {ord} qw(₁ ₂ ₃ ₄ ₅ ₆ ₇ ₈ ₉ ₀))}

Nasm::X86::Unisyn::Lex::Number::v {4}(sub Nasm::X86::Unisyn::Lex::Letter::v {(0x1d5d4...0x1d607, 0x1d756..0x1d78f)})

Variable names.

     Parameter                                                  Description
  1  sub Nasm::X86::Unisyn::Lex::Letter::v {(0x1d5d4...0x1d607  P
  2  0x1d756..0x1d78f)}

Nasm::X86::Unisyn::Lex::Number::q {5}()

Suffix operator - applies only to the preceding variable or bracketed term.

Nasm::X86::Unisyn::Lex::Number::s {6}()

Infix operator with left to right binding at priority 1.

Nasm::X86::Unisyn::Lex::Number::b {7}(sub Nasm::X86::Unisyn::Lex::Letter::b)

Open.

     Parameter                              Description
  1  sub Nasm::X86::Unisyn::Lex::Letter::b  P

Nasm::X86::Unisyn::Lex::Number::B {8}(sub Nasm::X86::Unisyn::Lex::Letter::B)

Close.

     Parameter                              Description
  1  sub Nasm::X86::Unisyn::Lex::Letter::B  P

Nasm::X86::Unisyn::Lex::Letter::d()

Dyad 2 - Double struck

Nasm::X86::Unisyn::Lex::Letter::e()

Dyad 3 - Mono

Nasm::X86::Unisyn::Lex::Number::a {11}(sub Nasm::X86::Unisyn::Lex::Letter::a)

Assign infix operator with right to left binding at priority 4.

     Parameter                              Description
  1  sub Nasm::X86::Unisyn::Lex::Letter::a  P

Nasm::X86::Unisyn::Lex::Letter::f()

Dyad 5 - Sans-serif Normal

Nasm::X86::Unisyn::Lex::Letter::g()

Dyad 6 - Sans-serif Bold

Nasm::X86::Unisyn::Lex::Letter::h()

Dyad 7 - Calligraphy - normal

Nasm::X86::Unisyn::Lex::Letter::i()

Dyad 8 - Calligraphy - bold

Nasm::X86::Unisyn::Lex::Letter::j()

Dyad 9 - Fraktur - Normal

Nasm::X86::Unisyn::Lex::Letter::k()

Dyad 10 - Fraktur - bold

Nasm::X86::Unisyn::Lex::Number::l {18}()

Dyad 11

Nasm::X86::Unisyn::Lex::Number::m {19}(sub Nasm::X86::Unisyn::Lex::Letter::m)

Dyad 12

     Parameter                              Description
  1  sub Nasm::X86::Unisyn::Lex::Letter::m  P