diff --git a/src/main/java/kc875/asm/visit/RegAllocationNaiveVisitor.java b/src/main/java/kc875/asm/visit/RegAllocationNaiveVisitor.java index c57de70..2a438ac 100644 --- a/src/main/java/kc875/asm/visit/RegAllocationNaiveVisitor.java +++ b/src/main/java/kc875/asm/visit/RegAllocationNaiveVisitor.java @@ -585,6 +585,36 @@ public List visit(ASMInstr_2Arg i) { ASMExpr r = i.getSrc(); List instrs = new ArrayList<>(); ASMExpr dest; + + // LEAs need a special case + if (i.getOpCode() == ASMOpCode.LEA) { + // LEA's dest must be a register, and its src must be a mem + // when we generate LEAs, we always do so correctly (mem into a temp) + if (l instanceof ASMExprTemp) { + List availRegs = getAvailRegs(getRegsInExpr(r)); // mem expression may contain registers + dest = new ASMExprReg(availRegs.get(0)); + + instrs.add(new ASMInstr_2Arg( + ASMOpCode.LEA, + dest, + r // has to be a mem + )); + + // now, we need to spill the left hand side temp onto the stack + ASMExprMem loc = getMemForTemp(((ASMExprTemp) l).getName(), instrs); + instrs.add(new ASMInstr_2Arg( + ASMOpCode.MOV, + loc, + dest + )); + } else { + // lhs has to be a register due to our invariant, so this is fine: + instrs.add(i); + } + + return instrs; + } + if (l instanceof ASMExprTemp) {//if LHS is a temp it gets turned into a mem dest = getMemForTemp(((ASMExprTemp) l).getName(), instrs); } else if (l instanceof ASMExprMem) {// if LHS is a mem it gets turned into a mem