/
alu.go
107 lines (86 loc) · 1.74 KB
/
alu.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
package vm
import "math/bits"
type aluFlags struct {
Negative bool
Zero bool
Carry bool
}
type ALU struct {
flags aluFlags
}
func newALU() *ALU {
return &ALU{
flags: aluFlags{
Negative: false,
Zero: false,
Carry: false,
},
}
}
func (alu *ALU) ADD(a, b uint64) uint64 {
res, carry := bits.Add64(a, b, 0)
alu.setFlags(res, carry)
return res
}
func (alu *ALU) SUB(a, b uint64) uint64 {
res, _ := bits.Sub64(a, b, 0)
alu.setFlags(res, 0)
return res
}
func (alu *ALU) AND(a, b uint64) uint64 {
res := a & b
alu.setFlags(res, 0)
return res
}
func (alu *ALU) OR(a, b uint64) uint64 {
res := a | b
alu.setFlags(res, 0)
return res
}
func (alu *ALU) XOR(a, b uint64) uint64 {
res := a ^ b
alu.setFlags(res, 0)
return res
}
func (alu *ALU) LSL(a, b uint64) uint64 {
res := a << b
alu.setFlags(res, 0)
return res
}
func (alu *ALU) LSR(a, b uint64) uint64 {
res := a >> b
alu.setFlags(res, 0)
return res
}
func (alu *ALU) setFlags(res, carry uint64) {
alu.flags.Zero = res == 0
alu.flags.Negative = res&(0b1000<<60) > 0 // check last bit for signed-ness
alu.flags.Carry = carry == 1
}
func (alu *ALU) Zero() bool {
return alu.flags.Zero
}
func (alu *ALU) Negative() bool {
return alu.flags.Negative
}
func (alu *ALU) Carry() bool {
return alu.flags.Carry
}
func (alu *ALU) Equal() bool {
return alu.Zero()
}
func (alu *ALU) NotEqual() bool {
return !alu.Zero()
}
func (alu *ALU) LessThan() bool {
return alu.Negative() != alu.Carry()
}
func (alu *ALU) LessThanEqual() bool {
return alu.Zero() || (alu.Negative() != alu.Carry())
}
func (alu *ALU) GreaterThan() bool {
return !alu.Zero() && (alu.Negative() == alu.Carry())
}
func (alu *ALU) GreaterThanEqual() bool {
return alu.Negative() == alu.Carry()
}