Commit 6237d2fa authored by Julian Kranz's avatar Julian Kranz
Browse files

X86 RREIL Translator

- Added semantics for: TEST
- Parity Flag
parent 5593cc0f
...@@ -273,28 +273,21 @@ val sem-undef-flow1 x = do ...@@ -273,28 +273,21 @@ val sem-undef-flow1 x = do
return void return void
end end
val emit-parity-flag sz r = do val emit-parity-flag r = do
byte-size <- return 8; byte-size <- return 8;
low-byte <- mktemp; low-byte <- mktemp;
movzx byte-size low-byte sz r; mov byte-size low-byte r;
counter <- mktemp;
mov byte-size counter (imm 0);
#Todo: Hacker's Delight - Bit counting => eliminate while
cond <- mktemp;
mov 1 cond (imm 1);
_while (var cond) __ do
t <- mktemp;
andb byte-size t (var low-byte) (imm 1);
add byte-size counter (var counter) (var t);
shr byte-size low-byte (var low-byte) (imm 1);
cmpneq byte-size cond (var low-byte) (imm 0)
end;
pf <- fPF; pf <- fPF;
xorb 1 pf (var counter) (imm 1) # Bitwise XNOR
cmpeq 1 pf (var (at-offset low-byte 7)) (var (at-offset low-byte 6));
cmpeq 1 pf (var pf) (var (at-offset low-byte 5));
cmpeq 1 pf (var pf) (var (at-offset low-byte 4));
cmpeq 1 pf (var pf) (var (at-offset low-byte 3));
cmpeq 1 pf (var pf) (var (at-offset low-byte 2));
cmpeq 1 pf (var pf) (var (at-offset low-byte 1));
cmpeq 1 pf (var pf) (var (at-offset low-byte 0))
end end
val emit-arithmetic-adjust-flag sz r op0 op1 = do val emit-arithmetic-adjust-flag sz r op0 op1 = do
...@@ -342,7 +335,7 @@ val emit-add-adc-flags sz sum s0 s1 carry = do ...@@ -342,7 +335,7 @@ val emit-add-adc-flags sz sum s0 s1 carry = do
cmpltu sz cf sum s0 cmpltu sz cf sum s0
end; end;
emit-parity-flag sz sum; emit-parity-flag sum;
emit-arithmetic-adjust-flag sz sum s0 s1 emit-arithmetic-adjust-flag sz sum s0 s1
end end
...@@ -377,7 +370,7 @@ val emit-sub-sbb-flags sz difference minuend subtrahend carry = do ...@@ -377,7 +370,7 @@ val emit-sub-sbb-flags sz difference minuend subtrahend carry = do
cmpltu sz cf minuend subtrahend cmpltu sz cf minuend subtrahend
end; end;
emit-parity-flag sz difference; emit-parity-flag difference;
emit-arithmetic-adjust-flag sz difference minuend subtrahend emit-arithmetic-adjust-flag sz difference minuend subtrahend
end end
...@@ -410,6 +403,11 @@ val sem-add x = do ...@@ -410,6 +403,11 @@ val sem-add x = do
commit sz a (var t) commit sz a (var t)
end end
val sem-cdqe = do
a <- return (semantic-register-of RAX);
movsx 64 a 32 (var a)
end
val sem-cmp x = do val sem-cmp x = do
sz <- guess-sizeof x.opnd1 x.opnd2; sz <- guess-sizeof x.opnd1 x.opnd2;
a <- write sz x.opnd1; a <- write sz x.opnd1;
...@@ -420,6 +418,34 @@ val sem-cmp x = do ...@@ -420,6 +418,34 @@ val sem-cmp x = do
emit-sub-sbb-flags sz (var t) b c (imm 0) emit-sub-sbb-flags sz (var t) b c (imm 0)
end end
val sem-jb x = do
sz <- guess-sizeof-flow x.opnd1;
target <- read-flow sz x.opnd1;
cf <- fCF;
ifgoto (var cf) sz target
end
val sem-jc x = do
sz <- guess-sizeof-flow x.opnd1;
target <- read-flow sz x.opnd1;
cf <- fCF;
ifgoto (var cf) sz target
end
val sem-je x = do
sz <- guess-sizeof-flow x.opnd1;
target <- read-flow sz x.opnd1;
eq <- fEQ;
ifgoto (var eq) sz target
end
val sem-jmp x = do
sz <- guess-sizeof-flow x.opnd1;
target <- read-flow sz x.opnd1;
on3 <- const 1;
ifgoto on3 sz target
end
val sem-mov x = do val sem-mov x = do
sz <- guess-sizeof x.opnd1 x.opnd2; sz <- guess-sizeof x.opnd1 x.opnd2;
a <- write sz x.opnd1; a <- write sz x.opnd1;
...@@ -427,7 +453,64 @@ val sem-mov x = do ...@@ -427,7 +453,64 @@ val sem-mov x = do
commit sz a b commit sz a b
end end
val sem-shr x = do val sem-push x = do
opnd-sz <- runtime-opnd-sz;
src-size <- guess-sizeof1 x.opnd1;
src <- read src-size x.opnd1;
temp <- mktemp;
case x.opnd1 of
REG r:
if segment-register? r then
movzx opnd-sz temp src-size src
else
mov opnd-sz temp src
| MEM m:
mov opnd-sz temp src
| IMM8 i:
movsx opnd-sz temp src-size src
| IMM16 i:
mov opnd-sz temp src
| IMM32 i:
movsx opnd-sz temp src-size src
end;
mode64 <- t-mode64?;
stack-address-size <- runtime-stack-address-size;
if mode64 then
do
sp-reg <- return RSP;
sp <- return (semantic-register-of sp-reg);
sp-size <- guess-sizeof1 (REG sp-reg);
if opnd-sz === 64 then
sub sp-size sp (var sp) (imm 8)
else
sub sp-size sp (var sp) (imm 2)
;
store (address sp-size (var sp)) (lin opnd-sz (var temp))
end
else
do
sp-reg <-
if stack-address-size === 32 then
return ESP
else
return SP
;
sp <- return (semantic-register-of sp-reg);
sp-size <- guess-sizeof1 (REG sp-reg);
sp-seg <- segmentation-offset-ss-add sp-size sp;
if opnd-sz === 32 then
sub sp-size sp (var sp) (imm 4)
else
sub sp-size sp (var sp) (imm 2)
;
store (address sp-size (var sp-seg)) (lin opnd-sz (var temp))
end
end
val sem-sal-shl x = do
sz <- guess-sizeof1 x.opnd1; sz <- guess-sizeof1 x.opnd1;
szOp2 <- guess-sizeof1 x.opnd2; szOp2 <- guess-sizeof1 x.opnd2;
dst <- write sz x.opnd1; dst <- write sz x.opnd1;
...@@ -443,25 +526,20 @@ val sem-shr x = do ...@@ -443,25 +526,20 @@ val sem-shr x = do
end); end);
temp-count <- mktemp; temp-count <- mktemp;
andb sz temp-count count count-mask; andb sz temp-count count count-mask;
tdst <- mktemp; tdst <- mktemp;
cf <- fCF; cf <- fCF;
_if (/gtu sz (var temp-count) (imm 0)) _then do _if (/gtu sz (var temp-count) (imm 0)) _then do
sub sz temp-count (var temp-count) (imm 1); shl sz tdst src (var temp-count);
shr sz tdst src (var temp-count);
mov 1 cf (var tdst);
shr sz tdst (var tdst) (imm 1) mov 1 cf (var (at-offset tdst (sz - 1)))
end; end;
ov <- fOF; ov <- fOF;
_if (/eq sz (var temp-count) (imm 1)) _then do _if (/eq sz (var temp-count) (imm 1)) _then
t <- mktemp; xorb 1 ov (var (at-offset tdst (sz - 1))) (var cf)
mov sz t src; _else (_if (/neq sz (var temp-count) (imm 0)) _then
mov 1 ov (var (at-offset t (sz - 1)))
end _else (_if (/neq sz (var temp-count) (imm 0)) _then
undef 1 ov) undef 1 ov)
; ;
...@@ -471,9 +549,53 @@ val sem-shr x = do ...@@ -471,9 +549,53 @@ val sem-shr x = do
zf <- fZF; zf <- fZF;
cmpeq sz zf (var tdst) (imm 0); cmpeq sz zf (var tdst) (imm 0);
emit-parity-flag sz (var tdst); emit-parity-flag (var tdst);
commit sz dst (var tdst) commit sz dst (var tdst)
# # dst => a, src => b, amount => c
# ## Temporary variables:
# t1 <- mktemp;
# t2 <- mktemp;
# cnt <- mktemp;
# cntIsZero <- mktemp;
# cntIsOne <- mktemp;
# af <- fAF;
# ov <- fOF;
# cf <- fCF;
# eq <- fEQ;
# mask <- const
# (case sz of
# 8: 31
# | 16: 31
# | 32: 31
# | 64: 63
# end);
# zer0 <- const 0;
# one <- const 1;
#
# ## Instruction semantics:
# setflag <- mklabel;
# exit <- mklabel;
# nop <- mklabel;
# convert sz cnt szOp2 c;
# andb sz cnt (var cnt) mask;
# cmpeq sz cntIsZero (var cnt) zer0;
# ifgotolabel (var cntIsZero) nop;
# shl sz t1 b (/SUB (var cnt) one);
# mov 1 cf (var (t1 /+ (sz - 1)));
# shl sz t2 b (var cnt);
# cmpeq sz cntIsOne (var cnt) one;
# ifgotolabel (var cntIsOne) setflag;
# undef 1 ov;
# gotolabel exit;
# label setflag;
# xorb 1 ov (var cf) (var (t2 /+ (sz - 1)));
# label exit;
# undef 1 af;
# commit sz a (var t2);
# label nop;
# cmpeq sz eq b zer0
end end
val sem-sar x = do val sem-sar x = do
...@@ -518,12 +640,28 @@ val sem-sar x = do ...@@ -518,12 +640,28 @@ val sem-sar x = do
zf <- fZF; zf <- fZF;
cmpeq sz zf (var tdst) (imm 0); cmpeq sz zf (var tdst) (imm 0);
emit-parity-flag sz (var tdst); emit-parity-flag (var tdst);
commit sz dst (var tdst) commit sz dst (var tdst)
end end
val sem-sal-shl x = do val sem-sbb x = do
sz <- guess-sizeof x.opnd1 x.opnd2;
difference <- write sz x.opnd1;
minuend <- read sz x.opnd1;
subtrahend <- read sz x.opnd2;
t <- mktemp;
cf <- fCF;
movzx sz t 1 (var cf);
add sz t (var t) subtrahend;
sub sz t minuend subtrahend;
emit-sub-sbb-flags sz (var t) minuend subtrahend (var cf);
commit sz difference (var t)
end
val sem-shr x = do
sz <- guess-sizeof1 x.opnd1; sz <- guess-sizeof1 x.opnd1;
szOp2 <- guess-sizeof1 x.opnd2; szOp2 <- guess-sizeof1 x.opnd2;
dst <- write sz x.opnd1; dst <- write sz x.opnd1;
...@@ -539,20 +677,25 @@ val sem-sal-shl x = do ...@@ -539,20 +677,25 @@ val sem-sal-shl x = do
end); end);
temp-count <- mktemp; temp-count <- mktemp;
andb sz temp-count count count-mask; andb sz temp-count count count-mask;
tdst <- mktemp; tdst <- mktemp;
cf <- fCF; cf <- fCF;
_if (/gtu sz (var temp-count) (imm 0)) _then do _if (/gtu sz (var temp-count) (imm 0)) _then do
shl sz tdst src (var temp-count); sub sz temp-count (var temp-count) (imm 1);
shr sz tdst src (var temp-count);
mov 1 cf (var (at-offset tdst (sz - 1))) mov 1 cf (var tdst);
end;
shr sz tdst (var tdst) (imm 1)
end;
ov <- fOF; ov <- fOF;
_if (/eq sz (var temp-count) (imm 1)) _then _if (/eq sz (var temp-count) (imm 1)) _then do
xorb 1 ov (var (at-offset tdst (sz - 1))) (var cf) t <- mktemp;
_else (_if (/neq sz (var temp-count) (imm 0)) _then mov sz t src;
mov 1 ov (var (at-offset t (sz - 1)))
end _else (_if (/neq sz (var temp-count) (imm 0)) _then
undef 1 ov) undef 1 ov)
; ;
...@@ -562,53 +705,9 @@ val sem-sal-shl x = do ...@@ -562,53 +705,9 @@ val sem-sal-shl x = do
zf <- fZF; zf <- fZF;
cmpeq sz zf (var tdst) (imm 0); cmpeq sz zf (var tdst) (imm 0);
emit-parity-flag sz (var tdst); emit-parity-flag (var tdst);
commit sz dst (var tdst) commit sz dst (var tdst)
# # dst => a, src => b, amount => c
# ## Temporary variables:
# t1 <- mktemp;
# t2 <- mktemp;
# cnt <- mktemp;
# cntIsZero <- mktemp;
# cntIsOne <- mktemp;
# af <- fAF;
# ov <- fOF;
# cf <- fCF;
# eq <- fEQ;
# mask <- const
# (case sz of
# 8: 31
# | 16: 31
# | 32: 31
# | 64: 63
# end);
# zer0 <- const 0;
# one <- const 1;
#
# ## Instruction semantics:
# setflag <- mklabel;
# exit <- mklabel;
# nop <- mklabel;
# convert sz cnt szOp2 c;
# andb sz cnt (var cnt) mask;
# cmpeq sz cntIsZero (var cnt) zer0;
# ifgotolabel (var cntIsZero) nop;
# shl sz t1 b (/SUB (var cnt) one);
# mov 1 cf (var (t1 /+ (sz - 1)));
# shl sz t2 b (var cnt);
# cmpeq sz cntIsOne (var cnt) one;
# ifgotolabel (var cntIsOne) setflag;
# undef 1 ov;
# gotolabel exit;
# label setflag;
# xorb 1 ov (var cf) (var (t2 /+ (sz - 1)));
# label exit;
# undef 1 af;
# commit sz a (var t2);
# label nop;
# cmpeq sz eq b zer0
end end
val sem-sub x = do val sem-sub x = do
...@@ -624,110 +723,27 @@ val sem-sub x = do ...@@ -624,110 +723,27 @@ val sem-sub x = do
commit sz difference (var t) commit sz difference (var t)
end end
val sem-sbb x = do val sem-test x = do
sz <- guess-sizeof x.opnd1 x.opnd2; sz <- guess-sizeof x.opnd1 x.opnd2;
difference <- write sz x.opnd1; a <- read sz x.opnd1;
minuend <- read sz x.opnd1; b <- read sz x.opnd2;
subtrahend <- read sz x.opnd2;
temp <- mktemp;
t <- mktemp; andb sz temp a b;
cf <- fCF;
movzx sz t 1 (var cf);
add sz t (var t) subtrahend;
sub sz t minuend subtrahend;
emit-sub-sbb-flags sz (var t) minuend subtrahend (var cf);
commit sz difference (var t)
end
val sem-je x = do sf <- fSF;
sz <- guess-sizeof-flow x.opnd1; cmplts sz sf (var temp) (imm 0);
target <- read-flow sz x.opnd1;
eq <- fEQ;
ifgoto (var eq) sz target
end
val sem-jb x = do zf <- fZF;
sz <- guess-sizeof-flow x.opnd1; cmpeq sz zf (var temp) (imm 0);
target <- read-flow sz x.opnd1;
cf <- fCF; emit-parity-flag temp;
ifgoto (var cf) sz target
end
val sem-jc x = do
sz <- guess-sizeof-flow x.opnd1;
target <- read-flow sz x.opnd1;
cf <- fCF; cf <- fCF;
ifgoto (var cf) sz target mov 1 cf (imm 0);
end
ov <- fOF;
val sem-jmp x = do mov 1 ov (imm 0)
sz <- guess-sizeof-flow x.opnd1;
target <- read-flow sz x.opnd1;
on3 <- const 1;
ifgoto on3 sz target
end
val sem-cdqe = do
a <- return (semantic-register-of RAX);
movsx 64 a 32 (var a)
end
val sem-push x = do
opnd-sz <- runtime-opnd-sz;
src-size <- guess-sizeof1 x.opnd1;
src <- read src-size x.opnd1;
temp <- mktemp;
case x.opnd1 of
REG r:
if segment-register? r then
movzx opnd-sz temp src-size src
else
mov opnd-sz temp src
| MEM m:
mov opnd-sz temp src
| IMM8 i:
movsx opnd-sz temp src-size src
| IMM16 i:
mov opnd-sz temp src
| IMM32 i:
movsx opnd-sz temp src-size src
end;
mode64 <- t-mode64?;
stack-address-size <- runtime-stack-address-size;
if mode64 then
do
sp-reg <- return RSP;
sp <- return (semantic-register-of sp-reg);
sp-size <- guess-sizeof1 (REG sp-reg);
if opnd-sz === 64 then
sub sp-size sp (var sp) (imm 8)
else
sub sp-size sp (var sp) (imm 2)
;
store (address sp-size (var sp)) (lin opnd-sz (var temp))
end
else
do
sp-reg <-
if stack-address-size === 32 then
return ESP
else
return SP
;
sp <- return (semantic-register-of sp-reg);
sp-size <- guess-sizeof1 (REG sp-reg);
sp-seg <- segmentation-offset-ss-add sp-size sp;
if opnd-sz === 32 then
sub sp-size sp (var sp) (imm 4)
else
sub sp-size sp (var sp) (imm 2)
;
store (address sp-size (var sp-seg)) (lin opnd-sz (var temp))
end
end end
val semantics insn = val semantics insn =
...@@ -1342,7 +1358,7 @@ val semantics insn = ...@@ -1342,7 +1358,7 @@ val semantics insn =
| SYSENTER: sem-undef-arity0 | SYSENTER: sem-undef-arity0
| SYSEXIT: sem-undef-arity0 | SYSEXIT: sem-undef-arity0
| SYSRET: sem-undef-arity0 | SYSRET: sem-undef-arity0
| TEST x: sem-undef-arity2 x | TEST x: sem-test x
| UCOMISD x: sem-undef-arity2 x | UCOMISD x: sem-undef-arity2 x
| UCOMISS x: sem-undef-arity2 x | UCOMISS x: sem-undef-arity2 x
| UD2: sem-undef-arity0 | UD2: sem-undef-arity0
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment