mirror of https://github.com/aamine/cbc
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:
parent
8f9df4fb03
commit
6833982356
11
ChangeLog
11
ChangeLog
|
@ -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
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue