Class: Haxor::Vm::Cpu::Core

Inherits:
Subsystem show all
Defined in:
lib/haxor/vm/cpu/core.rb

Constant Summary collapse

OP_NOP =

Misc

0x00
OP_EXITI =
0x01
OP_SYSCALL =
0x02
OP_ADD =

Arithmetic

0x10
OP_ADDI =
0x11
OP_SUB =
0x12
OP_MULT =
0x13
OP_DIV =
0x14
OP_MOD =
0x15
OP_LW =

Data transfer

0x20
OP_SW =
0x21
OP_LUI =
0x22
OP_AND =

Logical

0x30
OP_ANDI =
0x31
OP_OR =
0x32
OP_ORI =
0x33
OP_XOR =
0x34
OP_NOR =
0x35
OP_SLT =
0x36
OP_SLTI =
0x37
OP_SLLI =

Bitwise shift

0x40
OP_SRLI =
0x41
OP_SLL =
0x42
OP_SRL =
0x43
OP_BEQ =

Branch/Jumps

0x50
OP_BEQL =
0x51
OP_BNE =
0x52
OP_BNEL =
0x53
OP_J =
0x54
OP_JR =
0x55
OP_JAL =
0x56
REG_ZERO =
0
REG_STACK =
61
REG_RETURN =
62
REG_SYSCALL =
63

Instance Attribute Summary collapse

Attributes inherited from Subsystem

#vm

Instance Method Summary collapse

Methods inherited from Subsystem

#register, #subsystem

Constructor Details

#initialize ⇒ Core

Returns a new instance of Core.



55
56
57
58
59
60
# File 'lib/haxor/vm/cpu/core.rb', line 55

def initialize
  @registers = Array.new(64, 0)
  @units = []
  @opcodes = {}
  init_opcodes
end

Instance Attribute Details

#ip ⇒ Object

Returns the value of attribute ip.



5
6
7
# File 'lib/haxor/vm/cpu/core.rb', line 5

def ip
  @ip
end

Instance Method Details

#bind_opcode(opcode, method) ⇒ Object



244
245
246
247
248
249
# File 'lib/haxor/vm/cpu/core.rb', line 244

def bind_opcode(opcode, method)
  fail "OpCode already defined - #{opcode}." if @opcodes.key? opcode
  @opcodes[opcode] = {
    method: method
  }
end

#branch(rel_addr) ⇒ Object



240
241
242
# File 'lib/haxor/vm/cpu/core.rb', line 240

def branch(rel_addr)
  @ip += rel_addr * Consts::WORD_SIZE
end

#init_opcodes ⇒ Object



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
# File 'lib/haxor/vm/cpu/core.rb', line 62

def init_opcodes
  bind_opcode OP_NOP, :op_nop
  bind_opcode OP_ADD, :op_add
  bind_opcode OP_ADDI, :op_addi
  bind_opcode OP_SUB, :op_sub
  bind_opcode OP_MULT, :op_mult
  bind_opcode OP_DIV, :op_div
  bind_opcode OP_MOD, :op_mod
  bind_opcode OP_LW, :op_lw
  bind_opcode OP_SW, :op_sw
  bind_opcode OP_LUI, :op_lui
  bind_opcode OP_AND, :op_and
  bind_opcode OP_ANDI, :op_andi
  bind_opcode OP_OR, :op_or
  bind_opcode OP_ORI, :op_ori
  bind_opcode OP_XOR, :op_xor
  bind_opcode OP_NOR, :op_nor
  bind_opcode OP_SLT, :op_slt
  bind_opcode OP_SLTI, :op_slti
  bind_opcode OP_SLLI, :op_slli
  bind_opcode OP_SRLI, :op_srli
  bind_opcode OP_SLL, :op_sll
  bind_opcode OP_SRL, :op_srl
  bind_opcode OP_BEQ, :op_beq
  bind_opcode OP_BEQL, :op_beql
  bind_opcode OP_BNE, :op_bne
  bind_opcode OP_BNEL, :op_bnel
  bind_opcode OP_J, :op_j
  bind_opcode OP_JR, :op_jr
  bind_opcode OP_JAL, :op_jal
  bind_opcode OP_EXITI, :op_exiti
  bind_opcode OP_SYSCALL, :op_syscall
end

#iterate ⇒ Object



251
252
253
254
255
256
# File 'lib/haxor/vm/cpu/core.rb', line 251

def iterate
  opcode = subsystem(:mem).read @ip
  @ip += Consts::WORD_SIZE
  info = Utils.decode_opcode opcode
  send @opcodes[info.cmd][:method], info
end

#jmp(addr) ⇒ Object



236
237
238
# File 'lib/haxor/vm/cpu/core.rb', line 236

def jmp(addr)
  @ip = addr * Consts::WORD_SIZE
end

#op_add(info) ⇒ Object



99
100
101
# File 'lib/haxor/vm/cpu/core.rb', line 99

def op_add(info)
  reg info.reg1, reg(info.reg2) + reg(info.reg3)
end

#op_addi(info) ⇒ Object



103
104
105
# File 'lib/haxor/vm/cpu/core.rb', line 103

def op_addi(info)
  reg info.reg1, reg(info.reg2) + info.imm
end

#op_and(info) ⇒ Object



139
140
141
# File 'lib/haxor/vm/cpu/core.rb', line 139

def op_and(info)
  reg info.reg1, reg(info.reg2) & reg(info.reg3)
end

#op_andi(info) ⇒ Object



143
144
145
# File 'lib/haxor/vm/cpu/core.rb', line 143

def op_andi(info)
  reg info.reg1, reg(info.reg2) & info.imm
end

#op_beq(info) ⇒ Object



187
188
189
# File 'lib/haxor/vm/cpu/core.rb', line 187

def op_beq(info)
  branch(info.imm) if reg(info.reg1) == reg(info.reg2)
end

#op_beql(info) ⇒ Object



191
192
193
194
195
196
# File 'lib/haxor/vm/cpu/core.rb', line 191

def op_beql(info)
  return if reg(info.reg1) != reg(info.reg2)

  reg REG_RETURN, @ip
  branch(info.imm)
end

#op_bne(info) ⇒ Object



198
199
200
# File 'lib/haxor/vm/cpu/core.rb', line 198

def op_bne(info)
  branch info.imm if reg(info.reg1) != reg(info.reg2)
end

#op_bnel(info) ⇒ Object



202
203
204
205
206
207
# File 'lib/haxor/vm/cpu/core.rb', line 202

def op_bnel(info)
  return if reg(info.reg1) == reg(info.reg2)

  reg REG_RETURN, @ip
  branch(info.imm)
end

#op_div(info) ⇒ Object



115
116
117
# File 'lib/haxor/vm/cpu/core.rb', line 115

def op_div(info)
  reg info.reg1, reg(info.reg2) / reg(info.reg3)
end

#op_exiti(info) ⇒ Object



222
223
224
# File 'lib/haxor/vm/cpu/core.rb', line 222

def op_exiti(info)
  exit info.imm
end

#op_j(info) ⇒ Object



209
210
211
# File 'lib/haxor/vm/cpu/core.rb', line 209

def op_j(info)
  jmp info.imm
end

#op_jal(info) ⇒ Object



217
218
219
220
# File 'lib/haxor/vm/cpu/core.rb', line 217

def op_jal(info)
  reg REG_RETURN, @ip
  jmp info.imm
end

#op_jr(info) ⇒ Object



213
214
215
# File 'lib/haxor/vm/cpu/core.rb', line 213

def op_jr(info)
  @ip = reg(info.reg1)
end

#op_lui(info) ⇒ Object



135
136
137
# File 'lib/haxor/vm/cpu/core.rb', line 135

def op_lui(info)
  reg info.reg1, (info.imm << 32)
end

#op_lw(info) ⇒ Object

reg1 = memory



124
125
126
127
# File 'lib/haxor/vm/cpu/core.rb', line 124

