ARM: Make the addressing mode 3 loads/stores use the externally defined instructions.

This commit is contained in:
Gabe Black
2010-06-02 12:58:01 -05:00
parent 36b6ca2ce3
commit 55465844dc
2 changed files with 107 additions and 62 deletions

View File

@@ -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 {

View File

@@ -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() {{