Add spill/fill encodings for Intel ISAs.

To begin with, these are catch-all encodings with a SIB byte and a
32-bit displacement, so they can access any stack slot via both the
stack pointer and the frame pointer.

In the future, we will add encodings for 8-bit displacements as well as
EBP-relative references without a SIB byte.
This commit is contained in:
Jakob Stoklund Olesen
2017-09-22 15:35:11 -07:00
parent 76eb7df9f0
commit 29dfcf5dfb
8 changed files with 217 additions and 6 deletions

View File

@@ -65,7 +65,7 @@ def enc_i32_i64_ld_st(inst, w_bit, recipe, *args, **kwargs):
Add encodings for `inst.i32` to I32.
Add encodings for `inst.i32` to I64 with and without REX.
Add encodings for `inst.i64` to I64 with a REX prefix, using the `w_bit`
argument to determine wheter or not to set the REX.W bit.
argument to determine whether or not to set the REX.W bit.
"""
I32.enc(inst.i32.any, *recipe(*args, **kwargs))
@@ -181,6 +181,8 @@ enc_i32_i64_ld_st(base.store, True, r.st, 0x89)
enc_i32_i64_ld_st(base.store, True, r.stDisp8, 0x89)
enc_i32_i64_ld_st(base.store, True, r.stDisp32, 0x89)
enc_i32_i64(base.spill, r.spSib32, 0x89)
enc_i64(base.istore32.i64.any, r.st, 0x89)
enc_i64(base.istore32.i64.any, r.stDisp8, 0x89)
enc_i64(base.istore32.i64.any, r.stDisp32, 0x89)
@@ -208,6 +210,8 @@ enc_i32_i64_ld_st(base.load, True, r.ld, 0x8b)
enc_i32_i64_ld_st(base.load, True, r.ldDisp8, 0x8b)
enc_i32_i64_ld_st(base.load, True, r.ldDisp32, 0x8b)
enc_i32_i64(base.fill, r.fiSib32, 0x8b)
enc_i64(base.uload32.i64, r.ld, 0x8b)
enc_i64(base.uload32.i64, r.ldDisp8, 0x8b)
enc_i64(base.uload32.i64, r.ldDisp32, 0x8b)
@@ -252,6 +256,12 @@ enc_flt(base.store.f64.any, r.fst, 0x66, 0x0f, 0xd6)
enc_flt(base.store.f64.any, r.fstDisp8, 0x66, 0x0f, 0xd6)
enc_flt(base.store.f64.any, r.fstDisp32, 0x66, 0x0f, 0xd6)
enc_flt(base.fill.f32, r.ffiSib32, 0x66, 0x0f, 0x6e)
enc_flt(base.fill.f64, r.ffiSib32, 0xf3, 0x0f, 0x7e)
enc_flt(base.spill.f32, r.fspSib32, 0x66, 0x0f, 0x7e)
enc_flt(base.spill.f64, r.fspSib32, 0x66, 0x0f, 0xd6)
#
# Function addresses.
#

View File

@@ -8,7 +8,7 @@ from base.formats import Unary, UnaryImm, Binary, BinaryImm, MultiAry
from base.formats import Trap, Call, IndirectCall, Store, Load
from base.formats import IntCompare
from base.formats import RegMove, Ternary, Jump, Branch, FuncAddr
from .registers import GPR, ABCD, FPR, GPR8, FPR8
from .registers import GPR, ABCD, FPR, GPR8, FPR8, StackGPR32, StackFPR32
try:
from typing import Tuple, Dict, Sequence # noqa
@@ -474,6 +474,26 @@ fstDisp32 = TailRecipe(
sink.put4(offset as u32);
''')
# Unary spill with SIB and 32-bit displacement.
spSib32 = TailRecipe(
'spSib32', Unary, size=6, ins=GPR, outs=StackGPR32,
emit='''
let base = stk_base(out_stk0.base);
PUT_OP(bits, rex2(base, in_reg0), sink);
modrm_sib_disp32(in_reg0, sink);
sib_noindex(base, sink);
sink.put4(out_stk0.offset as u32);
''')
fspSib32 = TailRecipe(
'fspSib32', Unary, size=6, ins=FPR, outs=StackFPR32,
emit='''
let base = stk_base(out_stk0.base);
PUT_OP(bits, rex2(base, in_reg0), sink);
modrm_sib_disp32(in_reg0, sink);
sib_noindex(base, sink);
sink.put4(out_stk0.offset as u32);
''')
#
# Load recipes
#
@@ -540,6 +560,26 @@ fldDisp32 = TailRecipe(
sink.put4(offset as u32);
''')
# Unary fill with SIB and 32-bit displacement.
fiSib32 = TailRecipe(
'fiSib32', Unary, size=6, ins=StackGPR32, outs=GPR,
emit='''
let base = stk_base(in_stk0.base);
PUT_OP(bits, rex2(base, out_reg0), sink);
modrm_sib_disp32(out_reg0, sink);
sib_noindex(base, sink);
sink.put4(in_stk0.offset as u32);
''')
ffiSib32 = TailRecipe(
'ffiSib32', Unary, size=6, ins=StackFPR32, outs=FPR,
emit='''
let base = stk_base(in_stk0.base);
PUT_OP(bits, rex2(base, out_reg0), sink);
modrm_sib_disp32(out_reg0, sink);
sib_noindex(base, sink);
sink.put4(in_stk0.offset as u32);
''')
#
# Call/return
#

View File

@@ -23,7 +23,7 @@ data types, and the H-registers even less so. Rather than trying to model the
H-registers accurately, we'll avoid using them in both I32 and I64 modes.
"""
from __future__ import absolute_import
from cdsl.registers import RegBank, RegClass
from cdsl.registers import RegBank, RegClass, Stack
from .defs import ISA
@@ -44,4 +44,10 @@ ABCD = GPR[0:4]
FPR = RegClass(FloatRegs)
FPR8 = FPR[0:8]
# Constraints for stack operands.
# Stack operand with a 32-bit signed displacement from either RBP or RSP.
StackGPR32 = Stack(GPR)
StackFPR32 = Stack(FPR)
RegClass.extract_names(globals())