mirror of https://github.com/aamine/cbc
* net: revert r4100; implementing alloca() is too difficult for current architecture.
git-svn-id: file:///Users/aamine/c/gitwork/public/cbc/trunk@4102 1b9489fe-b721-0410-924e-b54b9192deb8
This commit is contained in:
parent
37476f6839
commit
b598628af9
|
|
@ -1,3 +1,8 @@
|
||||||
|
Sun Dec 7 23:26:50 2008 Minero Aoki <aamine@loveruby.net>
|
||||||
|
|
||||||
|
* net: revert r4100; implementing alloca() is too difficult for
|
||||||
|
current architecture.
|
||||||
|
|
||||||
Sun Dec 7 23:25:25 2008 Minero Aoki <aamine@loveruby.net>
|
Sun Dec 7 23:25:25 2008 Minero Aoki <aamine@loveruby.net>
|
||||||
|
|
||||||
* lib/libcbc.cb -> lib/stdarg.cb
|
* lib/libcbc.cb -> lib/stdarg.cb
|
||||||
|
|
|
||||||
|
|
@ -21,8 +21,4 @@ abstract public class AsmOperand implements OperandPattern {
|
||||||
public boolean match(AsmOperand operand) {
|
public boolean match(AsmOperand operand) {
|
||||||
return equals(operand);
|
return equals(operand);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void fixStackOffset(long diff) {
|
|
||||||
// does nothing by default
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -275,11 +275,6 @@ public class Assembler {
|
||||||
mov(naturalType, src, dest);
|
mov(naturalType, src, dest);
|
||||||
}
|
}
|
||||||
|
|
||||||
// for stack access
|
|
||||||
public void relocatableMov(AsmOperand src, AsmOperand dest) {
|
|
||||||
assemblies.add(new Instruction("mov", typeSuffix(naturalType), src, dest, true));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void mov(Type type, AsmOperand src, AsmOperand dest) {
|
public void mov(Type type, AsmOperand src, AsmOperand dest) {
|
||||||
insn(type, "mov", src, dest);
|
insn(type, "mov", src, dest);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,8 +22,4 @@ abstract public class Assembly {
|
||||||
public void collectStatistics(AsmStatistics stats) {
|
public void collectStatistics(AsmStatistics stats) {
|
||||||
// does nothing by default.
|
// does nothing by default.
|
||||||
}
|
}
|
||||||
|
|
||||||
public void fixStackOffset(long diff) {
|
|
||||||
// does nothing by default.
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,4 @@ abstract public class BaseSymbol implements Symbol {
|
||||||
public void collectStatistics(AsmStatistics stats) {
|
public void collectStatistics(AsmStatistics stats) {
|
||||||
stats.symbolUsed(this);
|
stats.symbolUsed(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Literal plus(long n) {
|
|
||||||
throw new Error("must not happen: BaseSymbol.plus called");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -43,10 +43,6 @@ public class IndirectMemoryReference extends MemoryReference {
|
||||||
base.collectStatistics(stats);
|
base.collectStatistics(stats);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void fixStackOffset(long diff) {
|
|
||||||
offset = offset.plus(diff);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return toSource(SymbolTable.dummy());
|
return toSource(SymbolTable.dummy());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,41 +5,32 @@ public class Instruction extends Assembly {
|
||||||
protected String mnemonic;
|
protected String mnemonic;
|
||||||
protected String suffix;
|
protected String suffix;
|
||||||
protected AsmOperand[] operands;
|
protected AsmOperand[] operands;
|
||||||
protected boolean needRelocation;
|
|
||||||
|
|
||||||
public Instruction(String mnemonic) {
|
public Instruction(String mnemonic) {
|
||||||
this(mnemonic, "", new AsmOperand[0], false);
|
this(mnemonic, "", new AsmOperand[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Instruction(String mnemonic, String suffix, AsmOperand a1) {
|
public Instruction(String mnemonic, String suffix, AsmOperand a1) {
|
||||||
this(mnemonic, suffix, new AsmOperand[] { a1 }, false);
|
this(mnemonic, suffix, new AsmOperand[] { a1 });
|
||||||
}
|
}
|
||||||
|
|
||||||
public Instruction(String mnemonic, String suffix,
|
public Instruction(String mnemonic, String suffix,
|
||||||
AsmOperand a1, AsmOperand a2) {
|
AsmOperand a1, AsmOperand a2) {
|
||||||
this(mnemonic, suffix, new AsmOperand[] { a1, a2 }, false);
|
this(mnemonic, suffix, new AsmOperand[] { a1, a2 });
|
||||||
}
|
}
|
||||||
|
|
||||||
public Instruction(String mnemonic, String suffix,
|
public Instruction(String mnemonic, String suffix, AsmOperand[] operands) {
|
||||||
AsmOperand a1, AsmOperand a2, boolean reloc) {
|
|
||||||
this(mnemonic, suffix, new AsmOperand[] { a1, a2 }, reloc);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Instruction(String mnemonic, String suffix, AsmOperand[] operands, boolean reloc) {
|
|
||||||
this.mnemonic = mnemonic;
|
this.mnemonic = mnemonic;
|
||||||
this.suffix = suffix;
|
this.suffix = suffix;
|
||||||
this.operands = operands;
|
this.operands = operands;
|
||||||
this.needRelocation = reloc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Instruction build(String mnemonic, AsmOperand o1) {
|
public Instruction build(String mnemonic, AsmOperand o1) {
|
||||||
return new Instruction(mnemonic, this.suffix,
|
return new Instruction(mnemonic, this.suffix, new AsmOperand[] { o1 });
|
||||||
new AsmOperand[] { o1 }, needRelocation);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Instruction build(String mnemonic, AsmOperand o1, AsmOperand o2) {
|
public Instruction build(String mnemonic, AsmOperand o1, AsmOperand o2) {
|
||||||
return new Instruction(mnemonic, this.suffix,
|
return new Instruction(mnemonic, this.suffix, new AsmOperand[] { o1, o2 });
|
||||||
new AsmOperand[] { o1, o2 }, needRelocation);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isInstruction() {
|
public boolean isInstruction() {
|
||||||
|
|
@ -88,13 +79,6 @@ public class Instruction extends Assembly {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void fixStackOffset(long diff) {
|
|
||||||
if (!needRelocation) return;
|
|
||||||
for (int i = 0; i < operands.length; i++) {
|
|
||||||
operands[i].fixStackOffset(diff);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public String toSource(SymbolTable table) {
|
public String toSource(SymbolTable table) {
|
||||||
StringBuffer buf = new StringBuffer();
|
StringBuffer buf = new StringBuffer();
|
||||||
buf.append("\t");
|
buf.append("\t");
|
||||||
|
|
|
||||||
|
|
@ -24,10 +24,6 @@ public class IntegerLiteral implements Literal {
|
||||||
return value == 0;
|
return value == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IntegerLiteral plus(long diff) {
|
|
||||||
return new IntegerLiteral(value + diff);
|
|
||||||
}
|
|
||||||
|
|
||||||
public IntegerLiteral integerLiteral() {
|
public IntegerLiteral integerLiteral() {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
@ -43,8 +39,4 @@ public class IntegerLiteral implements Literal {
|
||||||
public void collectStatistics(AsmStatistics stats) {
|
public void collectStatistics(AsmStatistics stats) {
|
||||||
// does nothing
|
// does nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toString() {
|
|
||||||
return "$" + value;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,5 +5,4 @@ public interface Literal {
|
||||||
public String toSource(SymbolTable table);
|
public String toSource(SymbolTable table);
|
||||||
public void collectStatistics(AsmStatistics stats);
|
public void collectStatistics(AsmStatistics stats);
|
||||||
public boolean isZero();
|
public boolean isZero();
|
||||||
public Literal plus(long diff);
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,10 +17,6 @@ public class SuffixedSymbol implements Symbol {
|
||||||
base.collectStatistics(stats);
|
base.collectStatistics(stats);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Literal plus(long n) {
|
|
||||||
throw new Error("must not happen: SuffixedSymbol.plus called");
|
|
||||||
}
|
|
||||||
|
|
||||||
public String name() {
|
public String name() {
|
||||||
return base.name();
|
return base.name();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -304,15 +304,13 @@ public class CodeGenerator
|
||||||
// #@@}
|
// #@@}
|
||||||
|
|
||||||
protected void compileFunctionBody(DefinedFunction func) {
|
protected void compileFunctionBody(DefinedFunction func) {
|
||||||
initStackParams();
|
|
||||||
List<Assembly> bodyAsms = compileStmts(func);
|
List<Assembly> bodyAsms = compileStmts(func);
|
||||||
AsmStatistics stats = AsmStatistics.collect(bodyAsms);
|
AsmStatistics stats = AsmStatistics.collect(bodyAsms);
|
||||||
bodyAsms = reduceLabels(bodyAsms, stats);
|
bodyAsms = reduceLabels(bodyAsms, stats);
|
||||||
List<Register> saveRegs = usedCalleeSavedRegisters(stats);
|
List<Register> saveRegs = usedCalleeSavedRegisters(stats);
|
||||||
long lvarBytes = allocateLocalVariables(func.body().scope(), savedRegsSize(saveRegs));
|
long lvarBytes = allocateLocalVariables(func.body().scope(),
|
||||||
fixStackOffsets(bodyAsms, savedRegsSize(saveRegs) + lvarBytes);
|
saveRegs.size());
|
||||||
|
prologue(func, saveRegs, lvarBytes);
|
||||||
prologue(func, saveRegs, savedRegsSize(saveRegs) + lvarBytes + maxStackLength());
|
|
||||||
if (options.isPositionIndependent() && stats.doesRegisterUsed(GOTBaseReg())) {
|
if (options.isPositionIndependent() && stats.doesRegisterUsed(GOTBaseReg())) {
|
||||||
loadGOTBaseAddress(GOTBaseReg());
|
loadGOTBaseAddress(GOTBaseReg());
|
||||||
}
|
}
|
||||||
|
|
@ -320,16 +318,6 @@ public class CodeGenerator
|
||||||
epilogue(func, saveRegs, lvarBytes);
|
epilogue(func, saveRegs, lvarBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected long savedRegsSize(List<Register> regs) {
|
|
||||||
long numReallySaved = 0;
|
|
||||||
for (Register reg : regs) {
|
|
||||||
if (! reg.baseName().equals("bp")) {
|
|
||||||
numReallySaved++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return numReallySaved * stackWordSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected List<Assembly> compileStmts(DefinedFunction func) {
|
protected List<Assembly> compileStmts(DefinedFunction func) {
|
||||||
pushAssembler();
|
pushAssembler();
|
||||||
currentFunction = func;
|
currentFunction = func;
|
||||||
|
|
@ -430,11 +418,11 @@ public class CodeGenerator
|
||||||
// #@@range/prologue{
|
// #@@range/prologue{
|
||||||
protected void prologue(DefinedFunction func,
|
protected void prologue(DefinedFunction func,
|
||||||
List<Register> saveRegs,
|
List<Register> saveRegs,
|
||||||
long frameSize) {
|
long lvarBytes) {
|
||||||
truePush(bp());
|
push(bp());
|
||||||
mov(sp(), bp());
|
mov(sp(), bp());
|
||||||
saveRegisters(saveRegs);
|
saveRegisters(saveRegs);
|
||||||
allocateStack(frameSize);
|
extendStack(lvarBytes);
|
||||||
if (options.isVerboseAsm()) {
|
if (options.isVerboseAsm()) {
|
||||||
for (DefinedVariable var : func.localVariables()) {
|
for (DefinedVariable var : func.localVariables()) {
|
||||||
comment("mem " + var.memref() + ": " + var.name());
|
comment("mem " + var.memref() + ": " + var.name());
|
||||||
|
|
@ -447,10 +435,10 @@ public class CodeGenerator
|
||||||
protected void epilogue(DefinedFunction func,
|
protected void epilogue(DefinedFunction func,
|
||||||
List<Register> savedRegs,
|
List<Register> savedRegs,
|
||||||
long lvarBytes) {
|
long lvarBytes) {
|
||||||
//shrinkStack(lvarBytes);
|
shrinkStack(lvarBytes);
|
||||||
restoreRegisters(savedRegs);
|
restoreRegisters(savedRegs);
|
||||||
mov(bp(), sp());
|
mov(bp(), sp());
|
||||||
truePop(bp());
|
pop(bp());
|
||||||
ret();
|
ret();
|
||||||
}
|
}
|
||||||
// #@@}
|
// #@@}
|
||||||
|
|
@ -501,9 +489,10 @@ public class CodeGenerator
|
||||||
* Returns byte-length of the local variable area.
|
* Returns byte-length of the local variable area.
|
||||||
* Note that numSavedRegs includes bp.
|
* Note that numSavedRegs includes bp.
|
||||||
*/
|
*/
|
||||||
protected long allocateLocalVariables(LocalScope scope, long offset) {
|
protected long allocateLocalVariables(LocalScope scope, long numSavedRegs) {
|
||||||
long maxLen = allocateScope(scope, offset);
|
long initLen = (numSavedRegs - 1) * stackWordSize;
|
||||||
return maxLen - offset;
|
long maxLen = allocateScope(scope, initLen);
|
||||||
|
return maxLen - initLen;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected long allocateScope(LocalScope scope, long parentStackLen) {
|
protected long allocateScope(LocalScope scope, long parentStackLen) {
|
||||||
|
|
@ -532,60 +521,15 @@ public class CodeGenerator
|
||||||
memref.fixOffset(offset);
|
memref.fixOffset(offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void allocateStack(long len) {
|
|
||||||
if (len > 0) {
|
|
||||||
if (stackGrowsLower) {
|
|
||||||
sub(imm(len), sp());
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
add(imm(len), sp());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected long stackPointer;
|
|
||||||
protected long stackPointerMax;
|
|
||||||
|
|
||||||
protected void initStackParams() {
|
|
||||||
stackPointer = 0;
|
|
||||||
stackPointerMax = stackPointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected long maxStackLength() {
|
|
||||||
return stackPointerMax;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected IndirectMemoryReference stackTop() {
|
|
||||||
if (stackGrowsLower) {
|
|
||||||
return mem(-stackPointer, bp());
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return mem(stackPointer - stackWordSize, bp());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void push(Register reg) {
|
|
||||||
extendStack(stackWordSize);
|
|
||||||
as.relocatableMov(reg, stackTop());
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void pop(Register reg) {
|
|
||||||
as.relocatableMov(stackTop(), reg);
|
|
||||||
rewindStack(stackWordSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void extendStack(long len) {
|
protected void extendStack(long len) {
|
||||||
stackPointer += len;
|
if (len > 0) {
|
||||||
stackPointerMax = Math.max(stackPointerMax, stackPointer);
|
add(imm(len * (stackGrowsLower ? -1 : 1)), sp());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void rewindStack(long len) {
|
protected void shrinkStack(long len) {
|
||||||
stackPointer -= len;
|
if (len > 0) {
|
||||||
}
|
add(imm(len * (stackGrowsLower ? 1 : -1)), sp());
|
||||||
|
|
||||||
protected void fixStackOffsets(List<Assembly> asms, long offset) {
|
|
||||||
for (Assembly asm : asms) {
|
|
||||||
asm.fixStackOffset(offset * (stackGrowsLower ? -1 : 1));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -597,12 +541,9 @@ public class CodeGenerator
|
||||||
public void visit(FuncallNode node) {
|
public void visit(FuncallNode node) {
|
||||||
// compile function arguments from right to left.
|
// compile function arguments from right to left.
|
||||||
ListIterator<ExprNode> args = node.finalArg();
|
ListIterator<ExprNode> args = node.finalArg();
|
||||||
long argIndex = node.numArgs() - 1;
|
|
||||||
while (args.hasPrevious()) {
|
while (args.hasPrevious()) {
|
||||||
compile(args.previous());
|
compile(args.previous());
|
||||||
mov(reg("ax"), argMemory(argIndex));
|
push(reg("ax"));
|
||||||
argIndex--;
|
|
||||||
extendStack(stackWordSize);
|
|
||||||
}
|
}
|
||||||
// call
|
// call
|
||||||
if (node.isStaticCall()) {
|
if (node.isStaticCall()) {
|
||||||
|
|
@ -616,16 +557,7 @@ public class CodeGenerator
|
||||||
}
|
}
|
||||||
// rewind stack
|
// rewind stack
|
||||||
// >4 bytes arguments are not supported.
|
// >4 bytes arguments are not supported.
|
||||||
rewindStack(node.numArgs() * stackWordSize);
|
shrinkStack(node.numArgs() * stackWordSize);
|
||||||
}
|
|
||||||
|
|
||||||
protected IndirectMemoryReference argMemory(long argIndex) {
|
|
||||||
if (stackGrowsLower) {
|
|
||||||
return mem(stackWordSize * argIndex, sp());
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return mem(-stackWordSize * (argIndex + 1), sp());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void visit(ReturnNode node) {
|
public void visit(ReturnNode node) {
|
||||||
|
|
@ -1316,8 +1248,8 @@ public class CodeGenerator
|
||||||
public void setl(Register reg) { as.setl(reg); }
|
public void setl(Register reg) { as.setl(reg); }
|
||||||
public void setle(Register reg) { as.setle(reg); }
|
public void setle(Register reg) { as.setle(reg); }
|
||||||
public void test(Type type, Register a, Register b) { as.test(type, a, b); }
|
public void test(Type type, Register a, Register b) { as.test(type, a, b); }
|
||||||
protected void truePush(Register reg) { as.push(reg); }
|
public void push(Register reg) { as.push(reg); }
|
||||||
protected void truePop(Register reg) { as.pop(reg); }
|
public void pop(Register reg) { as.pop(reg); }
|
||||||
public void call(Symbol sym) { as.call(sym); }
|
public void call(Symbol sym) { as.call(sym); }
|
||||||
public void callAbsolute(Register reg) { as.callAbsolute(reg); }
|
public void callAbsolute(Register reg) { as.callAbsolute(reg); }
|
||||||
public void ret() { as.ret(); }
|
public void ret() { as.ret(); }
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue