haxor 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b9cd0c9814ac3e3f2fdef12190761ba4eba60b08
4
- data.tar.gz: 6660137e743eb98ba7c64d3770d0326ea7e84710
3
+ metadata.gz: 8a4e2b69873a7f50003c2fb9d403f9529a7fc88e
4
+ data.tar.gz: 1531d3af090791055290d4bfb982fca8e9ae188e
5
5
  SHA512:
6
- metadata.gz: b0d90ca99f25427569baef3b3f897351448449f32306a162f2566cac5ddb0bdc42bc8f72574bfd316d0e85af7d24b68ba23a2a97b79d9ce330eb263b8c0be6bc
7
- data.tar.gz: d5451c7125f93d755b7decc9ebb7af83e0abf11ef11a8f5e4f0a9fda5d9a60891399fb7f4a3c2fe4c185f342d835e1a750d57c7a55b00443cfa3c29d3008200e
6
+ metadata.gz: e01e17918aaa669fc8404b5bd294e5e2d29251c480fb867ff9a679ac0cbcb134d17336c070175394d9014de02dd50343f5710036edf389b727e32a359b80ad9e
7
+ data.tar.gz: c0220e732f98cff88b1045bcd5418d36983a838197d8e765d49c1e7434f52fcc8cc7bc6eff93c1c33f62fdd0dcf8cc29c4a3b6e4e9d590a0bf62a3eb2a1136e1
@@ -15,8 +15,7 @@ require_relative 'haxor/vm/subsystem'
15
15
  require_relative 'haxor/vm/mem'
16
16
  require_relative 'haxor/vm/stack'
17
17
  require_relative 'haxor/vm/os'
18
- require_relative 'haxor/vm/registers'
19
- require_relative 'haxor/vm/cpu/core'
18
+ require_relative 'haxor/vm/cpu'
20
19
 
21
20
  # compiler
22
21
  require_relative 'haxor/compiler/unit'
@@ -2,9 +2,9 @@ module Haxor
2
2
  module Compiler
3
3
  class Core
4
4
  REG_ALIASES = {
5
- '$sp' => Vm::Cpu::Core::REG_STACK,
6
- '$ret' => Vm::Cpu::Core::REG_RETURN,
7
- '$sc' => Vm::Cpu::Core::REG_SYSCALL
5
+ '$sp' => Vm::Cpu::REG_STACK,
6
+ '$ret' => Vm::Cpu::REG_RETURN,
7
+ '$sc' => Vm::Cpu::REG_SYSCALL
8
8
  }
9
9
 
10
10
  def initialize
@@ -41,37 +41,37 @@ module Haxor
41
41
  bind_cmd 'bgtz', [:reg, :imm], :cmd_bgtz
42
42
  bind_cmd 'beqz', [:reg, :imm], :cmd_beqz
43
43
 
