diff --git a/ChangeLog b/ChangeLog index 5702c44..8b29f97 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,35 @@ +Tue Sep 16 02:18:06 2008 Minero Aoki + + * net/loveruby/cflat/compiler/CodeGenerator.java: both of "puts" + and "&puts" should be evaluated to its address. + + * net/loveruby/cflat/compiler/CodeGenerator.java: address -> + memref. + + * net/loveruby/cflat/ast/Entity.java: ditto. + + * net/loveruby/cflat/ast/Function.java: ditto. + + * net/loveruby/cflat/ast/Variable.java: ditto. + + * net/loveruby/cflat/ast/UndefinedVariable.java: ditto. + + * net/loveruby/cflat/ast/DefinedVariable.java: ditto. + + * net/loveruby/cflat/ast/ExprNode.java: ditto.: ditto. + + * net/loveruby/cflat/ast/ArefNode.java: ditto. + + * net/loveruby/cflat/ast/MemberNode.java: ditto. + + * net/loveruby/cflat/ast/PtrMemberNode.java: ditto. + + * net/loveruby/cflat/ast/VariableNode.java: ditto. + + * net/loveruby/cflat/ast/CastNode.java: ditto. + + * test: test "puts", "&puts", "myputs", "&myputs". + Tue Sep 16 00:59:55 2008 Minero Aoki * net/loveruby/cflat/ast/Function.java (address): should return diff --git a/net/loveruby/cflat/ast/ArefNode.java b/net/loveruby/cflat/ast/ArefNode.java index 47cc318..8f12d84 100644 --- a/net/loveruby/cflat/ast/ArefNode.java +++ b/net/loveruby/cflat/ast/ArefNode.java @@ -53,10 +53,6 @@ public class ArefNode extends ExprNode { return false; } - public AsmEntity address() { - throw new Error("ArefNode#address"); - } - public Location location() { return expr.location(); } diff --git a/net/loveruby/cflat/ast/CastNode.java b/net/loveruby/cflat/ast/CastNode.java index 39a6d9b..db4c910 100644 --- a/net/loveruby/cflat/ast/CastNode.java +++ b/net/loveruby/cflat/ast/CastNode.java @@ -35,6 +35,10 @@ public class CastNode extends ExprNode { return expr.isConstantAddress(); } + public Address memref() { + return expr.memref(); + } + public AsmEntity address() { return expr.address(); } diff --git a/net/loveruby/cflat/ast/DefinedVariable.java b/net/loveruby/cflat/ast/DefinedVariable.java index af0c812..215c237 100644 --- a/net/loveruby/cflat/ast/DefinedVariable.java +++ b/net/loveruby/cflat/ast/DefinedVariable.java @@ -4,7 +4,7 @@ import net.loveruby.cflat.asm.*; public class DefinedVariable extends Variable { protected ExprNode initializer; - protected AsmEntity address; + protected Address memref; public DefinedVariable(boolean priv, TypeNode type, String name, ExprNode init) { @@ -33,6 +33,20 @@ public class DefinedVariable extends Variable { this.initializer = expr; } + public void setMemref(Address addr) { + this.memref = addr; + } + + public Address memref() { + if (memref == null) + throw new Error("unresolved variable address"); + return memref; + } + + public AsmEntity address() { + return null; + } + protected void _dump(Dumper d) { d.printMember("name", name); d.printMember("isPrivate", isPrivate); diff --git a/net/loveruby/cflat/ast/Entity.java b/net/loveruby/cflat/ast/Entity.java index b1f7e5c..9536436 100644 --- a/net/loveruby/cflat/ast/Entity.java +++ b/net/loveruby/cflat/ast/Entity.java @@ -52,6 +52,7 @@ abstract public class Entity extends Node { return (nRefered > 0); } + abstract public Address memref(); abstract public AsmEntity address(); public Location location() { diff --git a/net/loveruby/cflat/ast/ExprNode.java b/net/loveruby/cflat/ast/ExprNode.java index 7e92e93..fbb7854 100644 --- a/net/loveruby/cflat/ast/ExprNode.java +++ b/net/loveruby/cflat/ast/ExprNode.java @@ -47,4 +47,8 @@ abstract public class ExprNode extends Node { public AsmEntity address() { throw new Error("ExprNode#address called"); } + + public Address memref() { + throw new Error("ExprNode#memref called"); + } } diff --git a/net/loveruby/cflat/ast/Function.java b/net/loveruby/cflat/ast/Function.java index 4a9f409..e222142 100644 --- a/net/loveruby/cflat/ast/Function.java +++ b/net/loveruby/cflat/ast/Function.java @@ -25,6 +25,10 @@ abstract public class Function extends Entity { return returnType().isVoid(); } + public Address memref() { + return null; + } + public AsmEntity address() { return new ImmediateValue(new Label(name())); } diff --git a/net/loveruby/cflat/ast/MemberNode.java b/net/loveruby/cflat/ast/MemberNode.java index c4c0862..b9fa27b 100644 --- a/net/loveruby/cflat/ast/MemberNode.java +++ b/net/loveruby/cflat/ast/MemberNode.java @@ -51,10 +51,6 @@ public class MemberNode extends ExprNode { return false; } - public AsmEntity address() { - throw new Error("must not happen: MemberNode#address"); - } - public Location location() { return expr.location(); } diff --git a/net/loveruby/cflat/ast/PtrMemberNode.java b/net/loveruby/cflat/ast/PtrMemberNode.java index 3cbf924..46b7806 100644 --- a/net/loveruby/cflat/ast/PtrMemberNode.java +++ b/net/loveruby/cflat/ast/PtrMemberNode.java @@ -52,10 +52,6 @@ public class PtrMemberNode extends ExprNode { return false; } - public AsmEntity address() { - throw new Error("PtrMemberNode#address"); - } - public long offset() { return dereferedComplexType().memberOffset(member); } diff --git a/net/loveruby/cflat/ast/UndefinedVariable.java b/net/loveruby/cflat/ast/UndefinedVariable.java index f9e72b5..c8970b8 100644 --- a/net/loveruby/cflat/ast/UndefinedVariable.java +++ b/net/loveruby/cflat/ast/UndefinedVariable.java @@ -15,12 +15,16 @@ public class UndefinedVariable extends Variable { return name(); } - public void setAddress(AsmEntity addr) { - throw new Error("UndefinedVariable#setAddress"); + public void setMemref(Address addr) { + throw new Error("UndefinedVariable#Memref"); + } + + public Address memref() { + return new DirectAddress(new Label(symbol())); } public AsmEntity address() { - return new DirectAddress(new Label(symbol())); + return new ImmediateValue(new Label(symbol())); } protected void _dump(Dumper d) { diff --git a/net/loveruby/cflat/ast/Variable.java b/net/loveruby/cflat/ast/Variable.java index 1343dd0..056e973 100644 --- a/net/loveruby/cflat/ast/Variable.java +++ b/net/loveruby/cflat/ast/Variable.java @@ -4,7 +4,6 @@ import net.loveruby.cflat.asm.*; abstract public class Variable extends Entity { protected long sequence; - protected AsmEntity address; public Variable(boolean priv, TypeNode type, String name) { super(priv, type, name); @@ -19,13 +18,5 @@ abstract public class Variable extends Entity { return (sequence < 0) ? name : (name + "." + sequence); } - public void setAddress(AsmEntity addr) { - address = addr; - } - - public AsmEntity address() { - if (address == null) - throw new Error("unresolved variable address"); - return address; - } + abstract public void setMemref(Address addr); } diff --git a/net/loveruby/cflat/ast/VariableNode.java b/net/loveruby/cflat/ast/VariableNode.java index cf039a3..b436184 100644 --- a/net/loveruby/cflat/ast/VariableNode.java +++ b/net/loveruby/cflat/ast/VariableNode.java @@ -56,6 +56,10 @@ public class VariableNode extends ExprNode { return entity.address(); } + public Address memref() { + return entity.memref(); + } + public Location location() { return location; } diff --git a/net/loveruby/cflat/compiler/CodeGenerator.java b/net/loveruby/cflat/compiler/CodeGenerator.java index 098e513..91a679b 100644 --- a/net/loveruby/cflat/compiler/CodeGenerator.java +++ b/net/loveruby/cflat/compiler/CodeGenerator.java @@ -51,7 +51,7 @@ public class CodeGenerator extends Visitor implements ASTLHSVisitor { // #@@} /** - * Sets address for... + * Sets memory reference for... * * public global variables * * private global variables * * static local variables @@ -60,7 +60,7 @@ public class CodeGenerator extends Visitor implements ASTLHSVisitor { protected void allocateGlobalVariables(Iterator vars) { while (vars.hasNext()) { Variable var = (Variable)vars.next(); - var.setAddress(globalVariableAddress(var.symbol())); + var.setMemref(globalVariableAddress(var.symbol())); } } // #@@} @@ -74,21 +74,21 @@ public class CodeGenerator extends Visitor implements ASTLHSVisitor { protected void allocateCommonSymbols(Iterator comms) { while (comms.hasNext()) { Variable var = (Variable)comms.next(); - var.setAddress(commonSymbolAddress(var.symbol())); + var.setMemref(commonSymbolAddress(var.symbol())); } } // #@@} /** Linux/IA-32 dependent */ // FIXME: PIC - protected AsmEntity globalVariableAddress(String sym) { - return new Symbol(new Label(csymbol(sym))); + protected Address globalVariableAddress(String sym) { + return new DirectAddress(new Label(csymbol(sym))); } /** Linux/IA-32 dependent */ // FIXME: PIC - protected AsmEntity commonSymbolAddress(String sym) { - return new Symbol(new Label(csymbol(sym))); + protected Address commonSymbolAddress(String sym) { + return new DirectAddress(new Label(csymbol(sym))); } /** Generates static variable entries */ @@ -298,7 +298,7 @@ public class CodeGenerator extends Visitor implements ASTLHSVisitor { while (vars.hasNext()) { Parameter var = (Parameter)vars.next(); if (stackGrowsLower) { - var.setAddress(mem(word * stackWordSize, bp())); + var.setMemref(mem(word * stackWordSize, bp())); } else { throw new Error("unsupported stack layout"); @@ -323,10 +323,10 @@ public class CodeGenerator extends Visitor implements ASTLHSVisitor { DefinedVariable var = (DefinedVariable)vars.next(); if (stackGrowsLower) { len = Assembler.align(len + var.allocSize(), stackAlignment); - var.setAddress(mem(-len, bp())); + var.setMemref(mem(-len, bp())); } else { - var.setAddress(mem(len, bp())); + var.setMemref(mem(len, bp())); len = Assembler.align(len + var.allocSize(), stackAlignment); } } @@ -397,7 +397,7 @@ public class CodeGenerator extends Visitor implements ASTLHSVisitor { DefinedVariable var = (DefinedVariable)vars.next(); if (var.initializer() != null) { compile(var.initializer()); - save(var.type(), reg("ax"), var.address()); + save(var.type(), reg("ax"), var.memref()); } } Iterator stmts = node.stmts(); @@ -647,9 +647,9 @@ public class CodeGenerator extends Visitor implements ASTLHSVisitor { public void visit(PrefixOpNode node) { if (node.expr().isConstantAddress()) { - load(node.expr().type(), node.expr().address(), reg("ax")); + load(node.expr().type(), node.expr().memref(), reg("ax")); compileUnaryArithmetic(node, reg("ax")); - save(node.expr().type(), reg("ax"), node.expr().address()); + save(node.expr().type(), reg("ax"), node.expr().memref()); } else { compileLHS(node.expr()); @@ -662,10 +662,10 @@ public class CodeGenerator extends Visitor implements ASTLHSVisitor { public void visit(SuffixOpNode node) { if (node.expr().isConstantAddress()) { - load(node.expr().type(), node.expr().address(), reg("ax")); + load(node.expr().type(), node.expr().memref(), reg("ax")); mov(reg("ax"), reg("cx")); compileUnaryArithmetic(node, reg("cx")); - save(node.expr().type(), reg("cx"), node.expr().address()); + save(node.expr().type(), reg("cx"), node.expr().memref()); } else { compileLHS(node.expr()); @@ -721,10 +721,16 @@ public class CodeGenerator extends Visitor implements ASTLHSVisitor { public void visit(VariableNode node) { if (node.type().isAllocatedArray()) { - lea(node.address(), reg("ax")); + // int[4] a; a implies &a + compileLHS(node); + } + else if (node.memref() == null) { + // "puts" equivalent to "&ptr" + mov(node.address(), reg("ax")); } else { - load(node.type(), node.address(), reg("ax")); + // regular variable + load(node.type(), node.memref(), reg("ax")); } } @@ -733,7 +739,7 @@ public class CodeGenerator extends Visitor implements ASTLHSVisitor { } public void visit(StringLiteralNode node) { - load(node.type(), imm(node.label()), reg("ax")); + mov(imm(node.label()), reg("ax")); } // @@ -743,7 +749,7 @@ public class CodeGenerator extends Visitor implements ASTLHSVisitor { public void visit(AssignNode node) { if (node.lhs().isConstantAddress()) { compile(node.rhs()); - save(node.type(), reg("ax"), node.lhs().address()); + save(node.type(), reg("ax"), node.lhs().memref()); } else { compile(node.rhs()); @@ -759,9 +765,9 @@ public class CodeGenerator extends Visitor implements ASTLHSVisitor { compile(node.rhs()); if (node.lhs().isConstantAddress()) { mov(reg("ax"), reg("cx")); - load(node.type(), node.lhs().address(), reg("ax")); + load(node.type(), node.lhs().memref(), reg("ax")); compileBinaryOp(node.operator(), node.type()); - save(node.type(), reg("ax"), node.lhs().address()); + save(node.type(), reg("ax"), node.lhs().memref()); } else { push(reg("ax")); @@ -807,7 +813,12 @@ public class CodeGenerator extends Visitor implements ASTLHSVisitor { } public void visitLHS(VariableNode node) { - lea(node.address(), reg("ax")); + if (node.address() != null) { + mov(node.address(), reg("ax")); + } + else { + lea(node.memref(), reg("ax")); + } } public void visitLHS(ArefNode node) { @@ -882,7 +893,7 @@ public class CodeGenerator extends Visitor implements ASTLHSVisitor { return new ImmediateValue(label); } - protected void load(Type type, AsmEntity addr, Register reg) { + protected void load(Type type, Address addr, Register reg) { switch ((int)type.size()) { case 1: if (type.isSigned()) { // signed char @@ -904,7 +915,7 @@ public class CodeGenerator extends Visitor implements ASTLHSVisitor { } } - protected void save(Type type, Register reg, AsmEntity addr) { + protected void save(Type type, Register reg, Address addr) { mov(type, reg.forType(type), addr); } diff --git a/test/funcptr3.cb b/test/funcptr3.cb new file mode 100644 index 0000000..d90f951 --- /dev/null +++ b/test/funcptr3.cb @@ -0,0 +1,11 @@ +import stdio; + +int +main(int argc, char **argv) +{ + int (*)(char*) f; + + f = &puts; + f("OK"); + return 0; +} diff --git a/test/funcptr4.cb b/test/funcptr4.cb new file mode 100644 index 0000000..fece80a --- /dev/null +++ b/test/funcptr4.cb @@ -0,0 +1,13 @@ +import stdio; + +void myputs(char* str) { puts(str); } + +int +main(int argc, char **argv) +{ + void (*)(char*) f; + + f = &myputs; + f("OK"); + return 0; +}