Eliminate the ABCD register class constaint in REX encodings.

Some REX-less encodings require an ABCD input because they are looking
at 8-bit registers. This constraint doesn't apply with a REX prefix
where the low 8 bits of all registers are addressable.
This commit is contained in:
Jakob Stoklund Olesen
2017-09-29 15:29:25 -07:00
parent 51a6901a7f
commit c82e68efea
2 changed files with 59 additions and 11 deletions

View File

@@ -4,6 +4,7 @@ Intel Encoding recipes.
from __future__ import absolute_import
from cdsl.isa import EncRecipe
from cdsl.predicates import IsSignedInt, IsEqual, Or
from cdsl.registers import RegClass
from base.formats import Unary, UnaryImm, Binary, BinaryImm, MultiAry
from base.formats import Trap, Call, IndirectCall, Store, Load
from base.formats import IntCompare, FloatCompare
@@ -96,13 +97,26 @@ def replace_put_op(emit, prefix):
return emit.replace('PUT_OP', 'put_' + prefix.lower())
# Register class mapping for no-REX instructions.
NOREX_MAP = {
GPR: GPR8,
FPR: FPR8
}
# Register class mapping for REX instructions. The ABCD constraint no longer
# applies.
REX_MAP = {
ABCD: GPR
}
def map_regs(
regs, # type: Sequence[OperandConstraint]
from_class, # type: OperandConstraint
to_class # type: OperandConstraint
mapping # type: Dict[RegClass, RegClass]
):
# type: (...) -> Sequence[OperandConstraint]
return tuple(to_class if (reg is from_class) else reg for reg in regs)
return tuple(mapping.get(rc, rc) if isinstance(rc, RegClass) else rc
for rc in regs)
class TailRecipe:
@@ -178,11 +192,8 @@ class TailRecipe:
isap=self.isap,
emit=replace_put_op(self.emit, name))
recipe.ins = map_regs(recipe.ins, GPR, GPR8)
recipe.ins = map_regs(recipe.ins, FPR, FPR8)
recipe.outs = map_regs(recipe.outs, GPR, GPR8)
recipe.outs = map_regs(recipe.outs, FPR, FPR8)
recipe.ins = map_regs(recipe.ins, NOREX_MAP)
recipe.outs = map_regs(recipe.outs, NOREX_MAP)
self.recipes[name] = recipe
return (self.recipes[name], bits)
@@ -208,7 +219,7 @@ class TailRecipe:
branch_range = (size, self.branch_range)
if name not in self.recipes:
self.recipes[name] = EncRecipe(
recipe = EncRecipe(
name + self.name,
self.format,
size,
@@ -218,6 +229,10 @@ class TailRecipe:
instp=self.instp,
isap=self.isap,
emit=replace_put_op(self.emit, name))
recipe.ins = map_regs(recipe.ins, REX_MAP)
recipe.outs = map_regs(recipe.outs, REX_MAP)
self.recipes[name] = recipe
return (self.recipes[name], bits)
@staticmethod
@@ -731,7 +746,7 @@ t8jccb_abcd = TailRecipe(
branch_range=8,
emit='''
// test8 r, r.
PUT_OP(0x84, rex2(in_reg0, in_reg0), sink);
PUT_OP((bits & 0xff00) | 0x84, rex2(in_reg0, in_reg0), sink);
modrm_rr(in_reg0, in_reg0, sink);
// Jcc instruction.
sink.put1(bits as u8);
@@ -743,7 +758,7 @@ t8jccd_abcd = TailRecipe(
branch_range=32,
emit='''
// test8 r, r.
PUT_OP(0x84, rex2(in_reg0, in_reg0), sink);
PUT_OP((bits & 0xff00) | 0x84, rex2(in_reg0, in_reg0), sink);
modrm_rr(in_reg0, in_reg0, sink);
// Jcc instruction.
sink.put1(0x0f);