44
- bind_cmd 'nop', [], Vm::Cpu::Core::OP_NOP
45
- bind_cmd 'add', [:reg, :reg, :reg], Vm::Cpu::Core::OP_ADD
46
- bind_cmd 'addi', [:reg, :reg, :imm], Vm::Cpu::Core::OP_ADDI
47
- bind_cmd 'sub', [:reg, :reg, :reg], Vm::Cpu::Core::OP_SUB
48
- bind_cmd 'mult', [:reg, :reg, :reg], Vm::Cpu::Core::OP_MULT
49
- bind_cmd 'div', [:reg, :reg, :reg], Vm::Cpu::Core::OP_DIV
50
- bind_cmd 'mod', [:reg, :reg, :reg], Vm::Cpu::Core::OP_MOD
51
- bind_cmd 'lw', [:reg, :reg, :imm], Vm::Cpu::Core::OP_LW
52
- bind_cmd 'sw', [:reg, :imm, :reg], Vm::Cpu::Core::OP_SW
53
- bind_cmd 'lui', [:reg, :imm], Vm::Cpu::Core::OP_LUI
54
- bind_cmd 'and', [:reg, :reg, :reg], Vm::Cpu::Core::OP_AND
55
- bind_cmd 'andi', [:reg, :reg, :imm], Vm::Cpu::Core::OP_ANDI
56
- bind_cmd 'or', [:reg, :reg, :reg], Vm::Cpu::Core::OP_OR
57
- bind_cmd 'ori', [:reg, :reg, :imm], Vm::Cpu::Core::OP_ORI
58
- bind_cmd 'xor', [:reg, :reg, :reg], Vm::Cpu::Core::OP_XOR
59
- bind_cmd 'nor', [:reg, :reg, :reg], Vm::Cpu::Core::OP_NOR
60
- bind_cmd 'slt', [:reg, :reg, :reg], Vm::Cpu::Core::OP_SLT
61
- bind_cmd 'slti', [:reg, :reg, :imm], Vm::Cpu::Core::OP_SLTI
62
- bind_cmd 'slli', [:reg, :reg, :imm], Vm::Cpu::Core::OP_SLLI
63
- bind_cmd 'srli', [:reg, :reg, :imm], Vm::Cpu::Core::OP_SRLI
64
- bind_cmd 'sll', [:reg, :reg, :reg], Vm::Cpu::Core::OP_SLL
65
- bind_cmd 'srl', [:reg, :reg, :reg], Vm::Cpu::Core::OP_SRL
66
- bind_cmd 'beq', [:reg, :reg, :imm], Vm::Cpu::Core::OP_BEQ, [:rel_imm, :x8]
67
- bind_cmd 'beql', [:reg, :reg, :imm], Vm::Cpu::Core::OP_BEQL, [:rel_imm, :x8]
68
- bind_cmd 'bne', [:reg, :reg, :imm], Vm::Cpu::Core::OP_BNE, [:rel_imm, :x8]
69
- bind_cmd 'bnel', [:reg, :reg, :imm], Vm::Cpu::Core::OP_BNEL, [:rel_imm, :x8]
70
- bind_cmd 'j', [:imm], Vm::Cpu::Core::OP_J, [:x8]
71
- bind_cmd 'jr', [:reg], Vm::Cpu::Core::OP_JR
72
- bind_cmd 'jal', [:imm], Vm::Cpu::Core::OP_JAL, [:x8]
73
- bind_cmd 'exiti', [:imm], Vm::Cpu::Core::OP_EXITI
74
- bind_cmd 'syscall', [], Vm::Cpu::Core::OP_SYSCALL
44
+ bind_cmd 'nop', [], Vm::Cpu::OP_NOP
45
+ bind_cmd 'add', [:reg, :reg, :reg], Vm::Cpu::OP_ADD
46
+ bind_cmd 'addi', [:reg, :reg, :imm], Vm::Cpu::OP_ADDI
47
+ bind_cmd 'sub', [:reg, :reg, :reg], Vm::Cpu::OP_SUB
48
+ bind_cmd 'mult', [:reg, :reg, :reg], Vm::Cpu::OP_MULT
49
+ bind_cmd 'div', [:reg, :reg, :reg], Vm::Cpu::OP_DIV
50
+ bind_cmd 'mod', [:reg, :reg, :reg], Vm::Cpu::OP_MOD
51
+ bind_cmd 'lw', [:reg, :reg, :imm], Vm::Cpu::OP_LW
52
+ bind_cmd 'sw', [:reg, :imm, :reg], Vm::Cpu::OP_SW
53
+ bind_cmd 'lui', [:reg, :imm], Vm::Cpu::OP_LUI
54
+ bind_cmd 'and', [:reg, :reg, :reg], Vm::Cpu::OP_AND
55
+ bind_cmd 'andi', [:reg, :reg, :imm], Vm::Cpu::OP_ANDI
56
+ bind_cmd 'or', [:reg, :reg, :reg], Vm::Cpu::OP_OR
57
+ bind_cmd 'ori', [:reg, :reg, :imm], Vm::Cpu::OP_ORI
58
+ bind_cmd 'xor', [:reg, :reg, :reg], Vm::Cpu::OP_XOR
59
+ bind_cmd 'nor', [:reg, :reg, :reg], Vm::Cpu::OP_NOR
60
+ bind_cmd 'slt', [:reg, :reg, :reg], Vm::Cpu::OP_SLT
61
+ bind_cmd 'slti', [:reg, :reg, :imm], Vm::Cpu::OP_SLTI
62
+ bind_cmd 'slli', [:reg, :reg, :imm], Vm::Cpu::OP_SLLI
63
+ bind_cmd 'srli', [:reg, :reg, :imm], Vm::Cpu::OP_SRLI
64
+ bind_cmd 'sll', [:reg, :reg, :reg], Vm::Cpu::OP_SLL
65
+ bind_cmd 'srl', [:reg, :reg, :reg], Vm::Cpu::OP_SRL
66
+ bind_cmd 'beq', [:reg, :reg, :imm], Vm::Cpu::OP_BEQ, [:rel_imm, :x8]
67
+ bind_cmd 'beql', [:reg, :reg, :imm], Vm::Cpu::OP_BEQL, [:rel_imm, :x8]
68
+ bind_cmd 'bne', [:reg, :reg, :imm], Vm::Cpu::OP_BNE, [:rel_imm, :x8]
69
+ bind_cmd 'bnel', [:reg, :reg, :imm], Vm::Cpu::OP_BNEL, [:rel_imm, :x8]
70
+ bind_cmd 'j', [:imm], Vm::Cpu::OP_J, [:x8]
71
+ bind_cmd 'jr', [:reg], Vm::Cpu::OP_JR
72
+ bind_cmd 'jal', [:imm], Vm::Cpu::OP_JAL, [:x8]
73
+ bind_cmd 'exiti', [:imm], Vm::Cpu::OP_EXITI
74
+ bind_cmd 'syscall', [], Vm::Cpu::OP_SYSCALL
75
75
  end
