NAME=ar comma
FILE=-
ARGS=-a x86 -b 64
CMDS=<<EOF
ar rax=33
ar rbx=44
ar rax,rbx
EOF
EXPECT=<<EOF
0x00000021
0x0000002c
EOF
RUN

NAME=add
FILE=-
CMDS=<<EOF
ae 3,3,+
ae 3,3,-
EOF
EXPECT=<<EOF
0x6
0
EOF
RUN

NAME=inc/dec
FILE=-
CMDS=<<EOF
ae 0xffffffffffffffff,++
ae 3,++
ae 3,--
ae 0,--
EOF
EXPECT=<<EOF
0
0x4
0x2
0xffffffffffffffff
EOF
RUN

NAME=sub
FILE=-
CMDS=ae 1,3,-
EXPECT=<<EOF
0x2
EOF
RUN

NAME=subeq
FILE=-
CMDS=<<EOF
e asm.bits=32
e asm.arch=x86
aei
ae 3,eax,=,1,eax,-=,eax,0,+
EOF
EXPECT=<<EOF
0x2
EOF
RUN

NAME=shift-left
FILE=-
CMDS=<<EOF
"ae 3,1,<<"
"ae 1,3,<<"
EOF
EXPECT=<<EOF
0x8
0x6
EOF
RUN

NAME=shift-right
FILE=-
CMDS=<<EOF
"ae 1,8,>>"
"ae 8,1,>>"
EOF
EXPECT=<<EOF
0x4
0
EOF
RUN

NAME=sub
FILE=-
CMDS=ae 3,1,-
EXPECT=<<EOF
0xfffffffffffffffe
EOF
RUN

NAME=neg
FILE=-
CMDS=<<EOF
ae 3,3,+,!
ae 3,3,-,!
EOF
EXPECT=<<EOF
0
0x1
EOF
RUN

NAME=condition
FILE=-
CMDS=ae 3,?{,0x80,}
EXPECT=<<EOF
0x80
EOF
RUN

NAME=memory write (MIPS little endian)
FILE=-
ARGS=-a mips
CMDS=<<EOF
e cfg.bigendian=false
aeim
e io.cache=true
"ae 0x69686766,0x00100000,=[4]"
psz @0x00100000
EOF
EXPECT=<<EOF
fghi
EOF
RUN

NAME=memory write (MIPS big endian)
FILE=-
ARGS=-a mips
CMDS=<<EOF
e cfg.bigendian=true
aeim
e io.cache=true
"ae 0x69686766,0x00100000,=[4]"
psz @0x00100000
EOF
EXPECT=<<EOF
ihgf
EOF
RUN

NAME=memory write (non-MIPS big endian)
FILE=-
CMDS=<<EOF
e cfg.bigendian=true
aeim
e io.cache=true
"ae 0x69686766,0x00100000,=[4]"
psz @0x00100000
EOF
EXPECT=<<EOF
ihgf
EOF
RUN

NAME=esil poke some (32-bits ARM big endian)
FILE=
ARGS=-a arm -b 32
CMDS=<<EOF
e cfg.bigendian=true
aeim
e io.cache=true
ar r0=0x00100000
ar r1=0x69686766
"ae r1,1,r0,=[*]"
p8 4@0x00100000
EOF
EXPECT=<<EOF
69686766
EOF
RUN

NAME=esil poke some (64-bits ARM big endian)
FILE=-
ARGS=-a arm -b 64
CMDS=<<EOF
e cfg.bigendian=true
aeim
e io.cache=true
ar x0=0x00100000
ar x1=0x69686766
"ae x1,1,x0,=[*]"
p8 8@0x00100000
EOF
EXPECT=<<EOF
0000000069686766
EOF
RUN

NAME=esil poke some (32-bits ARM little endian)
FILE=-
ARGS=-a arm -b 32
CMDS=<<EOF
e cfg.bigendian=false
aeim
e io.cache=true
ar r0=0x00100000
ar r1=0x69686766
"ae r1,1,r0,=[*]"
p8 4@0x00100000
EOF
EXPECT=<<EOF
66676869
EOF
RUN

NAME=esil poke some (64-bits ARM little endian)
FILE=-
ARGS=-a arm -b 64
CMDS=<<EOF
e cfg.bigendian=false
aeim
e io.cache=true
ar x0=0x00100000
ar x1=0x69686766
"ae x1,1,x0,=[*]"
p8 8@0x00100000
EOF
EXPECT=<<EOF
6667686900000000
EOF
RUN

NAME=esil poke some (count too long)
FILE=-
ARGS=-a arm -b 64
CMDS=<<EOF
e cfg.bigendian=false
aeim
e io.cache=true
ar x0=0x00100000
ar x1=0x69686766
"ae x1,0xffffffff,x0,=[*]"
p8 8@0x00100000
EOF
EXPECT=<<EOF
6667686900000000
EOF
RUN

NAME=rol
FILE=-
CMDS=<<EOF
e asm.bits=32
e asm.arch=x86
aei
ar eax=0x80000010
"ae 0x1,eax,<<<,eax,="
ar eax
EOF
EXPECT=<<EOF
0x00000021
EOF
RUN

NAME=ror
FILE=-
CMDS=<<EOF
e asm.bits=32
e asm.arch=x86
aei
ar eax=0x02000001
"ae 0x1,eax,>>>,eax,="
ar eax
EOF
EXPECT=<<EOF
0x81000000
EOF
RUN

NAME=or-mem-dst
FILE=-
CMDS=<<EOF
e asm.bits=32
e asm.arch=x86
aei
ar eax=0x0000000b
"ae 0xf,eax,=[4]"
"ae 0xf0,eax,|=[4]"
"ae eax,[4]"
EOF
EXPECT=<<EOF
0xff
EOF
RUN

