-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathIfAsmBuilder.py
141 lines (133 loc) · 5.18 KB
/
IfAsmBuilder.py
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
133
134
135
136
137
138
139
140
141
import midLevelAssem
from assemNumHelper import AssemNumHelper
from pyLog import pylog
class IfAsmBuilder(object):
@staticmethod
def get_asm_string_for_if(if_type, if_input, compare, destination, register):
skip_load = if_input.lower() == register;
if register:
load = IfAsmBuilder.get_load_for_register(register)
cmp = IfAsmBuilder.get_compare_for_register(register)
else:
load = "bit "
cmp = " N/A "
if not skip_load:
output = ["\t" + load + if_input + "\n"]
else:
output = ["\t"]
if if_type == midLevelAssem.MLAOperator.equal:
output += ["\t" + cmp + compare + "\n"]
output += ["\tbeq " + destination + "\n"]
return output
elif if_type == midLevelAssem.MLAOperator.not_equal:
output += ["\t" + cmp + compare + "\n"]
output += ["bne " + destination + "\n"]
return output
elif if_type == midLevelAssem.MLAOperator.less_than:
output += ["\t" + cmp + compare + "\n"]
output += ["\tbcc " + destination + "\n"]
return output
elif if_type == midLevelAssem.MLAOperator.greater_than:
output += ["\t" + cmp + compare + "\n"]
output += ["\tbeq + \n"]
output += ["\tbcs " + destination + "\n"]
output += ["+ \n"]
return output
elif if_type == midLevelAssem.MLAOperator.less_than_equal_to:
output += [cmp + compare + "\n"]
output += ["\tbeq " + destination + "\n"]
output += ["\tbcc " + destination + "\n"]
return output
elif if_type == midLevelAssem.MLAOperator.greater_than_equal_to:
output += ["\t" + cmp + compare + "\n"]
output += ["\tbcs " + destination + "\n"]
return output
elif if_type == midLevelAssem.MLAOperator.zero:
output += ["\tbeq " + destination + "\n"]
return output
elif if_type == midLevelAssem.MLAOperator.not_zero:
output += ["\tbne " + destination + "\n"]
return output
elif if_type == midLevelAssem.MLAOperator.positive:
output += ["\tbpl " + destination + "\n"]
return output
elif if_type == midLevelAssem.MLAOperator.negative:
output += ["\tbmi " + destination + "\n"]
return output
elif if_type == midLevelAssem.MLAOperator.unknown:
return ["!!--------MLA ERROR"]
@staticmethod
def get_asm_string_for_if_bit(match_results, tdm):
src = match_results.group(2).strip()
src_lower = src.lower()
not_version = match_results.group(1)
bit_value = match_results.group(3).strip()
dest = match_results.group(4).strip()
can_use_bit = True
use_bit = False
use_bpl_bmi = False
use_bvc_bvs = False
if (src_lower.endswith(",x") or src_lower.endswith(",y") ):
can_use_bit = False
if AssemNumHelper.is_immediate(bit_value):
value = tdm.lookup_value_for(bit_value)
if isinstance(value, int):
if value == 128:
if can_use_bit:
pylog.write_log("bit #128 to BIT/BPL/BMI")
use_bit = True
use_bpl_bmi = True
else:
pylog.write_log("bit #128 to LDA/BPL/BMI")
use_bpl_bmi = True
if value == 64:
if can_use_bit:
pylog.write_log("bit #64 to BIT/BVC/BVS")
use_bit = True
use_bvc_bvs = True
if src_lower != "a":
if use_bit:
out_string = "\tbit " + src + "\n"
else:
out_string = "\tlda " + src + "\n"
else:
out_string = ""
if not use_bit and not use_bpl_bmi:
out_string += "\tand " + match_results.group(3).strip()+"\n"
if not_version: # then we have a 'not'
if use_bpl_bmi:
out_string += "\tbmi " + dest
elif use_bvc_bvs:
out_string += "\tbvs " + dest
else:
out_string += "\tbne " + dest
else:
if use_bpl_bmi:
out_string += "\tbpl " + dest
elif use_bvc_bvs:
out_string += "\tbvc " + dest
else:
out_string += "\tbeq " + dest
if match_results.group(5):
out_string += "; " + match_results.group(5).strip() + "\n"
else:
out_string += "\n"
return out_string
@staticmethod
def get_load_for_register(register):
if register == "a":
return "lda "
if register == "x":
return "ldx "
if register == "y":
return "ldy "
return "Unknown register " + register
@staticmethod
def get_compare_for_register(register):
if register == "a":
return "cmp "
if register == "x":
return "cpx "
if register == "y":
return "cpy "
return "Unknown register " + register