76
76
 
77
77
  def bind_cmd(cmd, args, opcode, opts = [])
@@ -155,7 +155,7 @@ module Haxor
155
155
  end
156
156
 
157
157
  def cmd_ret(*_args)
158
- process_cmd 'jr', ['$' + Vm::Cpu::Core::REG_RETURN.to_s]
158
+ process_cmd 'jr', ['$' + Vm::Cpu::REG_RETURN.to_s]
159
159
  end
160
160
 
161
161
  def cmd_b(*args)
@@ -1,7 +1,7 @@
1
1
  module Haxor
2
2
  class Consts
3
3
  MAJOR = 0
4
- MINOR = 4
4
+ MINOR = 5
5
5
  PATCH = 0
6
6
  GEM_VERSION = "#{MAJOR}.#{MINOR}.#{PATCH}"
7
7
  VERSION = (MAJOR << 16) | (MINOR << 8) | PATCH
@@ -5,7 +5,7 @@ module Haxor
5
5
  SECTIONS = [:text, :data, :bss]
6
6
 
7
7
  def initialize
8
- @cpu = Vm::Cpu::Core.new
8
+ @cpu = Vm::Cpu.new
9
9
  @units = []
10
10
  @tokens = []
11
11
  @labels = {}
@@ -5,7 +5,7 @@ module Haxor
5
5
 
6
6
  def initialize
7
7
  @subsystems = {}
8
- register_subsystem :cpu, Cpu::Core.new
8
+ register_subsystem :cpu, Cpu.new
9
9
  register_subsystem :mem, Mem.new(Consts::RESERVED_MEM)
10
10
  register_subsystem :stack, Stack.new
11
11
  register_subsystem :os, Os.new
@@ -45,7 +45,7 @@ module Haxor
45
45
  subsystem(:cpu).ip = @hdr.entry_point # instruction pointer
46
46
  subsystem(:mem).enlarge @hdr.bss_size
47
47
  subsystem(:mem).enlarge @hdr.stack_size
48
- subsystem(:cpu).reg Vm::Cpu::Core::REG_STACK, subsystem(:mem).size
48
+ subsystem(:cpu).reg Vm::Cpu::REG_STACK, subsystem(:mem).size
49
49
  end
50
50
  end
51
51
  end