def op_lw(info)
  addr = reg(info.reg2) + info.imm
  reg info.reg1, subsystem(:mem).read(addr)
end

#op_mod(info) ⇒ Object



119
120
121
# File 'lib/haxor/vm/cpu/core.rb', line 119

def op_mod(info)
  reg info.reg1, reg(info.reg2) % reg(info.reg3)
end

#op_mult(info) ⇒ Object



111
112
113
# File 'lib/haxor/vm/cpu/core.rb', line 111

def op_mult(info)
  reg info.reg1, reg(info.reg2) * reg(info.reg3)
end

#op_nop(info) ⇒ Object



96
97
# File 'lib/haxor/vm/cpu/core.rb', line 96

def op_nop(info)
end

#op_nor(info) ⇒ Object



159
160
161
# File 'lib/haxor/vm/cpu/core.rb', line 159

def op_nor(info)
  reg info.reg1, ~(reg(info.reg2) | reg(info.reg3))
end

#op_or(info) ⇒ Object



147
148
149
# File 'lib/haxor/vm/cpu/core.rb', line 147

def op_or(info)
  reg info.reg1, reg(info.reg2) | reg(info.reg3)
end

#op_ori(info) ⇒ Object



151
152
153
# File 'lib/haxor/vm/cpu/core.rb', line 151

def op_ori(info)
  reg info.reg1, reg(info.reg2) | info.imm
end

#op_sll(info) ⇒ Object



179
180
181
# File 'lib/haxor/vm/cpu/core.rb', line 179

def op_sll(info)
  reg info.reg1, reg(info.reg2) << reg(info.reg3)
end

#op_slli(info) ⇒ Object



171
172
173
# File 'lib/haxor/vm/cpu/core.rb', line 171

def op_slli(info)
  reg info.reg1, reg(info.reg2) << info.imm
end

#op_slt(info) ⇒ Object



163
164
165
# File 'lib/haxor/vm/cpu/core.rb', line 163

def op_slt(info)
  reg info.reg1, reg(info.reg2) < reg(info.reg3) ? 1 : 0
end

#op_slti(info) ⇒ Object



167
168
169
# File 'lib/haxor/vm/cpu/core.rb', line 167

def op_slti(info)
  reg info.reg1, reg(info.reg2) < info.imm ? 1 : 0
end

#op_srl(info) ⇒ Object



183
184
185
# File 'lib/haxor/vm/cpu/core.rb', line 183

def op_srl(info)
  reg info.reg1, reg(info.reg2) >> reg(info.reg3)
end

#op_srli(info) ⇒ Object



175
176
177
# File 'lib/haxor/vm/cpu/core.rb', line 175

def op_srli(info)
  reg info.reg1, reg(info.reg2) >> info.imm
end

#op_sub(info) ⇒ Object



107
108
109
# File 'lib/haxor/vm/cpu/core.rb', line 107

def op_sub(info)
  reg info.reg1, reg(info.reg2) - reg(info.reg3)
end

#op_sw(info) ⇒ Object

memory = reg2



130
131
132
133
# File 'lib/haxor/vm/cpu/core.rb', line 130

def op_sw(info)
  addr = reg(info.reg1) + info.imm
  subsystem(:mem).write addr, reg(info.reg2)
end

#op_syscall(_info) ⇒ Object



226
227
228
# File 'lib/haxor/vm/cpu/core.rb', line 226

def op_syscall(_info)
  @vm.subsystem(:os).syscall
end

#op_xor(info) ⇒ Object



155
156
157
# File 'lib/haxor/vm/cpu/core.rb', line 155

def op_xor(info)
  reg info.reg1, reg(info.reg2) ^ reg(info.reg3)
end

#reg(id, value = nil) ⇒ Object



230
231
232
233
234
# File 'lib/haxor/vm/cpu/core.rb', line 230

def reg(id, value = nil)
  return @registers[id] if value.nil?
  return if id == REG_ZERO # $0 cannot be overwritten
  @registers[id] = value
end