-
Notifications
You must be signed in to change notification settings - Fork 0
/
eflags.go
115 lines (101 loc) · 2.38 KB
/
eflags.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
package main
import (
"fmt"
"math/bits"
// "github.com/fatih/color"
)
// Eflags is a set of flags
type Eflags uint32
// eflags
const (
CarryFlag = uint32(1) << 0
ParityFlag = uint32(1) << 2
AdjustFlag = uint32(1) << 4
ZeroFlag = uint32(1) << 6
SignFlag = uint32(1) << 7
TrapFlag = uint32(1) << 8
InterruptFlag = uint32(1) << 9
DirectionFlag = uint32(1) << 10
OverflowFlag = uint32(1) << 11
)
func (ef *Eflags) setVal(flag uint32, value bool) {
if value {
ef.set(flag)
} else {
ef.unset(flag)
}
}
func (ef *Eflags) set(flag uint32) {
*ef = Eflags(uint32(*ef) | flag)
}
func (ef *Eflags) unset(flag uint32) {
*ef = Eflags(uint32(*ef) & ^flag)
}
func (ef *Eflags) isEnable(flag uint32) bool {
return uint32(*ef)&flag == flag
}
func (ef *Eflags) updateBySub8(v1, v2 uint8, result uint16) {
sign1 := (v1 >> 7) & 0x01
sign2 := (v2 >> 7) & 0x01
signr := uint8((result >> 7) & 0x01)
ef.setVal(CarryFlag, (result>>8) != 0)
ef.setVal(ZeroFlag, result == 0)
ef.setVal(SignFlag, signr != 0)
ef.setVal(OverflowFlag,
(sign1 == 0 && sign2 == 1 && signr == 1) || (sign1 == 1 && sign2 == 0 && signr == 0))
}
func (ef *Eflags) updateByAndOr8(result uint8) {
ef.setVal(OverflowFlag, false)
ef.setVal(CarryFlag, false)
ef.setVal(SignFlag, (result>>7) != 0)
ef.setVal(ZeroFlag, result == 0)
popcnt := bits.OnesCount8(result)
ef.setVal(ParityFlag, popcnt%2 == 0)
}
func (ef *Eflags) updateBySub(v1, v2 uint32, result uint64) {
sign1 := (v1 >> 31) & 0x01
sign2 := (v2 >> 31) & 0x01
signr := uint32((result >> 31) & 0x01)
ef.setVal(CarryFlag, (result>>32) != 0)
ef.setVal(ZeroFlag, result == 0)
ef.setVal(SignFlag, signr != 0)
ef.setVal(OverflowFlag,
(sign1 == 0 && sign2 == 1 && signr == 1) || (sign1 == 1 && sign2 == 0 && signr == 0))
}
func (ef *Eflags) updatePF(result uint8) {
popcnt := bits.OnesCount8(result)
ef.setVal(ParityFlag, popcnt%2 == 0)
}
func (ef *Eflags) dump() {
s := "EFLAGS="
if ef.isEnable(CarryFlag) {
s += "CF "
}
if ef.isEnable(ParityFlag) {
s += "PF "
}
if ef.isEnable(AdjustFlag) {
s += "AF "
}
if ef.isEnable(ZeroFlag) {
s += "ZF "
}
if ef.isEnable(SignFlag) {
s += "SF "
}
if ef.isEnable(TrapFlag) {
s += "TF "
}
if ef.isEnable(InterruptFlag) {
s += "IF "
}
if ef.isEnable(DirectionFlag) {
s += "DF "
}
if ef.isEnable(OverflowFlag) {
s += "OF "
}
s += "\n"
// color.New(color.FgCyan).Print(s)
fmt.Print(s)
}