@@ -0,0 +1,258 @@
1
+ module Haxor
2
+ module Vm
3
+ class Cpu < Subsystem
4
+ attr_accessor :ip
5
+
6
+ # Misc
7
+ OP_NOP = 0x00
8
+ OP_EXITI = 0x01
9
+ OP_SYSCALL = 0x02
10
+
11
+ # Arithmetic
12
+ OP_ADD = 0x10
13
+ OP_ADDI = 0x11
14
+ OP_SUB = 0x12
15
+ OP_MULT = 0x13
16
+ OP_DIV = 0x14
17
+ OP_MOD = 0x15
18
+
19
+ # Data transfer
20
+ OP_LW = 0x20
21
+ OP_SW = 0x21
22
+ OP_LUI = 0x22
23
+
24
+ # Logical
25
+ OP_AND = 0x30
26
+ OP_ANDI = 0x31
27
+ OP_OR = 0x32
28
+ OP_ORI = 0x33
29
+ OP_XOR = 0x34
30
+ OP_NOR = 0x35
31
+ OP_SLT = 0x36
32
+ OP_SLTI = 0x37
33
+
34
+ # Bitwise shift
35
+ OP_SLLI = 0x40
36
+ OP_SRLI = 0x41
37
+ OP_SLL = 0x42
38
+ OP_SRL = 0x43
39
+
40
+ # Branch/Jumps
41
+ OP_BEQ = 0x50
42
+ OP_BEQL = 0x51
43
+ OP_BNE = 0x52
44
+ OP_BNEL = 0x53
45
+ OP_J = 0x54
46
+ OP_JR = 0x55
47
+ OP_JAL = 0x56
48
+
49
+ REG_ZERO = 0
50
+ REG_STACK = 61
51
+ REG_RETURN = 62
52
+ REG_SYSCALL = 63
53
+
54
+ def initialize
55
+ @registers = Array.new(64, 0)
56
+ @units = []
57
+ @opcodes = {}
58
+ init_opcodes
59
+ end
60
+
61
+ def init_opcodes
62
+ bind_opcode OP_NOP, :op_nop
63
+ bind_opcode OP_ADD, :op_add
64
+ bind_opcode OP_ADDI, :op_addi
65
+ bind_opcode OP_SUB, :op_sub
66
+ bind_opcode OP_MULT, :op_mult
67
+ bind_opcode OP_DIV, :op_div
68
+ bind_opcode OP_MOD, :op_mod
69
+ bind_opcode OP_LW, :op_lw
70
+ bind_opcode OP_SW, :op_sw
71
+ bind_opcode OP_LUI, :op_lui
72
+ bind_opcode OP_AND, :op_and
73
+ bind_opcode OP_ANDI, :op_andi
74
+ bind_opcode OP_OR, :op_or
75
+ bind_opcode OP_ORI, :op_ori
76
+ bind_opcode OP_XOR, :op_xor
77
+ bind_opcode OP_NOR, :op_nor
78
+ bind_opcode OP_SLT, :op_slt
79
+ bind_opcode OP_SLTI, :op_slti
80
+ bind_opcode OP_SLLI, :op_slli
81
+ bind_opcode OP_SRLI, :op_srli
82
+ bind_opcode OP_SLL, :op_sll
83
+ bind_opcode OP_SRL, :op_srl
84
+ bind_opcode OP_BEQ, :op_beq
85
+ bind_opcode OP_BEQL, :op_beql
86
+ bind_opcode OP_BNE, :op_bne
87
+ bind_opcode OP_BNEL, :op_bnel
88
+ bind_opcode OP_J, :op_j
89
+ bind_opcode OP_JR, :op_jr
90
+ bind_opcode OP_JAL, :op_jal
91
+ bind_opcode OP_EXITI, :op_exiti
92
+ bind_opcode OP_SYSCALL, :op_syscall
93
+ end
94
+
95
+ def op_nop(info)
96
+ end
97
+
98
+ def op_add(info)
99
+ reg info.reg1, reg(info.reg2) + reg(info.reg3)
100
+ end
101
+
102
+ def op_addi(info)
103
+ reg info.reg1, reg(info.reg2) + info.imm
104
+ end
105
+
106
+ def op_sub(info)
107
+ reg info.reg1, reg(info.reg2) - reg(info.reg3)
108
+ end
109
+
110
+ def op_mult(info)
111
+ reg info.reg1, reg(info.reg2) * reg(info.reg3)
112
+ end
113
+
114
+ def op_div(info)
115
+ reg info.reg1, reg(info.reg2) / reg(info.reg3)
116
+ end
117
+
118
+ def op_mod(info)
119
+ reg info.reg1, reg(info.reg2) % reg(info.reg3)
120
+ end
121
+
122
+ # reg1 = memory[reg2+imm]
123
+ def op_lw(info)
124
+ addr = reg(info.reg2) + info.imm
125
+ reg info.reg1, subsystem(:mem).read(addr)
126
+ end
127
+
128
+ # memory[reg1+imm] = reg2
129
+ def op_sw(info)
130
+ addr = reg(info.reg1) + info.imm
131
+ subsystem(:mem).write addr, reg(info.reg2)
132
+ end
133
+
134
+ def op_lui(info)
135
+ reg info.reg1, (info.imm << 32)
136
+ end
137
+
138
+ def op_and(info)
139
+ reg info.reg1, reg(info.reg2) & reg(info.reg3)
140
+ end
141
+
142
+ def op_andi(info)
143
+ reg info.reg1, reg(info.reg2) & info.imm
144
+ end
145
+
146
+ def op_or(info)
147
+ reg info.reg1, reg(info.reg2) | reg(info.reg3)
148
+ end
149
+
150
+ def op_ori(info)
151
+ reg info.reg1, reg(info.reg2) | info.imm
152
+ end
153
+
154
+ def op_xor(info)
155
+ reg info.reg1, reg(info.reg2) ^ reg(info.reg3)
156
+ end
157
+
158
+ def op_nor(info)
159
+ reg info.reg1, ~(reg(info.reg2) | reg(info.reg3))
160
+ end
161
+
162
+ def op_slt(info)
163
+ reg info.reg1, reg(info.reg2) < reg(info.reg3) ? 1 : 0
164
+ end
165
+
166
+ def op_slti(info)
167
+ reg info.reg1, reg(info.reg2) < info.imm ? 1 : 0
168
+ end
169
+
170
+ def op_slli(info)
171
+ reg info.reg1, reg(info.reg2) << info.imm
172
+ end
173
+
174
+ def op_srli(info)
175
+ reg info.reg1, reg(info.reg2) >> info.imm
176
+ end
177
+
178
+ def op_sll(info)
179
+ reg info.reg1, reg(info.reg2) << reg(info.reg3)
180
+ end
181
+
182
+ def op_srl(info)
183
+ reg info.reg1, reg(info.reg2) >> reg(info.reg3)
184
+ end
185
+
186
+ def op_beq(info)
187
+ branch(info.imm) if reg(info.reg1) == reg(info.reg2)
188
+ end
189
+
190
+ def op_beql(info)
191
+ return if reg(info.reg1) != reg(info.reg2)
192
+
193
+ reg REG_RETURN, @ip
194
+ branch(info.imm)
195
+ end
196
+
197
+ def op_bne(info)
198
+ branch info.imm if reg(info.reg1) != reg(info.reg2)
199
+ end
200
+
201
+ def op_bnel(info)
202
+ return if reg(info.reg1) == reg(info.reg2)
203
+
204
+ reg REG_RETURN, @ip
205
+ branch(info.imm)
206
+ end
207
+
208
+ def op_j(info)
209
+ jmp info.imm
210
+ end
211
+
212
+ def op_jr(info)
213
+ @ip = reg(info.reg1)
214
+ end
215
+
216
+ def op_jal(info)
217
+ reg REG_RETURN, @ip
218
+ jmp info.imm
219
+ end
220
+
221
+ def op_exiti(info)
222
+ exit info.imm
223
+ end
224
+
225
+ def op_syscall(_info)
226
+ @vm.subsystem(:os).syscall
227
+ end
228
+
229
+ def reg(id, value = nil)
230
+ return @registers[id] if value.nil?
231
+ return if id == REG_ZERO # $0 cannot be overwritten
232
+ @registers[id] = value
233
+ end
234
+
235
+ def jmp(addr)
236
+ @ip = addr * Consts::WORD_SIZE
237
+ end
238
+
239
+ def branch(rel_addr)
240
+ @ip += rel_addr * Consts::WORD_SIZE
241
+ end
242
+
243
+ def bind_opcode(opcode, method)
244
+ fail "OpCode already defined - #{opcode}." if @opcodes.key? opcode
245
+ @opcodes[opcode] = {
246
+ method: method
247
+ }
248
+ end
249
+
250
+ def iterate
251
+ opcode = subsystem(:mem).read @ip
252
+ @ip += Consts::WORD_SIZE
253
+ info = Utils.decode_opcode opcode
254
+ send @opcodes[info.cmd][:method], info
255
+ end
256
+ end
257
+ end
258
+ end
@@ -8,7 +8,7 @@ module Haxor
8
8
  }
