48 lines
1.7 KiB
Python
48 lines
1.7 KiB
Python
from Lib import RiscV
|
|
from Lib.Operands import Temporary, Operand, S
|
|
from Lib.Statement import Instruction
|
|
from Lib.Allocator import Allocator
|
|
from typing import List, Dict
|
|
|
|
|
|
class AllInMemAllocator(Allocator):
|
|
|
|
def replace(self, old_instr: Instruction) -> List[Instruction]:
|
|
"""Replace Temporary operands with the corresponding allocated
|
|
memory location. FP points to the stack."""
|
|
numreg = 1
|
|
before: List[Instruction] = []
|
|
after: List[Instruction] = []
|
|
subst: Dict[Operand, Operand] = {}
|
|
|
|
old_args = old_instr.args()
|
|
for arg in old_args:
|
|
# We substitute
|
|
subst[arg] = S[numreg]
|
|
numreg += 1
|
|
for arg in old_instr.used():
|
|
# We have to read them from memory
|
|
if(isinstance(arg, Temporary)):
|
|
before.append(RiscV.ld(subst[arg],self._fdata._pool.get_alloced_loc(arg)))
|
|
for arg in old_instr.defined():
|
|
# We have to write them after to memory
|
|
if(isinstance(arg, Temporary)):
|
|
after.append(RiscV.sd(subst[arg],self._fdata._pool.get_alloced_loc(arg)))
|
|
|
|
try:
|
|
new_instr = old_instr.substitute(subst)
|
|
except Exception:
|
|
# We have an instruction that doesn't need substitution
|
|
return [old_instr]
|
|
return before + [new_instr] + after
|
|
|
|
def prepare(self):
|
|
"""Allocate all temporaries to memory.
|
|
Invariants:
|
|
- Expanded instructions can use s2 and s3
|
|
(to store the values of temporaries before the actual instruction).
|
|
"""
|
|
self._fdata._pool.set_temp_allocation(
|
|
{temp: self._fdata.fresh_offset()
|
|
for temp in self._fdata._pool.get_all_temps()})
|