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:
@@ -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.
|
||||
#
|
||||
|
||||
@@ -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
|
||||
#
|
||||
|
||||
@@ -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())
|
||||
|
||||
Reference in New Issue
Block a user