Start adding Intel 64-bit encodings.

Add a TailRecipe.rex() method which creates an encoding recipe with a
REX prefix.

Define I64 encodings with REX.W for i64 operations and with/without REX
for i32 ops. Only test the with-REX encodings for now. We don't yet have
an instruction shrinking pass that can select the non-REX encodings.
This commit is contained in:
Jakob Stoklund Olesen
2017-07-10 16:16:22 -07:00
parent fb227cb389
commit a4a8c83aab
4 changed files with 365 additions and 18 deletions

View File

@@ -160,6 +160,33 @@ class TailRecipe:
emit=replace_put_op(self.emit, name))
return (self.recipes[name], bits)
def rex(self, *ops, **kwargs):
# type: (*int, **int) -> Tuple[EncRecipe, int]
"""
Create a REX encoding recipe and encoding bits for the opcode bytes in
`ops`.
The recipe will always generate a REX prefix, whether it is required or
not. For instructions that don't require a REX prefix, two encodings
should be added: One with REX and one without.
"""
rrr = kwargs.get('rrr', 0)
w = kwargs.get('w', 0)
name, bits = decode_ops(ops, rrr, w)
name = 'Rex' + name
if name not in self.recipes:
self.recipes[name] = EncRecipe(
name + self.name,
self.format,
1 + len(ops) + self.size,
ins=self.ins,
outs=self.outs,
branch_range=self.branch_range,
instp=self.instp,
isap=self.isap,
emit=replace_put_op(self.emit, name))
return (self.recipes[name], bits)
# XX /r
rr = TailRecipe(
@@ -208,11 +235,21 @@ rid = TailRecipe(
sink.put4(imm as u32);
''')
# XX+rd id unary with 32-bit immediate.
# XX /n id with 32-bit immediate sign-extended. UnaryImm version.
uid = TailRecipe(
'uid', UnaryImm, size=4, ins=(), outs=GPR,
'uid', UnaryImm, size=5, ins=(), outs=GPR,
instp=IsSignedInt(UnaryImm.imm, 32),
emit='''
PUT_OP(bits, rex1(out_reg0), sink);
modrm_r_bits(out_reg0, bits, sink);
let imm: i64 = imm.into();
sink.put4(imm as u32);
''')
# XX+rd id unary with 32-bit immediate. Note no recipe predicate.
puid = TailRecipe(
'uid', UnaryImm, size=4, ins=(), outs=GPR,
emit='''
// The destination register is encoded in the low bits of the opcode.
// No ModR/M.
PUT_OP(bits | (out_reg0 & 7), rex1(out_reg0), sink);
@@ -220,6 +257,15 @@ uid = TailRecipe(
sink.put4(imm as u32);
''')
# XX+rd iq unary with 64-bit immediate.
puiq = TailRecipe(
'uiq', UnaryImm, size=8, ins=(), outs=GPR,
emit='''
PUT_OP(bits | (out_reg0 & 7), rex1(out_reg0), sink);
let imm: i64 = imm.into();
sink.put8(imm as u64);
''')
#
# Store recipes.
#