summaryrefslogtreecommitdiff
path: root/src/Opcodes.scala
diff options
context:
space:
mode:
Diffstat (limited to 'src/Opcodes.scala')
-rw-r--r--src/Opcodes.scala87
1 files changed, 87 insertions, 0 deletions
diff --git a/src/Opcodes.scala b/src/Opcodes.scala
new file mode 100644
index 0000000..7207f48
--- /dev/null
+++ b/src/Opcodes.scala
@@ -0,0 +1,87 @@
+package ixee.re.disasm
+
+import ixee.cryptopals.utils.ByteUtils._
+import ixee.cryptopals.utils.FunctionUtils._
+
+import scala.collection.mutable.Map
+
+sealed trait OpCode {
+ def instrName: String
+ override def toString: String = instrName
+}
+
+sealed trait NoOpCode extends OpCode
+sealed trait OneOpCode extends OpCode
+sealed trait TwoOpCode extends OpCode
+
+object Opcodes {
+ def opcodes: Map[Int, OpCode] = noOpCodes ++ oneOpCodes ++ twoOpCodes
+ val noOpCodes: Map[Int, NoOpCode] = Map()
+ val oneOpCodes: Map[Int, OneOpCode] = Map()
+ val twoOpCodes: Map[Int, TwoOpCode] = Map()
+
+ def apply(value: Int) = opcodes.get(value)
+ def noOp(value: Int) = noOpCodes.get(value)
+ def oneOp(value: Int) = oneOpCodes.get(value)
+ def twoOp(value: Int) = twoOpCodes.get(value)
+
+ object NoOpCodes {
+ val Prefix = 0x01
+ case class Code(value: Byte, name: String) extends NoOpCode { def instrName = name }
+ object Code {
+ def apply(value: Int, name: String) = new Code(value.toByte, name).tap(code => noOpCodes += ((((Prefix << 3) + value) << 10) -> code))
+ }
+
+ Code(0x00, "JNE")
+ Code(0x01, "JEQ")
+ Code(0x02, "JNC")
+ Code(0x03, "JC ")
+ Code(0x04, "JN ")
+ Code(0x05, "JGE")
+ Code(0x06, "JL ")
+ Code(0x07, "JMP")
+ }
+
+ object OneOpCodes {
+ val Prefix = 0x04
+ case class Code(value: Byte, name: String) extends OneOpCode { def instrName = name }
+ object Code {
+ def apply(value: Int, name: String) = new Code(value.toByte, name).tap(code => oneOpCodes += ((((Prefix << 3) + value) << 7) -> code))
+ }
+
+ Code(0x00, "RRC")
+ Code(0x01, "SWPB")
+ Code(0x02, "RRA")
+ Code(0x03, "SXT")
+ Code(0x04, "PUSH")
+ Code(0x05, "CALL")
+ Code(0x06, "RETI")
+// Code(0x07, "NotImplemented")
+ }
+
+ object TwoOpCodes {
+ val Prefix = 0x1
+ case class Code(value: Byte, name: String) extends TwoOpCode { def instrName = name }
+ object Code {
+ def apply(value: Int, name: String) = new Code(value.toByte, name).tap(code => twoOpCodes += ((value @<< 12) -> code))
+ }
+
+ Code(0x04, "MOV")
+ Code(0x05, "ADD")
+ Code(0x06, "ADDC")
+ Code(0x07, "SUBC")
+ Code(0x08, "SUB")
+ Code(0x09, "CMP")
+ Code(0x0a, "DADD")
+ Code(0x0b, "BIT")
+ Code(0x0c, "BIC")
+ Code(0x0d, "BIS")
+ Code(0x0e, "XOR")
+ Code(0x0f, "AND")
+ }
+
+ // forces the various opcode bodies to be evaluated. kinda weird, but it works so welp.
+ NoOpCodes
+ OneOpCodes
+ TwoOpCodes
+}