ARM: Make the addressing mode 3 loads/stores use the externally defined instructions.
This commit is contained in:
@@ -90,16 +90,7 @@ format DataOp {
|
||||
0x19: WarnUnimpl::ldrex();
|
||||
}
|
||||
}
|
||||
format AddrMode3 {
|
||||
0xb: strh_ldrh(store, {{ Mem.uh = Rd; }},
|
||||
load, {{ Rd = Mem.uh; }});
|
||||
0xd: ldrd_ldrsb(load, {{ Rde = bits(Mem.ud, 31, 0);
|
||||
Rdo = bits(Mem.ud, 63, 32); }},
|
||||
load, {{ Rd = Mem.sb; }});
|
||||
0xf: strd_ldrsh(store, {{ Mem.ud = (Rde.ud & mask(32)) |
|
||||
(Rdo.ud << 32); }},
|
||||
load, {{ Rd = Mem.sh; }});
|
||||
}
|
||||
0xb, 0xd, 0xf: AddrMode3::addrMode3();
|
||||
}
|
||||
0: decode IS_MISC {
|
||||
0: decode OPCODE {
|
||||
|
||||
@@ -38,7 +38,8 @@
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Authors: Stephen Hines
|
||||
// Authors: Gabe Black
|
||||
// Stephen Hines
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
@@ -83,30 +84,15 @@ def template LoadStoreConstructor {{
|
||||
}
|
||||
}};
|
||||
|
||||
let {{
|
||||
def buildPUBWLCase(p, u, b, w, l):
|
||||
return (p << 4) + (u << 3) + (b << 2) + (w << 1) + (l << 0)
|
||||
|
||||
def buildMode3Inst(p, u, i, w, type, code, mnem):
|
||||
op = ("-", "+")[u]
|
||||
offset = ("%s Rm", "%s hilo")[i] % op
|
||||
ea_code = "EA = Rn %s;" % ("", offset)[p]
|
||||
if p == 0 or w == 1:
|
||||
code += "Rn = Rn %s;" % offset
|
||||
newSuffix = "_P%dU%dI%dW%d" % (p, u, i, w)
|
||||
suffix = ("Reg", "Hilo")[i]
|
||||
return LoadStoreBase(mnem, mnem.capitalize() + newSuffix,
|
||||
ea_code, code, mem_flags = [], inst_flags = [],
|
||||
base_class = 'Memory' + suffix,
|
||||
exec_template_base = type.capitalize())
|
||||
}};
|
||||
|
||||
def format AddrMode2(imm) {{
|
||||
if eval(imm):
|
||||
imm = True
|
||||
else:
|
||||
imm = False
|
||||
|
||||
def buildPUBWLCase(p, u, b, w, l):
|
||||
return (p << 4) + (u << 3) + (b << 2) + (w << 1) + (l << 0)
|
||||
|
||||
header_output = decoder_output = exec_output = ""
|
||||
decode_block = "switch(PUBWL) {\n"
|
||||
|
||||
@@ -117,7 +103,7 @@ def format AddrMode2(imm) {{
|
||||
for b in (0, 1):
|
||||
for w in (0, 1):
|
||||
post = (p == 0)
|
||||
user = (p == 0 and w == 0)
|
||||
user = (p == 0 and w == 1)
|
||||
writeback = (p == 0 or w == 1)
|
||||
add = (u == 1)
|
||||
if b == 0:
|
||||
@@ -163,44 +149,112 @@ def format AddrMode2(imm) {{
|
||||
}'''
|
||||
}};
|
||||
|
||||
def format AddrMode3(l0Type, l0Code, l1Type, l1Code) {{
|
||||
l0Code = ArmGenericCodeSubs(l0Code);
|
||||
l1Code = ArmGenericCodeSubs(l1Code);
|
||||
def format AddrMode3() {{
|
||||
decode = '''
|
||||
{
|
||||
const uint32_t op1 = bits(machInst, 24, 20);
|
||||
const uint32_t op2 = bits(machInst, 6, 5);
|
||||
const uint32_t puiw = bits(machInst, 24, 21);
|
||||
const uint32_t imm = IMMED_HI_11_8 << 4 | IMMED_LO_3_0;
|
||||
switch (op2) {
|
||||
case 0x1:
|
||||
if (op1 & 0x1) {
|
||||
%(ldrh)s
|
||||
} else {
|
||||
%(strh)s
|
||||
}
|
||||
case 0x2:
|
||||
if (op1 & 0x1) {
|
||||
%(ldrsb)s
|
||||
} else {
|
||||
%(ldrd)s
|
||||
}
|
||||
case 0x3:
|
||||
if (op1 & 0x1) {
|
||||
%(ldrsh)s
|
||||
} else {
|
||||
%(strd)s
|
||||
}
|
||||
default:
|
||||
return new Unknown(machInst);
|
||||
}
|
||||
}
|
||||
'''
|
||||
|
||||
header_output = decoder_output = exec_output = ""
|
||||
decode_block = "switch(PUBWL) {\n"
|
||||
(l0Mnem, l1Mnem) = name.split("_");
|
||||
def decodePuiwCase(load, d, p, u, i, w, size=4, sign=False):
|
||||
post = (p == 0)
|
||||
user = (p == 0 and w == 1)
|
||||
writeback = (p == 0 or w == 1)
|
||||
add = (u == 1)
|
||||
caseVal = (p << 3) + (u << 2) + (i << 1) + (w << 0)
|
||||
decode = '''
|
||||
case %#x:
|
||||
return new '''% caseVal
|
||||
if add:
|
||||
addStr = "true"
|
||||
else:
|
||||
addStr = "false"
|
||||
if i:
|
||||
if load:
|
||||
if d:
|
||||
className = loadDoubleImmClassName(post, add, writeback)
|
||||
else:
|
||||
className = loadImmClassName(post, add, writeback, \
|
||||
size=size, sign=sign, \
|
||||
user=user)
|
||||
else:
|
||||
if d:
|
||||
className = storeDoubleImmClassName(post, add, writeback)
|
||||
else:
|
||||
className = storeImmClassName(post, add, writeback, \
|
||||
size=size, sign=sign, \
|
||||
user=user)
|
||||
decode += ("%s(machInst, RT, RN, %s, imm);\n" % \
|
||||
(className, addStr))
|
||||
else:
|
||||
if load:
|
||||
if d:
|
||||
className = loadDoubleRegClassName(post, add, writeback)
|
||||
else:
|
||||
className = loadRegClassName(post, add, writeback, \
|
||||
size=size, sign=sign, \
|
||||
user=user)
|
||||
else:
|
||||
if d:
|
||||
className = storeDoubleRegClassName(post, add, writeback)
|
||||
else:
|
||||
className = storeRegClassName(post, add, writeback, \
|
||||
size=size, sign=sign, \
|
||||
user=user)
|
||||
decode += ("%s(machInst, RT, RN, %s, 0, LSL, RM);\n" % \
|
||||
(className, addStr))
|
||||
return decode
|
||||
|
||||
# Loop over all the values of p, u, i, w and l and build instructions and
|
||||
# a decode block for them.
|
||||
for (l, type, code, mnem) in ((0, l0Type, l0Code, l0Mnem),
|
||||
(1, l1Type, l1Code, l1Mnem)):
|
||||
def decodePuiw(load, d, size=4, sign=False):
|
||||
global decodePuiwCase
|
||||
decode = "switch (puiw) {\n"
|
||||
for p in (0, 1):
|
||||
wset = (0, 1)
|
||||
if (p == 0):
|
||||
wset = (0,)
|
||||
for u in (0, 1):
|
||||
for i in (0, 1):
|
||||
for w in wset:
|
||||
(new_header_output,
|
||||
new_decoder_output,
|
||||
new_decode_block,
|
||||
new_exec_output) = buildMode3Inst(p, u, i, w,
|
||||
type, code, mnem)
|
||||
header_output += new_header_output
|
||||
decoder_output += new_decoder_output
|
||||
exec_output += new_exec_output
|
||||
decode_block += '''
|
||||
case %#x:
|
||||
{%s}
|
||||
break;
|
||||
''' % (buildPUBWLCase(p,u,i,w,l), new_decode_block)
|
||||
for w in (0, 1):
|
||||
decode += decodePuiwCase(load, d, p, u, i, w,
|
||||
size, sign)
|
||||
decode += '''
|
||||
default:
|
||||
return new Unknown(machInst);
|
||||
}
|
||||
'''
|
||||
return decode
|
||||
|
||||
decode_block += '''
|
||||
default:
|
||||
return new Unknown(machInst);
|
||||
break;
|
||||
}'''
|
||||
subs = {
|
||||
"ldrh" : decodePuiw(True, False, size=2),
|
||||
"strh" : decodePuiw(False, False, size=2),
|
||||
"ldrsb" : decodePuiw(True, False, size=1, sign=True),
|
||||
"ldrd" : decodePuiw(True, True),
|
||||
"ldrsh" : decodePuiw(True, False, size=2, sign=True),
|
||||
"strd" : decodePuiw(False, True)
|
||||
}
|
||||
decode_block = decode % subs
|
||||
}};
|
||||
|
||||
def format Thumb32LoadWord() {{
|
||||
|
||||
Reference in New Issue
Block a user