2018-07-26 19:47:56 -07:00
|
|
|
require "./lexer.cr"
|
|
|
|
|
|
|
|
module Chalk
|
|
|
|
class Instruction
|
2018-07-27 19:56:26 -07:00
|
|
|
def to_bin(i, index)
|
|
|
|
return 0
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
class InstructionContext
|
|
|
|
property table : Table
|
|
|
|
property stack : Int32
|
|
|
|
|
|
|
|
def initialize(@table, @stack)
|
|
|
|
end
|
2018-07-26 19:47:56 -07:00
|
|
|
end
|
|
|
|
|
|
|
|
class LoadInstruction < Instruction
|
|
|
|
property register : Int32
|
|
|
|
property value : Int32
|
|
|
|
|
2018-07-27 00:06:33 -07:00
|
|
|
def initialize(@register, @value)
|
2018-07-26 19:47:56 -07:00
|
|
|
end
|
|
|
|
|
|
|
|
def to_s(io)
|
|
|
|
io << "load R"
|
|
|
|
@register.to_s(16, io)
|
|
|
|
io << " " << @value
|
|
|
|
end
|
2018-07-27 19:56:26 -07:00
|
|
|
|
|
|
|
def to_bin(i, index)
|
|
|
|
0x6000 | (register << 8) | value
|
|
|
|
end
|
2018-07-26 19:47:56 -07:00
|
|
|
end
|
|
|
|
|
|
|
|
class LoadRegInstruction < Instruction
|
|
|
|
property into : Int32
|
|
|
|
property from : Int32
|
|
|
|
|
2018-07-27 00:06:33 -07:00
|
|
|
def initialize(@into, @from)
|
2018-07-26 19:47:56 -07:00
|
|
|
end
|
|
|
|
|
|
|
|
def to_s(io)
|
|
|
|
io << "loadr R"
|
|
|
|
@into.to_s(16, io)
|
|
|
|
io << " R"
|
|
|
|
@from.to_s(16, io)
|
|
|
|
end
|
2018-07-27 19:56:26 -07:00
|
|
|
|
|
|
|
def to_bin(i, index)
|
|
|
|
0x8000 | (into << 8) | (from << 4)
|
|
|
|
end
|
2018-07-26 19:47:56 -07:00
|
|
|
end
|
|
|
|
|
|
|
|
class OpInstruction < Instruction
|
|
|
|
property op : TokenType
|
|
|
|
property into : Int32
|
|
|
|
property value : Int32
|
|
|
|
|
2018-07-27 00:06:33 -07:00
|
|
|
def initialize(@op, @into, @value)
|
2018-07-26 19:47:56 -07:00
|
|
|
end
|
|
|
|
|
|
|
|
def to_s(io)
|
|
|
|
io << "op " << op << " R"
|
|
|
|
@into.to_s(16, io)
|
|
|
|
io << " " << @value
|
|
|
|
end
|
2018-07-27 19:56:26 -07:00
|
|
|
|
|
|
|
def to_bin(i, index)
|
|
|
|
case op
|
|
|
|
when TokenType::OpAdd
|
|
|
|
return 0x7000 | (into << 8) | value
|
|
|
|
else
|
|
|
|
raise "Invalid instruction"
|
|
|
|
end
|
|
|
|
end
|
2018-07-26 19:47:56 -07:00
|
|
|
end
|
|
|
|
|
|
|
|
class OpRegInstruction < Instruction
|
|
|
|
property op : TokenType
|
|
|
|
property into : Int32
|
|
|
|
property from : Int32
|
|
|
|
|
2018-07-27 00:06:33 -07:00
|
|
|
def initialize(@op, @into, @from)
|
2018-07-26 19:47:56 -07:00
|
|
|
end
|
|
|
|
|
|
|
|
def to_s(io)
|
|
|
|
io << "opr " << op << " R"
|
|
|
|
@into.to_s(16, io)
|
|
|
|
io << " R"
|
|
|
|
@from.to_s(16, io)
|
|
|
|
end
|
2018-07-27 19:56:26 -07:00
|
|
|
|
|
|
|
def to_bin(i, index)
|
|
|
|
code = 0
|
|
|
|
case op
|
|
|
|
when TokenType::OpAdd
|
|
|
|
code = 4
|
|
|
|
when TokenType::OpSub
|
|
|
|
code = 5
|
|
|
|
when TokenType::OpOr
|
|
|
|
code = 1
|
|
|
|
when TokenType::OpAnd
|
|
|
|
code = 2
|
|
|
|
when TokenType::OpXor
|
|
|
|
code = 3
|
|
|
|
else
|
|
|
|
raise "Invalid instruction"
|
|
|
|
end
|
|
|
|
return 0x8000 | (into << 8) | (from << 4) | code
|
|
|
|
end
|
2018-07-26 19:47:56 -07:00
|
|
|
end
|
|
|
|
|
|
|
|
class StoreInstruction < Instruction
|
|
|
|
property up_to : Int32
|
|
|
|
|
2018-07-27 00:06:33 -07:00
|
|
|
def initialize(@up_to)
|
2018-07-26 19:47:56 -07:00
|
|
|
end
|
|
|
|
|
|
|
|
def to_s(io)
|
|
|
|
io << "store R"
|
|
|
|
@up_to.to_s(16, io)
|
|
|
|
end
|
2018-07-27 19:56:26 -07:00
|
|
|
|
|
|
|
def to_bin(i, index)
|
|
|
|
return 0xf055 | (up_to << 8)
|
|
|
|
end
|
2018-07-26 19:47:56 -07:00
|
|
|
end
|
|
|
|
|
|
|
|
class RestoreInstruction < Instruction
|
|
|
|
property up_to : Int32
|
|
|
|
|
2018-07-27 00:06:33 -07:00
|
|
|
def initialize(@up_to)
|
2018-07-26 19:47:56 -07:00
|
|
|
end
|
|
|
|
|
|
|
|
def to_s(io)
|
|
|
|
io << "restore R"
|
|
|
|
@up_to.to_s(16, io)
|
|
|
|
end
|
2018-07-27 19:56:26 -07:00
|
|
|
|
|
|
|
def to_bin(i, index)
|
|
|
|
return 0xf065 | (up_to << 8)
|
|
|
|
end
|
2018-07-26 19:47:56 -07:00
|
|
|
end
|
|
|
|
|
|
|
|
class ReturnInstruction < Instruction
|
2018-07-27 18:57:08 -07:00
|
|
|
def initialize()
|
2018-07-26 19:47:56 -07:00
|
|
|
end
|
|
|
|
|
|
|
|
def to_s(io)
|
2018-07-27 18:57:08 -07:00
|
|
|
io << "return"
|
2018-07-26 19:47:56 -07:00
|
|
|
end
|
2018-07-27 00:06:33 -07:00
|
|
|
|
2018-07-27 19:56:26 -07:00
|
|
|
def to_bin(i, index)
|
|
|
|
return 0x00ee
|
2018-07-27 00:06:33 -07:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2018-07-27 18:57:08 -07:00
|
|
|
class JumpRelativeInstruction < Instruction
|
2018-07-27 00:06:33 -07:00
|
|
|
property offset : Int32
|
2018-07-27 18:57:08 -07:00
|
|
|
|
|
|
|
def initialize(@offset)
|
|
|
|
end
|
|
|
|
|
|
|
|
def to_s(io)
|
|
|
|
io << "jr " << @offset
|
|
|
|
end
|
2018-07-27 19:56:26 -07:00
|
|
|
|
|
|
|
def to_bin(i, index)
|
|
|
|
return 0x1000 | ((offset + index) * 2 + 0x200)
|
|
|
|
end
|
2018-07-27 18:57:08 -07:00
|
|
|
end
|
|
|
|
|
|
|
|
class SkipEqInstruction < Instruction
|
2018-07-27 00:06:33 -07:00
|
|
|
property left : Int32
|
|
|
|
property right : Int32
|
|
|
|
|
2018-07-27 18:57:08 -07:00
|
|
|
def initialize(@left, @right)
|
2018-07-27 00:06:33 -07:00
|
|
|
end
|
|
|
|
|
|
|
|
def to_s(io)
|
2018-07-27 18:57:08 -07:00
|
|
|
io << "seq R"
|
|
|
|
@left.to_s(16, io)
|
|
|
|
io << " " << right
|
|
|
|
end
|
2018-07-27 19:56:26 -07:00
|
|
|
|
|
|
|
def to_bin(i, index)
|
|
|
|
return 0x3000 | (left << 8) | right
|
|
|
|
end
|
2018-07-27 18:57:08 -07:00
|
|
|
end
|
|
|
|
|
|
|
|
class SkipNeInstruction < Instruction
|
|
|
|
property left : Int32
|
|
|
|
property right : Int32
|
|
|
|
|
|
|
|
def initialize(@left, @right)
|
|
|
|
end
|
|
|
|
|
|
|
|
def to_s(io)
|
|
|
|
io << "sne R"
|
|
|
|
@left.to_s(16, io)
|
|
|
|
io << " " << right
|
|
|
|
end
|
2018-07-27 19:56:26 -07:00
|
|
|
|
|
|
|
def to_bin(i, index)
|
|
|
|
return 0x4000 | (left << 8) | right
|
|
|
|
end
|
2018-07-27 18:57:08 -07:00
|
|
|
end
|
|
|
|
|
|
|
|
class SkipRegEqInstruction < Instruction
|
|
|
|
property left : Int32
|
|
|
|
property right : Int32
|
|
|
|
|
|
|
|
def initialize(@left, @right)
|
|
|
|
end
|
|
|
|
|
|
|
|
def to_s(io)
|
|
|
|
io << "seqr R"
|
|
|
|
@left.to_s(16, io)
|
|
|
|
io << " R"
|
|
|
|
@right.to_s(16, io)
|
|
|
|
end
|
2018-07-27 19:56:26 -07:00
|
|
|
|
|
|
|
def to_bin(i, index)
|
|
|
|
return 0x5000 | (left << 8) | (right << 4)
|
|
|
|
end
|
2018-07-27 18:57:08 -07:00
|
|
|
end
|
|
|
|
|
|
|
|
class SkipRegNeInstruction < Instruction
|
|
|
|
property left : Int32
|
|
|
|
property right : Int32
|
|
|
|
|
|
|
|
def initialize(@left, @right)
|
|
|
|
end
|
|
|
|
|
|
|
|
def to_s(io)
|
|
|
|
io << "sner R"
|
2018-07-27 00:06:33 -07:00
|
|
|
@left.to_s(16, io)
|
|
|
|
io << " R"
|
|
|
|
@right.to_s(16, io)
|
|
|
|
end
|
2018-07-27 19:56:26 -07:00
|
|
|
|
|
|
|
def to_bin(i, index)
|
|
|
|
return 0x9000 | (left << 8) | (right << 4)
|
|
|
|
end
|
2018-07-27 00:06:33 -07:00
|
|
|
end
|
2018-07-27 18:01:00 -07:00
|
|
|
|
|
|
|
class CallInstruction < Instruction
|
|
|
|
property name : String
|
|
|
|
|
|
|
|
def initialize(@name)
|
|
|
|
end
|
|
|
|
|
|
|
|
def to_s(io)
|
2018-07-27 18:57:08 -07:00
|
|
|
io << "call " << @name
|
2018-07-27 18:01:00 -07:00
|
|
|
end
|
2018-07-27 18:57:08 -07:00
|
|
|
|
2018-07-27 19:56:26 -07:00
|
|
|
def to_bin(i, index)
|
|
|
|
return 0x2000 | (i.table[name]?.as(FunctionEntry).addr * 2 + 0x200)
|
2018-07-27 18:57:08 -07:00
|
|
|
end
|
|
|
|
end
|
2018-07-27 19:56:26 -07:00
|
|
|
|
2018-07-27 18:57:08 -07:00
|
|
|
class SetIStackInstruction < Instruction
|
|
|
|
def to_s(io)
|
|
|
|
io << "setis"
|
|
|
|
end
|
2018-07-27 19:56:26 -07:00
|
|
|
|
|
|
|
def to_bin(i, index)
|
|
|
|
return 0xa000 | (i.stack * 2 + 0x200)
|
|
|
|
end
|
2018-07-27 18:57:08 -07:00
|
|
|
end
|
|
|
|
|
|
|
|
class AddIRegInstruction < Instruction
|
|
|
|
property reg : Int32
|
|
|
|
|
|
|
|
def initialize(@reg)
|
|
|
|
end
|
|
|
|
|
|
|
|
def to_s(io)
|
|
|
|
io << "addi R"
|
|
|
|
reg.to_s(16, io)
|
|
|
|
end
|
2018-07-27 19:56:26 -07:00
|
|
|
|
|
|
|
def to_bin(i, index)
|
|
|
|
return 0xf000 | (reg << 8) | 0x1e
|
|
|
|
end
|
2018-07-27 18:57:08 -07:00
|
|
|
end
|
2018-07-26 19:47:56 -07:00
|
|
|
end
|