9
9
 
10
10
  def syscall
11
- func = subsystem(:cpu).reg(Vm::Cpu::Core::REG_SYSCALL)
11
+ func = subsystem(:cpu).reg(Vm::Cpu::REG_SYSCALL)
12
12
  send(TABLE[func])
13
13
  end
14
14
 
@@ -78,7 +78,7 @@ module Haxor
78
78
  result = file.scanf fmt
79
79
 
80
80
  if result.size != types.size
81
- subsystem(:cpu).reg Vm::Cpu::Core::REG_SYSCALL, -1
81
+ subsystem(:cpu).reg Vm::Cpu::REG_SYSCALL, -1
82
82
  return
83
83
  end
84
84
 
@@ -7,9 +7,9 @@ module Haxor
7
7
  end
8
8
 
9
9
  def push_value(value)
10
- sp = @vm.subsystem(:cpu).reg Vm::Cpu::Core::REG_STACK
10
+ sp = @vm.subsystem(:cpu).reg Vm::Cpu::REG_STACK
11
11
  sp -= Consts::WORD_SIZE
12
- @vm.subsystem(:cpu).reg Vm::Cpu::Core::REG_STACK, sp
12
+ @vm.subsystem(:cpu).reg Vm::Cpu::REG_STACK, sp
13
13
  @vm.subsystem(:mem).write sp, value
14
14
  end
15
15
 
@@ -19,10 +19,10 @@ module Haxor
19
19
  end
20
20
 
21
21
  def pop_value
22
- sp = @vm.subsystem(:cpu).reg Vm::Cpu::Core::REG_STACK
22
+ sp = @vm.subsystem(:cpu).reg Vm::Cpu::REG_STACK
23
23
  value = @vm.subsystem(:mem).read sp
24
24
  sp += Consts::WORD_SIZE
25
- @vm.subsystem(:cpu).reg Vm::Cpu::Core::REG_STACK, sp
25
+ @vm.subsystem(:cpu).reg Vm::Cpu::REG_STACK, sp
26
26
 
27
27
  value
28
28
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: haxor
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Krzysztof Magosa
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-01-04 00:00:00.000000000 Z
11
+ date: 2016-01-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -75,10 +75,9 @@ files:
75
75
  - lib/haxor/token/pointer.rb
76
76
  - lib/haxor/utils.rb
77
77
  - lib/haxor/vm/core.rb
78
- - lib/haxor/vm/cpu/core.rb
78
+ - lib/haxor/vm/cpu.rb
79
79
  - lib/haxor/vm/mem.rb
80
80
  - lib/haxor/vm/os.rb
81
- - lib/haxor/vm/registers.rb
82
81
  - lib/haxor/vm/stack.rb
83
82
  - lib/haxor/vm/subsystem.rb
84
83
  - media/memory.png