NAME=rep stosq
FILE=bins/elf/analysis/x64-rep-stosq
CMDS=<<EOF
e io.cache=1
aei
aeip
3aes
ar rcx
ar rdi
ar rip
aes
ar rcx
ar rdi
ar rip
EOF
EXPECT=<<EOF
0x00000001
0x006000d0
0x004000c0
0x00000000
0x006000d8
0x004000c3
EOF
RUN

NAME=signext 8 32 64 
FILE=-
CMDS="ae 8,0x80,~,8,0x70,~,32,0x80000000,~,64,0x80000000,~"
EXPECT=<<EOF
0xffffffffffffff80,0x70,0xffffffff80000000,0x80000000
EOF
RUN

NAME=signext ex 
FILE=-
CMDS="ae 32,0xffffffffffffff12,~"
EXPECT=<<EOF
0xffffffffffffff12
EOF
RUN

NAME=sign extension assignement
FILE=-
CMDS=<<EOF
e asm.arch=riscv
e asm.bits=32
"ae 0x8007,a0,=,0x5,a1,=,16,a0,~=,8,a1,~="
ar a0
ar a1
EOF
EXPECT=<<EOF
0xffff8007
0x00000005
EOF
RUN

NAME=float int to double
FILE=-
CMDS="ae 9,I2D"
EXPECT=<<EOF
0x4022000000000000
EOF
RUN

NAME=float double to int
FILE=-
CMDS="ae 9,I2D,D2I"
EXPECT=<<EOF
0x9
EOF
RUN

NAME=float double to float (32)
FILE=-
CMDS="ae 32,9,I2D,D2F"
EXPECT=<<EOF
0x41100000
EOF
RUN

NAME=float math
FILE=-
CMDS="ae 9,I2D,SQRT,4,I2D,F+,3,I2D,F/,6,I2D,F*"
EXPECT=<<EOF
0x4004924924924924
EOF
RUN

NAME=inc/dec
FILE=-
CMDS=<<EOF
ae 0xffffffffffffffff,++ # 0
ae 1,2,+,3,++,+ # should be 3 + 4
ae 1,3,--,+ # should be 3
ae 1,3,--,- # should be 1
ae 0,++
EOF
EXPECT=<<EOF
0
0x7
0x3
0x1
0x1
EOF
RUN

NAME=ae??
FILE=-
CMDS=ae??
EXPECT=<<EOF
| Examples:ESIL   examples and documentation
| =       assign updating internal flags
| :=      assign without updating internal flags
| +=      a+=b => b,a,+=
| /       division
| *       multiply
| *=      multiply and assign a *= b
| L*      long multiply
| +       a=a+b => b,a,+,a,=
| ++      increment, 2,a,++ == 3 (see rsi,--=[1], ... )
| --      decrement, 2,a,-- == 1
| *=      a*=b => b,a,*=
| /=      a/=b => b,a,/=
| %       module
| %=      a%=b => b,a,%=
| &=      and ax, bx => bx,ax,&=
| ^       xor
| &       and
| |       or r0, r1, r2 => r2,r1,|,r0,=
| !=      negate all bits
| ^=      xor ax, bx => bx,ax,^=
| []      mov eax,[eax] => eax,[],eax,=
| =[]     mov [eax+3], 1 => 1,3,eax,+,=[]
| =[1]    mov byte[eax],1 => 1,eax,=[1]
| =[8]    mov [rax],1 => 1,rax,=[8]
| ()      execute an esil syscall
| []      peek from random position
| [N]     peek word of N bytes from popped address
| [*]     peek some from random position
| =[*]    poke some at random position
| $       int 0x80 => 0x80,$
| $$      simulate a hardware trap
| ==      pops twice, compare and update esil flags
| <       compare for smaller
| <=      compare for smaller or equal
| >       compare for bigger
| >=      compare bigger for or equal
| >>=     shr ax, bx => bx,ax,>>=  # shift right
| <<=     shl ax, bx => bx,ax,<<=  # shift left
| >>>=    ror ax, bx => bx,ax,>>>=  # rotate right
| <<<=    rol ax, bx => bx,ax,<<<=  # rotate left
| ?{      if popped value != 0 run the block until }
| }{      else block
| }       end of conditional block
| NAN     checks if result in stack is not a number
| I2D     signed to double
| U2D     unsigned to double
| D2I     double to signed
| D2U     double to unsigned
| F==     float comparison
| CEIL    float ceil
| FLOOR   float floor
| ROUND   float round
| SQRT    float square root
| POP     drops last element in the esil stack
| DUP     duplicate last value in stack
| NUM     evaluate last item in stack to number
| SWAP    swap last two values in stack
| TRAP    stop execution
| BITS    16,BITS  # change bits, useful for arm/thumb
| TODO    the instruction is not yet esilized
| STACK   show contents of stack
| CLEAR   clears the esil stack
| REPEAT  repeat n times
| BREAK   terminates the string parsing
| SETJT   set jump target
| SETJTS  set jump target set
| SETD    set delay slot
| GOTO    jump to the Nth word popped from the stack
| $       esil interrupt
| $z      internal flag: zero
| $c      internal flag: carry
| $b      internal flag: borrow
| $p      internal flag: parity
| $s      internal flag: sign
| $o      internal flag: overflow
| $ds     internal flag: delay-slot
| $jt     internal flag: jump-target
| $js     internal flag: jump-target-set
| $$      internal flag: pc address
EOF
RUN
