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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
package ixee.re.disasm
import ixee.cryptopals.utils.ByteUtils._
import ixee.cryptopals.utils.FunctionUtils._
import scala.collection.mutable.Map
sealed trait AddressingMode {
def name: String
def wide: Boolean
override def toString: String = name
def nameifyRegister(reg: Int): String = reg match {
case 0 => "pc"
case 1 => "sp"
case 2 => "sr"
case 3 => "cg"
case num @ _ => s"r$num"
}
}
sealed trait NormMode extends AddressingMode {
def wide = false
def stringifyWith(reg: Int): String
}
sealed trait WideMode extends AddressingMode {
def wide = true
def stringifyWith(reg: Int, word: Int): String
}
sealed trait OneOpAddressing extends AddressingMode
sealed trait TwoOpAddressing extends AddressingMode
sealed trait TwoOpSourceAddressing extends TwoOpAddressing
sealed trait TwoOpDestAddressing extends TwoOpAddressing
object TwoOpSourceAddressingModes {
// just alias the apply over to make names look right at call sites.
// think hard about refactoring this
def apply(register: Int, mode: Int): Option[TwoOpSourceAddressing] = OneOpAddressingModes(register, mode)
}
object OneOpAddressingModes {
trait AddressingMode extends OneOpAddressing with TwoOpSourceAddressing
def apply(register: Int, mode: Int): Option[AddressingMode] = register match {
case 0 => PCModes(mode) orElse General(mode)
case 2 => SRModes(mode) orElse General(mode)
case 3 => CGModes(mode) orElse General(mode)
case _ => General(mode)
}
trait Modes {
private val modeMap: Map[Int, AddressingMode] = Map()
case class Mode(as: Int, name: String, stringifier: String => String) extends AddressingMode with NormMode {
modeMap += as -> this
def stringifyWith(reg: Int): String = stringifier(nameifyRegister(reg))
}
case class ExtraByteMode(as: Int, name: String, stringifier: (String, Int) => String) extends AddressingMode with WideMode {
modeMap += as -> this
def stringifyWith(reg: Int, const: Int): String = stringifier(nameifyRegister(reg), const)
}
def apply(x: Int): Option[AddressingMode] = modeMap.get(x)
}
object PCModes extends Modes {
ExtraByteMode(3, "NextWord", (reg, byte) => s"${if (byte < 0) "-" else ""}0x${"%x".format(Math.abs(byte))}")
}
object SRModes extends Modes {
Mode(2, "Const4", reg => "#4")
Mode(3, "Const8", reg => "#8")
}
object CGModes extends Modes {
Mode(0, "Const0", reg => "#0")
Mode(1, "Const1", reg => "#1")
Mode(2, "Const2", reg => "#2")
Mode(3, "ConstNeg1", reg => "#-1")
}
object General extends Modes {
Mode(0, "RegisterDirect", ident)
ExtraByteMode(1, "Indexed", (reg, byte) => s"${if (byte < 0) "-" else ""}0x${"%x".format(Math.abs(byte))}($reg)")
Mode(2, "RegisterIndirect", reg => s"@$reg")
Mode(3, "IndirectAutoInc", reg => s"@$reg+")
}
PCModes
SRModes
CGModes
General
}
object TwoOpDestAddressingModes {
trait AddressingMode extends TwoOpDestAddressing
def apply(register: Int, mode: Int): Option[AddressingMode] = register match {
case 0 => PCModes(mode) orElse General(mode)
case 2 => SRModes(mode) orElse General(mode)
case _ => General(mode)
}
trait Modes {
private val modeMap: Map[Int, AddressingMode] = Map()
case class Mode(as: Int, name: String, stringifier: String => String) extends AddressingMode with NormMode {
modeMap += as -> this
def stringifyWith(reg: Int): String = stringifier(nameifyRegister(reg))
}
case class ExtraByteMode(as: Int, name: String, stringifier: (String, Int) => String) extends AddressingMode with WideMode {
modeMap += as -> this
def stringifyWith(reg: Int, const: Int): String = stringifier(nameifyRegister(reg), const)
}
def apply(x: Int): Option[AddressingMode] = modeMap.get(x)
}
object PCModes extends Modes {
Mode(1, "Symbolic", reg => s"<??> (symbolic? x(PC)?")
}
object SRModes extends Modes {
ExtraByteMode(1, "Absolute", (reg, byte) => s"&${"%4x".format(byte)}")
}
object General extends Modes {
Mode(0, "RegisterDirect", reg => s"$reg")
ExtraByteMode(1, "Indexed", (reg, byte) => s"${if (byte < 0) "-" else ""}0x${"%x".format(Math.abs(byte))}($reg)")
}
PCModes
SRModes
General
}
|