mirror of https://github.com/aamine/cbc
* net/loveruby/cflat/compiler/CodeGenerator.java: fix local variables offset after compiling function body, to allow saving really-used callee-saved registers only.
* net/loveruby/cflat/asm/IndirectMemoryReference.java: allow fixing offset out of consructor. * net/loveruby/cflat/asm/AsmStatistics.java: new class. * net/loveruby/cflat/asm/Assembly.java: support #collectStatistics. * net/loveruby/cflat/asm/Instruction.java: ditto. * net/loveruby/cflat/asm/AsmOperand.java: ditto. * net/loveruby/cflat/asm/Register.java: ditto. * net/loveruby/cflat/asm/AbsoluteAddress.java: ditto. * net/loveruby/cflat/asm/DirectMemoryReference.java: ditto. * net/loveruby/cflat/asm/ImmediateValue.java: ditto. * net/loveruby/cflat/ast/Scope.java: refactoring: rename method: #allChildren -> #allScopes. * net/loveruby/cflat/ast/Scope.java (allScopes): should include receiver scope itself. * net/loveruby/cflat/ast/LocalScope.java (allVariables): did not wrongly included current scope's variables. * net/loveruby/cflat/ast/LocalScope.java: refactoring: rename method: allVariables -> allLocalVariables. * net/loveruby/cflat/ast/DefinedFunction.java: ditto. git-svn-id: file:///Users/aamine/c/gitwork/public/cbc/trunk@4040 1b9489fe-b721-0410-924e-b54b9192deb8
This commit is contained in:
parent
076d0dea13
commit
1668b72403
40
ChangeLog
40
ChangeLog
|
|
@ -1,3 +1,43 @@
|
|||
Sun Sep 21 03:04:16 2008 Minero Aoki <aamine@loveruby.net>
|
||||
|
||||
* net/loveruby/cflat/compiler/CodeGenerator.java: fix local
|
||||
variables offset after compiling function body, to allow saving
|
||||
really-used callee-saved registers only.
|
||||
|
||||
* net/loveruby/cflat/asm/IndirectMemoryReference.java: allow
|
||||
fixing offset out of consructor.
|
||||
|
||||
* net/loveruby/cflat/asm/AsmStatistics.java: new class.
|
||||
|
||||
* net/loveruby/cflat/asm/Assembly.java: support
|
||||
#collectStatistics.
|
||||
|
||||
* net/loveruby/cflat/asm/Instruction.java: ditto.
|
||||
|
||||
* net/loveruby/cflat/asm/AsmOperand.java: ditto.
|
||||
|
||||
* net/loveruby/cflat/asm/Register.java: ditto.
|
||||
|
||||
* net/loveruby/cflat/asm/AbsoluteAddress.java: ditto.
|
||||
|
||||
* net/loveruby/cflat/asm/DirectMemoryReference.java: ditto.
|
||||
|
||||
* net/loveruby/cflat/asm/ImmediateValue.java: ditto.
|
||||
|
||||
* net/loveruby/cflat/ast/Scope.java: refactoring: rename method:
|
||||
#allChildren -> #allScopes.
|
||||
|
||||
* net/loveruby/cflat/ast/Scope.java (allScopes): should include
|
||||
receiver scope itself.
|
||||
|
||||
* net/loveruby/cflat/ast/LocalScope.java (allVariables): did not
|
||||
wrongly included current scope's variables.
|
||||
|
||||
* net/loveruby/cflat/ast/LocalScope.java: refactoring: rename
|
||||
method: allVariables -> allLocalVariables.
|
||||
|
||||
* net/loveruby/cflat/ast/DefinedFunction.java: ditto.
|
||||
|
||||
Sat Sep 20 23:48:31 2008 Minero Aoki <aamine@loveruby.net>
|
||||
|
||||
* net/loveruby/cflat/compiler/Options.java: new option -O0, -O,
|
||||
|
|
|
|||
|
|
@ -11,6 +11,10 @@ public class AbsoluteAddress extends AsmOperand {
|
|||
return this.register;
|
||||
}
|
||||
|
||||
public void collectStatistics(AsmStatistics stats) {
|
||||
register.collectStatistics(stats);
|
||||
}
|
||||
|
||||
public String toSource() {
|
||||
return "*" + register.toSource();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,8 @@ abstract public class AsmOperand implements OperandPattern {
|
|||
return null;
|
||||
}
|
||||
|
||||
abstract public void collectStatistics(AsmStatistics stats);
|
||||
|
||||
// default implementation
|
||||
public boolean match(AsmOperand operand) {
|
||||
return equals(operand);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,52 @@
|
|||
package net.loveruby.cflat.asm;
|
||||
import java.util.*;
|
||||
|
||||
public class AsmStatistics {
|
||||
protected Map registerUsage;
|
||||
protected Map insnUsage;
|
||||
|
||||
static public AsmStatistics collect(List assemblies) {
|
||||
AsmStatistics stats = new AsmStatistics();
|
||||
Iterator asms = assemblies.iterator();
|
||||
while (asms.hasNext()) {
|
||||
Assembly asm = (Assembly)asms.next();
|
||||
asm.collectStatistics(stats);
|
||||
}
|
||||
return stats;
|
||||
}
|
||||
|
||||
public AsmStatistics() {
|
||||
registerUsage = new HashMap();
|
||||
insnUsage = new HashMap();
|
||||
}
|
||||
|
||||
public int numRegisterUsage(String name) {
|
||||
return fetchCount(registerUsage, name);
|
||||
}
|
||||
|
||||
public void registerUsed(String name) {
|
||||
incrementCount(registerUsage, name);
|
||||
}
|
||||
|
||||
public int numInstructionUsage(String insn) {
|
||||
return fetchCount(insnUsage, insn);
|
||||
}
|
||||
|
||||
public void instructionUsed(String insn) {
|
||||
incrementCount(insnUsage, insn);
|
||||
}
|
||||
|
||||
protected int fetchCount(Map m, String name) {
|
||||
Integer n = (Integer)m.get(name);
|
||||
if (n == null) {
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
return n.intValue();
|
||||
}
|
||||
}
|
||||
|
||||
protected void incrementCount(Map m, String name) {
|
||||
m.put(name, new Integer(fetchCount(m, name) + 1));
|
||||
}
|
||||
}
|
||||
|
|
@ -10,4 +10,8 @@ abstract public class Assembly {
|
|||
public boolean isLabel() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void collectStatistics(AsmStatistics stats) {
|
||||
// does nothing by default.
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,10 @@ public class DirectMemoryReference extends MemoryReference {
|
|||
return this.value;
|
||||
}
|
||||
|
||||
public void collectStatistics(AsmStatistics stats) {
|
||||
// does nothing
|
||||
}
|
||||
|
||||
public String toSource() {
|
||||
return this.value.toSource();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,10 @@ public class ImmediateValue extends AsmOperand {
|
|||
return this.expr;
|
||||
}
|
||||
|
||||
public void collectStatistics(AsmStatistics stats) {
|
||||
// does nothing
|
||||
}
|
||||
|
||||
public String toSource() {
|
||||
return "$" + expr.toSource();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,25 +3,44 @@ package net.loveruby.cflat.asm;
|
|||
public class IndirectMemoryReference extends MemoryReference {
|
||||
protected long offset;
|
||||
protected Register base;
|
||||
protected boolean fixed;
|
||||
|
||||
public IndirectMemoryReference(Register base) {
|
||||
this(0, base);
|
||||
this.offset = 0;
|
||||
this.base = base;
|
||||
this.fixed = false;
|
||||
}
|
||||
|
||||
public IndirectMemoryReference(long offset, Register base) {
|
||||
this.offset = offset;
|
||||
this.base = base;
|
||||
this.fixed = true;
|
||||
}
|
||||
|
||||
public long offset() {
|
||||
return offset;
|
||||
}
|
||||
|
||||
public void fixOffset(long realOffset) {
|
||||
if (fixed) {
|
||||
throw new Error("must not happen: fixed = true");
|
||||
}
|
||||
this.offset = realOffset;
|
||||
this.fixed = true;
|
||||
}
|
||||
|
||||
public Register base() {
|
||||
return base;
|
||||
}
|
||||
|
||||
public void collectStatistics(AsmStatistics stats) {
|
||||
base.collectStatistics(stats);
|
||||
}
|
||||
|
||||
public String toSource() {
|
||||
if (! fixed) {
|
||||
throw new Error("must not happen: writing unfixed variable");
|
||||
}
|
||||
return (offset == 0 ? "" : "" + offset) + "(" + base.toSource() + ")";
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,6 +53,13 @@ public class Instruction extends Assembly {
|
|||
return this.operands[1];
|
||||
}
|
||||
|
||||
public void collectStatistics(AsmStatistics stats) {
|
||||
stats.instructionUsed(mnemonic);
|
||||
for (int i = 0; i < operands.length; i++) {
|
||||
operands[i].collectStatistics(stats);
|
||||
}
|
||||
}
|
||||
|
||||
public String toSource() {
|
||||
StringBuffer buf = new StringBuffer();
|
||||
buf.append("\t");
|
||||
|
|
|
|||
|
|
@ -61,6 +61,10 @@ public class Register extends AsmOperand {
|
|||
return false;
|
||||
}
|
||||
|
||||
public void collectStatistics(AsmStatistics stats) {
|
||||
stats.registerUsed(name);
|
||||
}
|
||||
|
||||
public String toSource() {
|
||||
return "%" + name();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ public class DefinedFunction extends Function {
|
|||
* Does NOT include static local variables.
|
||||
*/
|
||||
public Iterator localVariables() {
|
||||
return scope.allVariables();
|
||||
return scope.allLocalVariables();
|
||||
}
|
||||
|
||||
class JumpEntry {
|
||||
|
|
|
|||
|
|
@ -38,8 +38,9 @@ public class DefinedVariable extends Variable {
|
|||
}
|
||||
|
||||
public MemoryReference memref() {
|
||||
if (memref == null)
|
||||
if (memref == null) {
|
||||
throw new Error("unresolved variable address");
|
||||
}
|
||||
return memref;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,14 +19,21 @@ public class LocalScope extends Scope {
|
|||
return children.iterator();
|
||||
}
|
||||
|
||||
// Returns local variables defined in this scope.
|
||||
// Does includes all nested local variables.
|
||||
// Does NOT include static local variables.
|
||||
/**
|
||||
* Returns local variables defined in this scope.
|
||||
* Does NOT includes children's local variables.
|
||||
* Does NOT include static local variables.
|
||||
*/
|
||||
public Iterator variables() {
|
||||
return variablesList().iterator();
|
||||
return lvarList().iterator();
|
||||
}
|
||||
|
||||
protected List variablesList() {
|
||||
/**
|
||||
* Returns local variables defined in this scope.
|
||||
* Does NOT includes children's local variables.
|
||||
* Does NOT include static local variables.
|
||||
*/
|
||||
protected List lvarList() {
|
||||
List result = new ArrayList();
|
||||
Iterator ents = entities.values().iterator();
|
||||
while (ents.hasNext()) {
|
||||
|
|
@ -41,9 +48,13 @@ public class LocalScope extends Scope {
|
|||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of all entities in this scope.
|
||||
* Result includes the number of children's entities.
|
||||
*/
|
||||
public long numAllEntities() {
|
||||
if (numAllEntities < 0) {
|
||||
Iterator cs = allChildren();
|
||||
Iterator cs = allScopes().iterator();
|
||||
long n = 0;
|
||||
while (cs.hasNext()) {
|
||||
Scope c = (Scope)cs.next();
|
||||
|
|
@ -54,26 +65,32 @@ public class LocalScope extends Scope {
|
|||
return numAllEntities;
|
||||
}
|
||||
|
||||
// Returns all function local variables defined in this scope.
|
||||
// Does includes all nested local variables.
|
||||
// Does NOT include static local variables.
|
||||
public Iterator allVariables() {
|
||||
return allEntities().iterator();
|
||||
/**
|
||||
* Returns all local variables in this scope.
|
||||
* The result DOES includes all nested local variables,
|
||||
* while it does NOT include static local variables.
|
||||
*/
|
||||
public Iterator allLocalVariables() {
|
||||
return allLocalVariablesList().iterator();
|
||||
}
|
||||
|
||||
protected List allEntities() {
|
||||
// List<DefinedVariable>
|
||||
protected List allLocalVariablesList() {
|
||||
List result = new ArrayList();
|
||||
Iterator scopes = allChildren();
|
||||
Iterator scopes = allScopes().iterator();
|
||||
while (scopes.hasNext()) {
|
||||
LocalScope s = (LocalScope)scopes.next();
|
||||
result.addAll(s.variablesList());
|
||||
result.addAll(s.lvarList());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all static local variables defined in this scope.
|
||||
*/
|
||||
public List staticLocalVariables() {
|
||||
List result = new ArrayList();
|
||||
Iterator scopes = allChildren();
|
||||
Iterator scopes = allScopes().iterator();
|
||||
while (scopes.hasNext()) {
|
||||
LocalScope s = (LocalScope)scopes.next();
|
||||
Iterator vars = s.entities.values().iterator();
|
||||
|
|
|
|||
|
|
@ -37,20 +37,19 @@ abstract public class Scope {
|
|||
children.add(s);
|
||||
}
|
||||
|
||||
// Returns a list of all child scopes.
|
||||
// Does NOT include myself.
|
||||
protected Iterator allChildren() {
|
||||
// Returns a list of all child scopes including this scope.
|
||||
protected List allScopes() {
|
||||
List result = new ArrayList();
|
||||
collectChildren(result);
|
||||
return result.iterator();
|
||||
collectScope(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
protected void collectChildren(List buf) {
|
||||
protected void collectScope(List buf) {
|
||||
buf.add(this);
|
||||
Iterator cs = children.iterator();
|
||||
while (cs.hasNext()) {
|
||||
Scope c = (Scope)cs.next();
|
||||
buf.add(c);
|
||||
c.collectChildren(buf);
|
||||
c.collectScope(buf);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -187,28 +187,35 @@ public class CodeGenerator extends Visitor implements ASTLHSVisitor {
|
|||
protected void compileFunction(DefinedFunction func) {
|
||||
long numSavedRegs = 0; // 1 for PIC
|
||||
allocateParameters(func);
|
||||
long lvarBytes = allocateLocalVariables(func, numSavedRegs);
|
||||
allocateLocalVariablesTemp(func.body().scope());
|
||||
|
||||
List bodyAsms = compileFunctionBody(func);
|
||||
AsmStatistics stats = AsmStatistics.collect(bodyAsms);
|
||||
List usedCalleeSavedRegs = usedCalleeSavedRegs(stats);
|
||||
long lvarBytes = allocateLocalVariables(func.body().scope(),
|
||||
usedCalleeSavedRegs.size());
|
||||
|
||||
currentFunction = func;
|
||||
String symbol = csymbol(func.name());
|
||||
if (! func.isPrivate()) {
|
||||
_globl(symbol);
|
||||
}
|
||||
_type(symbol, "@function");
|
||||
label(symbol);
|
||||
prologue(func, lvarBytes);
|
||||
compileFunctionBody(func.body());
|
||||
epilogue(func, lvarBytes);
|
||||
prologue(func, usedCalleeSavedRegs, lvarBytes);
|
||||
as.addAll(bodyAsms);
|
||||
epilogue(func, usedCalleeSavedRegs, lvarBytes);
|
||||
_size(symbol, ".-" + symbol);
|
||||
}
|
||||
// #@@}
|
||||
|
||||
protected void compileFunctionBody(Node body) {
|
||||
protected List compileFunctionBody(DefinedFunction func) {
|
||||
currentFunction = func;
|
||||
this.as = newAssembler();
|
||||
compile(body);
|
||||
compile(func.body());
|
||||
List assemblies = this.as.assemblies();
|
||||
this.as = this.assembler;
|
||||
this.as.addAll(optimizer.optimize(assemblies));
|
||||
currentFunction = null;
|
||||
return optimizer.optimize(assemblies);
|
||||
}
|
||||
|
||||
// #@@range/compile{
|
||||
|
|
@ -231,47 +238,45 @@ public class CodeGenerator extends Visitor implements ASTLHSVisitor {
|
|||
}
|
||||
// #@@}
|
||||
|
||||
// #@@range/prologue{
|
||||
protected void prologue(DefinedFunction func, long lvarBytes) {
|
||||
push(bp());
|
||||
mov(sp(), bp());
|
||||
extendStack(lvarBytes);
|
||||
protected List usedCalleeSavedRegs(AsmStatistics stats) {
|
||||
List result = new ArrayList();
|
||||
Iterator regs = calleeSavedRegisters().iterator();
|
||||
while (regs.hasNext()) {
|
||||
Register reg = (Register)regs.next();
|
||||
if (stats.numRegisterUsage(reg.baseName()) > 0) {
|
||||
result.add(reg);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
// #@@}
|
||||
|
||||
// #@@range/epilogue{
|
||||
protected void epilogue(DefinedFunction func, long lvarBytes) {
|
||||
label(epilogueLabel(func));
|
||||
shrinkStack(lvarBytes);
|
||||
mov(bp(), sp());
|
||||
pop(bp());
|
||||
ret();
|
||||
}
|
||||
// #@@}
|
||||
protected List calleeSavedRegistersCache = null;
|
||||
|
||||
// #@@range/jmpEpilogue{
|
||||
protected void jmpEpilogue() {
|
||||
jmp(new Label(epilogueLabel(currentFunction)));
|
||||
protected List calleeSavedRegisters() {
|
||||
if (calleeSavedRegistersCache == null) {
|
||||
ArrayList regs = new ArrayList();
|
||||
regs.add(reg("bx"));
|
||||
regs.add(reg("si"));
|
||||
regs.add(reg("di"));
|
||||
regs.add(reg("bp"));
|
||||
calleeSavedRegistersCache = regs;
|
||||
}
|
||||
return calleeSavedRegistersCache;
|
||||
}
|
||||
// #@@}
|
||||
|
||||
// #@@range/epilogueLabel{
|
||||
protected String epilogueLabel(DefinedFunction func) {
|
||||
return ".L" + func.name() + "$epilogue";
|
||||
}
|
||||
// #@@}
|
||||
|
||||
/* Standard IA-32 stack frame layout (after prologue)
|
||||
*
|
||||
* ======================= esp (stack top)
|
||||
* temporary
|
||||
* variables...
|
||||
* --------------------- ebp-(4*3)
|
||||
* --------------------- ebp-(4*4)
|
||||
* lvar 3
|
||||
* --------------------- ebp-(4*2)
|
||||
* --------------------- ebp-(4*3)
|
||||
* lvar 2
|
||||
* --------------------- ebp-(4*1)
|
||||
* --------------------- ebp-(4*2)
|
||||
* lvar 1
|
||||
* --------------------- ebp-(4*1)
|
||||
* callee-saved register
|
||||
* ======================= ebp
|
||||
* saved ebp
|
||||
* --------------------- ebp+(4*1)
|
||||
|
|
@ -296,6 +301,59 @@ public class CodeGenerator extends Visitor implements ASTLHSVisitor {
|
|||
// +1 for return address, +1 for saved bp
|
||||
static final protected long paramStartWord = 2;
|
||||
|
||||
// #@@range/prologue{
|
||||
protected void prologue(DefinedFunction func,
|
||||
List saveRegs, long lvarBytes) {
|
||||
push(bp());
|
||||
mov(sp(), bp());
|
||||
Iterator regs = saveRegs.iterator();
|
||||
while (regs.hasNext()) {
|
||||
Register reg = (Register)regs.next();
|
||||
// bp is already saved
|
||||
if (! reg.baseName().equals("bp")) {
|
||||
push(reg);
|
||||
}
|
||||
}
|
||||
extendStack(lvarBytes);
|
||||
|
||||
Iterator vars = func.localVariables();
|
||||
while (vars.hasNext()) {
|
||||
DefinedVariable var = (DefinedVariable)vars.next();
|
||||
comment("mem " + var.memref().toSource() + ": " + var.name());
|
||||
}
|
||||
}
|
||||
// #@@}
|
||||
|
||||
// #@@range/epilogue{
|
||||
protected void epilogue(DefinedFunction func,
|
||||
List savedRegs, long lvarBytes) {
|
||||
label(epilogueLabel(func));
|
||||
shrinkStack(lvarBytes);
|
||||
Iterator regs = savedRegs.iterator();
|
||||
while (regs.hasNext()) {
|
||||
Register reg = (Register)regs.next();
|
||||
if (! reg.baseName().equals("bp")) {
|
||||
pop(reg);
|
||||
}
|
||||
}
|
||||
mov(bp(), sp());
|
||||
pop(bp());
|
||||
ret();
|
||||
}
|
||||
// #@@}
|
||||
|
||||
// #@@range/jmpEpilogue{
|
||||
protected void jmpEpilogue() {
|
||||
jmp(new Label(epilogueLabel(currentFunction)));
|
||||
}
|
||||
// #@@}
|
||||
|
||||
// #@@range/epilogueLabel{
|
||||
protected String epilogueLabel(DefinedFunction func) {
|
||||
return ".L" + func.name() + "$epilogue";
|
||||
}
|
||||
// #@@}
|
||||
|
||||
protected void allocateParameters(DefinedFunction func) {
|
||||
Iterator vars = func.parameters();
|
||||
long word = paramStartWord;
|
||||
|
|
@ -311,12 +369,26 @@ public class CodeGenerator extends Visitor implements ASTLHSVisitor {
|
|||
}
|
||||
}
|
||||
|
||||
// Fixes addresses of local variables.
|
||||
// Returns byte-length of the local variable area.
|
||||
protected long allocateLocalVariables(DefinedFunction func,
|
||||
long numSavedRegs) {
|
||||
long initLen = numSavedRegs * stackWordSize;
|
||||
long maxLen = allocateScope(func.body().scope(), initLen);
|
||||
/**
|
||||
* Allocates addresses of local variables, but offset is still
|
||||
* not determined, assign unfixed IndirectMemoryReference.
|
||||
*/
|
||||
protected void allocateLocalVariablesTemp(LocalScope scope) {
|
||||
Iterator vars = scope.allLocalVariables();
|
||||
while (vars.hasNext()) {
|
||||
DefinedVariable var = (DefinedVariable)vars.next();
|
||||
var.setMemref(new IndirectMemoryReference(bp()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fixes addresses of local variables.
|
||||
* Returns byte-length of the local variable area.
|
||||
* Note that numSavedRegs includes bp.
|
||||
*/
|
||||
protected long allocateLocalVariables(LocalScope scope, long numSavedRegs) {
|
||||
long initLen = (numSavedRegs - 1) * stackWordSize;
|
||||
long maxLen = allocateScope(scope, initLen);
|
||||
return maxLen - initLen;
|
||||
}
|
||||
|
||||
|
|
@ -327,10 +399,10 @@ public class CodeGenerator extends Visitor implements ASTLHSVisitor {
|
|||
DefinedVariable var = (DefinedVariable)vars.next();
|
||||
if (stackGrowsLower) {
|
||||
len = Assembler.align(len + var.allocSize(), stackAlignment);
|
||||
var.setMemref(mem(-len, bp()));
|
||||
fixMemref((IndirectMemoryReference)var.memref(), -len);
|
||||
}
|
||||
else {
|
||||
var.setMemref(mem(len, bp()));
|
||||
fixMemref((IndirectMemoryReference)var.memref(), len);
|
||||
len = Assembler.align(len + var.allocSize(), stackAlignment);
|
||||
}
|
||||
}
|
||||
|
|
@ -346,6 +418,10 @@ public class CodeGenerator extends Visitor implements ASTLHSVisitor {
|
|||
return maxLen;
|
||||
}
|
||||
|
||||
protected void fixMemref(IndirectMemoryReference memref, long offset) {
|
||||
memref.fixOffset(offset);
|
||||
}
|
||||
|
||||
protected void extendStack(long len) {
|
||||
if (len > 0) {
|
||||
add(imm(len * (stackGrowsLower ? -1 : 1)), sp());
|
||||
|
|
@ -886,7 +962,7 @@ public class CodeGenerator extends Visitor implements ASTLHSVisitor {
|
|||
}
|
||||
|
||||
protected IndirectMemoryReference mem(Register reg) {
|
||||
return new IndirectMemoryReference(reg);
|
||||
return new IndirectMemoryReference(0, reg);
|
||||
}
|
||||
|
||||
protected IndirectMemoryReference mem(long offset, Register reg) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue