mirror of https://github.com/aamine/cbc
* 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:
parent
cb8b921931
commit
9af6bc364f
32
ChangeLog
32
ChangeLog
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,6 +35,10 @@ public class CastNode extends ExprNode {
|
|||
return expr.isConstantAddress();
|
||||
}
|
||||
|
||||
public Address memref() {
|
||||
return expr.memref();
|
||||
}
|
||||
|
||||
public AsmEntity address() {
|
||||
return expr.address();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@ abstract public class Entity extends Node {
|
|||
return (nRefered > 0);
|
||||
}
|
||||
|
||||
abstract public Address memref();
|
||||
abstract public AsmEntity address();
|
||||
|
||||
public Location location() {
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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()));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,6 +56,10 @@ public class VariableNode extends ExprNode {
|
|||
return entity.address();
|
||||
}
|
||||
|
||||
public Address memref() {
|
||||
return entity.memref();
|
||||
}
|
||||
|
||||
public Location location() {
|
||||
return location;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,11 @@
|
|||
import stdio;
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int (*)(char*) f;
|
||||
|
||||
f = &puts;
|
||||
f("OK");
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
Loading…
Reference in New Issue