@@ -1,260 +0,0 @@
1
- module Haxor
2
- module Vm
3
- module Cpu
4
- class Core < Subsystem
5
- attr_accessor :ip
6
-
7
- # Misc
8
- OP_NOP = 0x00
9
- OP_EXITI = 0x01
10
- OP_SYSCALL = 0x02
11
-
12
- # Arithmetic
13
- OP_ADD = 0x10
14
- OP_ADDI = 0x11
15
- OP_SUB = 0x12
16
- OP_MULT = 0x13
17
- OP_DIV = 0x14
18
- OP_MOD = 0x15
19
-
20
- # Data transfer
21
- OP_LW = 0x20
22
- OP_SW = 0x21
23
- OP_LUI = 0x22
24
-
25
- # Logical
26
- OP_AND = 0x30
27
- OP_ANDI = 0x31
28
- OP_OR = 0x32
29
- OP_ORI = 0x33
30
- OP_XOR = 0x34
31
- OP_NOR = 0x35
32
- OP_SLT = 0x36
33
- OP_SLTI = 0x37
34
-
35
- # Bitwise shift
36
- OP_SLLI = 0x40
37
- OP_SRLI = 0x41
38
- OP_SLL = 0x42
39
- OP_SRL = 0x43
40
-
41
- # Branch/Jumps
42
- OP_BEQ = 0x50
43
- OP_BEQL = 0x51
44
- OP_BNE = 0x52
45
- OP_BNEL = 0x53
46
- OP_J = 0x54
47
- OP_JR = 0x55
48
- OP_JAL = 0x56
49
-
50
- REG_ZERO = 0
51
- REG_STACK = 61
52
- REG_RETURN = 62
53
- REG_SYSCALL = 63
54
-
55
- def initialize
56
- @registers = Array.new(64, 0)
57
- @units = []
58
- @opcodes = {}
59
- init_opcodes
60
- end
61
-
62
- def init_opcodes
63
- bind_opcode OP_NOP, :op_nop
64
- bind_opcode OP_ADD, :op_add
65
- bind_opcode OP_ADDI, :op_addi
66
- bind_opcode OP_SUB, :op_sub
67
- bind_opcode OP_MULT, :op_mult
68
- bind_opcode OP_DIV, :op_div
69
- bind_opcode OP_MOD, :op_mod
70
- bind_opcode OP_LW, :op_lw
71
- bind_opcode OP_SW, :op_sw
72
- bind_opcode OP_LUI, :op_lui
73
- bind_opcode OP_AND, :op_and
74
- bind_opcode OP_ANDI, :op_andi
75
- bind_opcode OP_OR, :op_or
76
- bind_opcode OP_ORI, :op_ori
77
- bind_opcode OP_XOR, :op_xor
78
- bind_opcode OP_NOR, :op_nor
79
- bind_opcode OP_SLT, :op_slt
80
- bind_opcode OP_SLTI, :op_slti
81
- bind_opcode OP_SLLI, :op_slli
82
- bind_opcode OP_SRLI, :op_srli
83
- bind_opcode OP_SLL, :op_sll
84
- bind_opcode OP_SRL, :op_srl
85
- bind_opcode OP_BEQ, :op_beq
86
- bind_opcode OP_BEQL, :op_beql
87
- bind_opcode OP_BNE, :op_bne
88
- bind_opcode OP_BNEL, :op_bnel
89
- bind_opcode OP_J, :op_j
90
- bind_opcode OP_JR, :op_jr
91
- bind_opcode OP_JAL, :op_jal
92
- bind_opcode OP_EXITI, :op_exiti
93
- bind_opcode OP_SYSCALL, :op_syscall
94
- end
95
-
96
- def op_nop(info)
97
- end
98
-
99
- def op_add(info)
100
- reg info.reg1, reg(info.reg2) + reg(info.reg3)
101
- end
102
-
103
- def op_addi(info)
104
- reg info.reg1, reg(info.reg2) + info.imm
105
- end
106
-
107
- def op_sub(info)
108
- reg info.reg1, reg(info.reg2) - reg(info.reg3)
109
- end
110
-
111
- def op_mult(info)
112
- reg info.reg1, reg(info.reg2) * reg(info.reg3)
113
- end
114
-
115
- def op_div(info)
116
- reg info.reg1, reg(info.reg2) / reg(info.reg3)
117
- end
118
-
119
- def op_mod(info)
120
- reg info.reg1, reg(info.reg2) % reg(info.reg3)
121
- end
122
-
123
- # reg1 = memory[reg2+imm]
124
- def op_lw(info)
125
- addr = reg(info.reg2) + info.imm
126
- reg info.reg1, subsystem(:mem).read(addr)
127
- end
128
-
129
- # memory[reg1+imm] = reg2
130
- def op_sw(info)
131
- addr = reg(info.reg1) + info.imm
132
- subsystem(:mem).write addr, reg(info.reg2)
133
- end
134
-
135
- def op_lui(info)
136
- reg info.reg1, (info.imm << 32)
137
- end
138
-
139
- def op_and(info)
140
- reg info.reg1, reg(info.reg2) & reg(info.reg3)
141
- end
142
-
143
- def op_andi(info)
144
- reg info.reg1, reg(info.reg2) & info.imm
145
- end
146
-
147
- def op_or(info)
148
- reg info.reg1, reg(info.reg2) | reg(info.reg3)
149
- end
150
-
151
- def op_ori(info)
152
- reg info.reg1, reg(info.reg2) | info.imm
153
- end
154
-
155
- def op_xor(info)
156
- reg info.reg1, reg(info.reg2) ^ reg(info.reg3)
157
- end
158
-
159
- def op_nor(info)
160
- reg info.reg1, ~(reg(info.reg2) | reg(info.reg3))
161
- end
162
-
163
- def op_slt(info)
164
- reg info.reg1, reg(info.reg2) < reg(info.reg3) ? 1 : 0
165
- end
166
-
167
- def op_slti(info)
168
- reg info.reg1, reg(info.reg2) < info.imm ? 1 : 0
169
- end
170
-
171
- def op_slli(info)
172
- reg info.reg1, reg(info.reg2) << info.imm
173
- end
174
-
175
- def op_srli(info)
176
- reg info.reg1, reg(info.reg2) >> info.imm
177
- end
178
-
179
- def op_sll(info)
180
- reg info.reg1, reg(info.reg2) << reg(info.reg3)
181
- end
182
-
183
- def op_srl(info)
184
- reg info.reg1, reg(info.reg2) >> reg(info.reg3)
185
- end
186
-
187
- def op_beq(info)
188
- branch(info.imm) if reg(info.reg1) == reg(info.reg2)
189
- end
190
-
191
- def op_beql(info)
192
- return if reg(info.reg1) != reg(info.reg2)
193
-
194
- reg REG_RETURN, @ip
195
- branch(info.imm)
196
- end
197
-
198
- def op_bne(info)
199
- branch info.imm if reg(info.reg1) != reg(info.reg2)
200
- end
201
-
202
- def op_bnel(info)
203
- return if reg(info.reg1) == reg(info.reg2)
204
-
205
- reg REG_RETURN, @ip
206
- branch(info.imm)
207
- end
208
-
209
- def op_j(info)
210
- jmp info.imm
211
- end
212
-
213
- def op_jr(info)
214
- @ip = reg(info.reg1)
215
- end
216
-
217
- def op_jal(info)
218
- reg REG_RETURN, @ip
219
- jmp info.imm
220
- end
221
-
222
- def op_exiti(info)
223
- exit info.imm
224
- end
225
-
226
- def op_syscall(_info)
227
- @vm.subsystem(:os).syscall
228
- end
229
-
230
- def reg(id, value = nil)
231
- return @registers[id] if value.nil?
232
- return if id == REG_ZERO # $0 cannot be overwritten
233
- @registers[id] = value
234
- end
235
-
236
- def jmp(addr)
237
- @ip = addr * Consts::WORD_SIZE
238
- end
239
-
240
- def branch(rel_addr)
241
- @ip += rel_addr * Consts::WORD_SIZE
242
- end
243
-
244
- def bind_opcode(opcode, method)
245
- fail "OpCode already defined - #{opcode}." if @opcodes.key? opcode
246
- @opcodes[opcode] = {
247
- method: method
248
- }
249
- end
250
-
251
- def iterate
252
- opcode = subsystem(:mem).read @ip
253
- @ip += Consts::WORD_SIZE
254
- info = Utils.decode_opcode opcode
255
- send @opcodes[info.cmd][:method], info
256
- end
257
- end
258
- end
259
- end
260
- end
@@ -1,42 +0,0 @@
1
- module Haxor
2
- module Vm
3
- class Registers < Subsystem
4
- def initialize
5
- @registers = {}
6
- end
7
-
8
- def flag(flag, enabled)
9
- flags = read 'fr'
10
- if enabled
11
- flags |= flag
12
- else
13
- flags &= ~flag
14
- end
15
- write 'fr', flags
16
- end
17
-
18
- def check_flag(flag)
19
- flags = read 'fr'
20
- (flags & flag) > 0
21
- end
22
-
23
- def read(register)
24
- addr = resolve register
25
- @vm.subsystem(:mem).read addr
26
- end
27
-
28
- def write(register, value)
29
- addr = resolve register
30
- @vm.subsystem(:mem).write addr, value
31
- end
32
-
33
- def resolve(register)
34
- @registers[register]
35
- end
36
-
37
- def add_register(register, addr)
38
- @registers[register] = addr
39
- end
40
- end
41
- end
42
- end