Add regspill and regfill instructions.
These are parallels to the existing regmove instruction, but the divert the value to and from a stack slot. Like regmove diversions, this is a temporary diversion that must be local to the EBB.
This commit is contained in:
@@ -58,6 +58,10 @@ StackStore = InstructionFormat(VALUE, stack_slot, offset32)
|
||||
HeapAddr = InstructionFormat(heap, VALUE, uimm32)
|
||||
|
||||
RegMove = InstructionFormat(VALUE, ('src', regunit), ('dst', regunit))
|
||||
RegSpill = InstructionFormat(
|
||||
VALUE, ('src', regunit), ('dst', entities.stack_slot))
|
||||
RegFill = InstructionFormat(
|
||||
VALUE, ('src', entities.stack_slot), ('dst', regunit))
|
||||
|
||||
Trap = InstructionFormat(trapcode)
|
||||
CondTrap = InstructionFormat(VALUE, trapcode)
|
||||
|
||||
@@ -514,6 +514,34 @@ regmove = Instruction(
|
||||
ins=(x, src, dst),
|
||||
other_side_effects=True)
|
||||
|
||||
regspill = Instruction(
|
||||
'regspill', r"""
|
||||
Temporarily divert ``x`` from ``src`` to ``SS``.
|
||||
|
||||
This instruction moves the location of a value from a register to a
|
||||
stack slot without creating a new SSA value. It is used by the register
|
||||
allocator to temporarily rearrange register assignments in order to
|
||||
satisfy instruction constraints.
|
||||
|
||||
See also :inst:`regmove`.
|
||||
""",
|
||||
ins=(x, src, SS),
|
||||
other_side_effects=True)
|
||||
|
||||
|
||||
regfill = Instruction(
|
||||
'regfill', r"""
|
||||
Temporarily divert ``x`` from ``SS`` to ``dst``.
|
||||
|
||||
This instruction moves the location of a value from a stack slot to a
|
||||
register without creating a new SSA value. It is used by the register
|
||||
allocator to temporarily rearrange register assignments in order to
|
||||
satisfy instruction constraints.
|
||||
|
||||
See also :inst:`regmove`.
|
||||
""",
|
||||
ins=(x, SS, dst),
|
||||
other_side_effects=True)
|
||||
#
|
||||
# Vector operations
|
||||
#
|
||||
|
||||
@@ -32,7 +32,7 @@ def gen_recipe(recipe, fmt):
|
||||
for o in recipe.outs)
|
||||
|
||||
# Regmove instructions get special treatment.
|
||||
is_regmove = (recipe.format.name == 'RegMove')
|
||||
is_regmove = (recipe.format.name in ('RegMove', 'RegSpill', 'RegFill'))
|
||||
|
||||
# First unpack the instruction.
|
||||
with fmt.indented(
|
||||
@@ -111,6 +111,10 @@ def gen_recipe(recipe, fmt):
|
||||
# diversion tracker.
|
||||
if recipe.format.name == 'RegMove':
|
||||
fmt.line('divert.regmove(arg, src, dst);')
|
||||
elif recipe.format.name == 'RegSpill':
|
||||
fmt.line('divert.regspill(arg, src, dst);')
|
||||
elif recipe.format.name == 'RegFill':
|
||||
fmt.line('divert.regfill(arg, src, dst);')
|
||||
|
||||
# Call hand-written code. If the recipe contains a code snippet, use
|
||||
# that. Otherwise cal a recipe function in the target ISA's binemit
|
||||
|
||||
Reference in New Issue
Block a user