r5034@macbookpro: aamine | 2009-06-07 04:17:22 +0900

* net/loveruby/cflat/sysdep/x86/CodeGenerator.java: refactoring: extract class: StackFrameInfo.
 * net/loveruby/cflat/sysdep/x86/CodeGenerator.java: refactoring: extract method: generateFunctionBody.
 net/loveruby/cflat/entity/DefinedFunction.java: new method #lvarScope.
 


git-svn-id: file:///Users/aamine/c/gitwork/public/cbc/trunk@4279 1b9489fe-b721-0410-924e-b54b9192deb8
This commit is contained in:
Minero Aoki 2009-06-06 19:17:42 +00:00
parent 8f9df4fb03
commit 6833982356
3 changed files with 77 additions and 52 deletions

View File

@ -1,3 +1,14 @@
Sun Jun 7 04:16:39 2009 Minero Aoki <aamine@loveruby.net>
* net/loveruby/cflat/sysdep/x86/CodeGenerator.java: refactoring:
extract class: StackFrameInfo.
* net/loveruby/cflat/sysdep/x86/CodeGenerator.java: refactoring:
extract method: generateFunctionBody.
net/loveruby/cflat/entity/DefinedFunction.java: new method
#lvarScope.
Sun Jun 7 03:17:06 2009 Minero Aoki <aamine@loveruby.net> Sun Jun 7 03:17:06 2009 Minero Aoki <aamine@loveruby.net>
* sysdep/x86/CodeGenerator.java (compileFunctionBody): fix offset * sysdep/x86/CodeGenerator.java (compileFunctionBody): fix offset

View File

@ -44,6 +44,10 @@ public class DefinedFunction extends Function {
this.scope = scope; this.scope = scope;
} }
public LocalScope lvarScope() {
return body().scope();
}
/** /**
* Returns function local variables. * Returns function local variables.
* Does NOT include paramters. * Does NOT include paramters.

View File

@ -392,33 +392,42 @@ public class CodeGenerator
} }
// #@@} // #@@}
// #@@range/StackFrameInfo{
class StackFrameInfo {
final long stackWordSize;
List<Register> saveRegs;
long lvarSize;
long tempSize;
StackFrameInfo(long stackWordSize) {
this.stackWordSize = stackWordSize;
}
long saveRegsSize() { return saveRegs.size() * stackWordSize; }
long lvarOffset() { return saveRegsSize(); }
long tempOffset() { return saveRegsSize() + lvarSize; }
long frameSize() { return saveRegsSize() + lvarSize + tempSize; }
}
// #@@}
// #@@range/compileFunctionBody{ // #@@range/compileFunctionBody{
private void compileFunctionBody( private void compileFunctionBody(
AssemblyFile file, DefinedFunction func) { AssemblyFile file, DefinedFunction func) {
StackFrameInfo frame = new StackFrameInfo(STACK_WORD_SIZE);
locateParameters(func.parameters()); locateParameters(func.parameters());
long lvarsSize = locateLocalVariables(func.body().scope(), 0); frame.lvarSize = locateLocalVariables(func.lvarScope());
AssemblyFile body = optimize(compileStmts(func)); AssemblyFile body = optimize(compileStmts(func));
List<Register> saveRegs = usedCalleeSavedRegisters(body); frame.saveRegs = usedCalleeSavedRegisters(body);
long saveRegsSize = stackSizeFromWordNum(saveRegs.size()); frame.tempSize = body.virtualStack.maxSize();
fixLocalVariableOffsets(func.body().scope(), saveRegsSize);
fixTempVariableOffsets(body, saveRegsSize + lvarsSize); fixLocalVariableOffsets(func.lvarScope(), frame.lvarOffset());
fixTempVariableOffsets(body, frame.tempOffset());
if (options.isVerboseAsm()) { if (options.isVerboseAsm()) {
printStackFrameLayout(file, saveRegsSize, lvarsSize, printStackFrameLayout(file, frame, func.localVariables());
body.virtualStack.maxSize(), func.localVariables());
} }
generateFunctionBody(file, body, frame);
file.virtualStack.reset();
prologue(file, func, saveRegs,
saveRegsSize + lvarsSize + body.virtualStack.maxSize());
if (options.isPositionIndependent()
&& body.doesUses(GOTBaseReg())) {
loadGOTBaseAddress(file, GOTBaseReg());
}
file.addAll(body.assemblies());
epilogue(file, func, saveRegs, lvarsSize);
file.virtualStack.fixOffset(0);
} }
// #@@} // #@@}
@ -433,24 +442,21 @@ public class CodeGenerator
} }
// #@@} // #@@}
private void printStackFrameLayout( private void printStackFrameLayout(AssemblyFile file,
AssemblyFile file, StackFrameInfo frame, List<DefinedVariable> lvars) {
long saveRegsBytes, long lvarBytes, long maxTmpBytes,
List<DefinedVariable> lvars) {
List<MemInfo> vars = new ArrayList<MemInfo>(); List<MemInfo> vars = new ArrayList<MemInfo>();
for (DefinedVariable var : lvars) { for (DefinedVariable var : lvars) {
vars.add(new MemInfo(var.memref(), var.name())); vars.add(new MemInfo(var.memref(), var.name()));
} }
vars.add(new MemInfo(mem(0, bp()), "return address")); vars.add(new MemInfo(mem(0, bp()), "return address"));
vars.add(new MemInfo(mem(4, bp()), "saved %ebp")); vars.add(new MemInfo(mem(4, bp()), "saved %ebp"));
if (saveRegsBytes > 0) { if (frame.saveRegsSize() > 0) {
vars.add(new MemInfo(mem(-saveRegsBytes, bp()), vars.add(new MemInfo(mem(-frame.saveRegsSize(), bp()),
"saved callee-saved registers (" + saveRegsBytes + " bytes)")); "saved callee-saved registers (" + frame.saveRegsSize() + " bytes)"));
} }
if (maxTmpBytes > 0) { if (frame.tempSize > 0) {
long offset = -(saveRegsBytes + lvarBytes + maxTmpBytes); vars.add(new MemInfo(mem(-frame.frameSize(), bp()),
vars.add(new MemInfo(mem(offset, bp()), "tmp variables (" + frame.tempSize + " bytes)"));
"tmp variables (" + maxTmpBytes + " bytes)"));
} }
Collections.sort(vars, new Comparator<MemInfo>() { Collections.sort(vars, new Comparator<MemInfo>() {
public int compare(MemInfo x, MemInfo y) { public int compare(MemInfo x, MemInfo y) {
@ -519,44 +525,44 @@ public class CodeGenerator
return calleeSavedRegistersCache; return calleeSavedRegistersCache;
} }
// #@@range/generateFunctionBody{
private void generateFunctionBody(AssemblyFile file,
AssemblyFile body, StackFrameInfo frame) {
file.virtualStack.reset();
prologue(file, frame.saveRegs, frame.frameSize());
if (options.isPositionIndependent()
&& body.doesUses(GOTBaseReg())) {
loadGOTBaseAddress(file, GOTBaseReg());
}
file.addAll(body.assemblies());
epilogue(file, frame.saveRegs);
file.virtualStack.fixOffset(0);
}
// #@@}
// #@@range/prologue{ // #@@range/prologue{
private void prologue(AssemblyFile file, DefinedFunction func, private void prologue(AssemblyFile file,
List<Register> saveRegs, long frameSize) { List<Register> saveRegs, long frameSize) {
file.push(bp()); file.push(bp());
file.mov(sp(), bp()); file.mov(sp(), bp());
saveRegisters(file, saveRegs); for (Register reg : saveRegs) {
file.virtualPush(reg);
}
extendStack(file, frameSize); extendStack(file, frameSize);
} }
// #@@} // #@@}
// #@@range/epilogue{ // #@@range/epilogue{
private void epilogue(AssemblyFile file, DefinedFunction func, private void epilogue(AssemblyFile file, List<Register> savedRegs) {
List<Register> savedRegs, long lvarBytes) { for (Register reg : ListUtils.reverse(savedRegs)) {
restoreRegisters(file, savedRegs); file.virtualPop(reg);
}
file.mov(bp(), sp()); file.mov(bp(), sp());
file.pop(bp()); file.pop(bp());
file.ret(); file.ret();
} }
// #@@} // #@@}
// #@@range/saveRegisters{
private void saveRegisters(AssemblyFile file, List<Register> saveRegs) {
for (Register reg : saveRegs) {
file.virtualPush(reg);
}
}
// #@@}
// #@@range/restoreRegisters{
private void restoreRegisters(
AssemblyFile file, List<Register> savedRegs) {
ListIterator<Register> regs = savedRegs.listIterator(savedRegs.size());
while (regs.hasPrevious()) {
file.virtualPop(regs.previous());
}
}
// #@@}
// #@@range/locateParameters{ // #@@range/locateParameters{
static final private long PARAM_START_WORD = 2; static final private long PARAM_START_WORD = 2;
// return addr and saved bp // return addr and saved bp
@ -575,6 +581,10 @@ public class CodeGenerator
* not determined, assign unfixed IndirectMemoryReference. * not determined, assign unfixed IndirectMemoryReference.
*/ */
// #@@range/locateLocalVariables{ // #@@range/locateLocalVariables{
private long locateLocalVariables(LocalScope scope) {
return locateLocalVariables(scope, 0);
}
private long locateLocalVariables( private long locateLocalVariables(
LocalScope scope, long parentStackLen) { LocalScope scope, long parentStackLen) {
long len = parentStackLen; long len = parentStackLen;