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:
@@ -104,4 +104,37 @@ ebb1(v31: i64):
|
||||
return v31
|
||||
}
|
||||
|
||||
function #0000001a(i64 vmctx [%r14]) -> i64 [%rax] spiderwasm {
|
||||
gv0 = vmctx+48
|
||||
sig0 = (i32 [%rdi], i64 [%rsi], i64 vmctx [%r14], i64 sigid [%rbx]) -> i64 [%rax] spiderwasm
|
||||
|
||||
ebb0(v0: i64):
|
||||
v1 = iconst.i32 32
|
||||
v2 = iconst.i64 64
|
||||
v3 = iconst.i32 9
|
||||
v4 = iconst.i64 1063
|
||||
v5 = iadd_imm v0, 48
|
||||
v6 = load.i32 v5
|
||||
v7 = icmp uge v3, v6
|
||||
; If we're unlucky, there are no ABCD registers available for v7 at this branch.
|
||||
brz v7, ebb2
|
||||
trap oob
|
||||
|
||||
ebb2:
|
||||
v8 = load.i64 v5+8
|
||||
v9 = uextend.i64 v3
|
||||
v16 = iconst.i64 16
|
||||
v10 = imul v9, v16
|
||||
v11 = iadd v8, v10
|
||||
v12 = load.i64 v11
|
||||
brnz v12, ebb3
|
||||
trap icall_null
|
||||
|
||||
ebb3:
|
||||
v13 = load.i64 v11+8
|
||||
v14 = call_indirect.i64 sig0, v12(v1, v2, v13, v4)
|
||||
jump ebb1(v14)
|
||||
|
||||
ebb1(v15: i64):
|
||||
return v15
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user