* 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".


git-svn-id: file:///Users/aamine/c/gitwork/public/cbc/trunk@4025 1b9489fe-b721-0410-924e-b54b9192deb8
This commit is contained in:
Minero Aoki 2008-09-15 17:18:16 +00:00
parent cb8b921931
commit 9af6bc364f
15 changed files with 131 additions and 50 deletions

View File

@ -1,3 +1,35 @@
Tue Sep 16 02:18:06 2008 Minero Aoki <aamine@loveruby.net>
* 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 <aamine@loveruby.net>
* net/loveruby/cflat/ast/Function.java (address): should return

View File

@ -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();
}

View File

@ -35,6 +35,10 @@ public class CastNode extends ExprNode {
return expr.isConstantAddress();
}
public Address memref() {
return expr.memref();
}
public AsmEntity address() {
return expr.address();
}

View File

@ -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);

View File

@ -52,6 +52,7 @@ abstract public class Entity extends Node {
return (nRefered > 0);
}
abstract public Address memref();
abstract public AsmEntity address();
public Location location() {

View File

@ -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");
}
}

View File

@ -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()));
}

View File

@ -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();
}

View File

@ -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);
}

View File

@ -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) {

View File

@ -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);
}

View File

@ -56,6 +56,10 @@ public class VariableNode extends ExprNode {
return entity.address();
}
public Address memref() {
return entity.memref();
}
public Location location() {
return location;
}

View File

@ -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);
}

11
test/funcptr3.cb Normal file
View File

@ -0,0 +1,11 @@
import stdio;
int
main(int argc, char **argv)
{
int (*)(char*) f;
f = &puts;
f("OK");
return 0;
}

13
test/funcptr4.cb Normal file
View File

@ -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;
}