* net/loveruby/cflat/asm/Type.java: new class representing assembly integer types.

* net/loveruby/cflat/asm/*.java: support it.
* net/loveruby/cflat/ir/*.java: support it.
* net/loveruby/cflat/compiler/IRGenerator.java: convert ast Type -> asm Type.
* net/loveruby/cflat/compiler/CodeGenerator.java: use asm Type.


git-svn-id: file:///Users/aamine/c/gitwork/public/cbc/trunk@4160 1b9489fe-b721-0410-924e-b54b9192deb8
This commit is contained in:
Minero Aoki 2009-04-26 17:04:29 +00:00
parent 8e8ae12043
commit 2f7019356a
20 changed files with 233 additions and 103 deletions

View File

@ -1,3 +1,17 @@
Mon Apr 27 02:04:26 2009 Minero Aoki <aamine@loveruby.net>
* net/loveruby/cflat/asm/Type.java: new class representing
assembly integer types.
* net/loveruby/cflat/asm/*.java: support it.
* net/loveruby/cflat/ir/*.java: support it.
* net/loveruby/cflat/compiler/IRGenerator.java: convert ast Type
-> asm Type.
* net/loveruby/cflat/compiler/CodeGenerator.java: use asm Type.
Mon Apr 27 00:24:24 2009 Minero Aoki <aamine@loveruby.net> Mon Apr 27 00:24:24 2009 Minero Aoki <aamine@loveruby.net>
* net/loveruby/cflat/compiler/CodeGenerator.java: remove simple * net/loveruby/cflat/compiler/CodeGenerator.java: remove simple

View File

@ -1,5 +1,4 @@
package net.loveruby.cflat.asm; package net.loveruby.cflat.asm;
import net.loveruby.cflat.type.*;
import net.loveruby.cflat.utils.*; import net.loveruby.cflat.utils.*;
import java.util.*; import java.util.*;
@ -92,7 +91,7 @@ public class Assembler {
} }
protected String typeSuffix(Type t) { protected String typeSuffix(Type t) {
switch ((int)t.size()) { switch (t.size()) {
case 1: return "b"; case 1: return "b";
case 2: return "w"; case 2: return "w";
case 4: return "l"; case 4: return "l";

View File

@ -1,5 +1,4 @@
package net.loveruby.cflat.asm; package net.loveruby.cflat.asm;
import net.loveruby.cflat.type.Type;
public class Instruction extends Assembly { public class Instruction extends Assembly {
protected String mnemonic; protected String mnemonic;

View File

@ -1,5 +1,4 @@
package net.loveruby.cflat.asm; package net.loveruby.cflat.asm;
import net.loveruby.cflat.type.*;
public class Register extends AsmOperand { public class Register extends AsmOperand {
protected int size; protected int size;
@ -18,11 +17,11 @@ public class Register extends AsmOperand {
} }
public Register forType(Type t) { public Register forType(Type t) {
switch ((int)t.size()) { switch (t.size()) {
case 1: case 1:
case 2: case 2:
case 4: case 4:
return new Register((int)t.size(), name); return new Register(t.size(), name);
default: default:
throw new Error("invalid register size: " + t.size()); throw new Error("invalid register size: " + t.size());
} }

View File

@ -0,0 +1,74 @@
package net.loveruby.cflat.asm;
public enum Type {
S_INT8,
U_INT8,
S_INT16,
U_INT16,
S_INT32,
U_INT32,
S_INT64,
U_INT64;
static public Type get(boolean isSigned, long size) {
if (isSigned) {
switch ((int)size) {
case 1:
return S_INT8;
case 2:
return S_INT16;
case 4:
return S_INT32;
case 8:
return S_INT64;
default:
throw new Error("unsupported asm type size: " + size);
}
}
else {
switch ((int)size) {
case 1:
return U_INT8;
case 2:
return U_INT16;
case 4:
return U_INT32;
case 8:
return U_INT64;
default:
throw new Error("unsupported asm type size: " + size);
}
}
}
public boolean isSigned() {
switch (this) {
case S_INT8:
case S_INT16:
case S_INT32:
case S_INT64:
return true;
default:
return false;
}
}
public int size() {
switch (this) {
case S_INT8:
case U_INT8:
return 1;
case S_INT16:
case U_INT16:
return 2;
case S_INT32:
case U_INT32:
return 4;
case S_INT64:
case U_INT64:
return 8;
default:
throw new Error("must not happen");
}
}
}

View File

@ -81,7 +81,8 @@ public class AST extends Node {
declarations.defvars(), declarations.defvars(),
declarations.defuns(), declarations.defuns(),
declarations.funcdecls(), declarations.funcdecls(),
scope, constantTable, typeTable); scope,
constantTable);
} }
protected void _dump(Dumper d) { protected void _dump(Dumper d) {

View File

@ -1,6 +1,5 @@
package net.loveruby.cflat.compiler; package net.loveruby.cflat.compiler;
import net.loveruby.cflat.ir.*; import net.loveruby.cflat.ir.*;
import net.loveruby.cflat.type.Type;
import net.loveruby.cflat.ast.LocalScope; import net.loveruby.cflat.ast.LocalScope;
import net.loveruby.cflat.ast.ConstantEntry; import net.loveruby.cflat.ast.ConstantEntry;
import net.loveruby.cflat.ast.Entity; import net.loveruby.cflat.ast.Entity;
@ -176,16 +175,16 @@ public class CodeGenerator implements IRVisitor<Void,Void>, ELFConstants {
as._type(sym, "@object"); as._type(sym, "@object");
as._size(sym, ent.allocSize()); as._size(sym, ent.allocSize());
as.label(sym); as.label(sym);
compileImmediate(ent.type(), ent.ir()); compileImmediate(ent.type().allocSize(), ent.ir());
} }
// #@@} // #@@}
/** Generates immediate values for .data section */ /** Generates immediate values for .data section */
// #@@range/compileImmediates{ // #@@range/compileImmediates{
protected void compileImmediate(Type type, Expr node) { protected void compileImmediate(long size, Expr node) {
if (node instanceof IntValue) { if (node instanceof IntValue) {
IntValue expr = (IntValue)node; IntValue expr = (IntValue)node;
switch ((int)type.allocSize()) { switch ((int)size) {
case 1: as._byte(expr.value()); break; case 1: as._byte(expr.value()); break;
case 2: as._value(expr.value()); break; case 2: as._value(expr.value()); break;
case 4: as._long(expr.value()); break; case 4: as._long(expr.value()); break;
@ -196,7 +195,7 @@ public class CodeGenerator implements IRVisitor<Void,Void>, ELFConstants {
} }
else if (node instanceof StringValue) { else if (node instanceof StringValue) {
StringValue expr = (StringValue)node; StringValue expr = (StringValue)node;
switch ((int)type.allocSize()) { switch ((int)size) {
case 4: as._long(expr.symbol()); break; case 4: as._long(expr.symbol()); break;
case 8: as._quad(expr.symbol()); break; case 8: as._quad(expr.symbol()); break;
default: default:
@ -840,7 +839,7 @@ public class CodeGenerator implements IRVisitor<Void,Void>, ELFConstants {
} }
else if (node.right().isConstantAddress()) { else if (node.right().isConstantAddress()) {
compile(node.left()); compile(node.left());
loadVariable(node.right(), reg("cx")); loadVariable((Var)node.right(), reg("cx"));
right = reg("cx", node.type()); right = reg("cx", node.type());
} }
else { else {
@ -937,7 +936,7 @@ public class CodeGenerator implements IRVisitor<Void,Void>, ELFConstants {
default: default:
// Comparison operators // Comparison operators
as.cmp(t, right, reg("ax", t)); as.cmp(t, right, reg("ax", t));
if (!t.isPointer() && t.isSigned()) { if (t.isSigned()) {
switch (op) { switch (op) {
case EQ: as.sete (al()); break; case EQ: as.sete (al()); break;
case NEQ: as.setne(al()); break; case NEQ: as.setne(al()); break;
@ -1108,7 +1107,7 @@ public class CodeGenerator implements IRVisitor<Void,Void>, ELFConstants {
* by #isConstantAddress before calling this method. * by #isConstantAddress before calling this method.
*/ */
// #@@range/loadVariable{ // #@@range/loadVariable{
protected void loadVariable(Expr node, Register dest) { protected void loadVariable(Var node, Register dest) {
if (node.memref() == null) { if (node.memref() == null) {
as.mov(node.address(), dest); as.mov(node.address(), dest);
load(node.type(), mem(dest), dest); load(node.type(), mem(dest), dest);
@ -1191,7 +1190,7 @@ public class CodeGenerator implements IRVisitor<Void,Void>, ELFConstants {
// #@@range/load{ // #@@range/load{
protected void load(Type type, MemoryReference mem, Register reg) { protected void load(Type type, MemoryReference mem, Register reg) {
switch ((int)type.size()) { switch (type.size()) {
case 1: case 1:
if (type.isSigned()) { // signed char if (type.isSigned()) { // signed char
as.movsbl(mem, reg); as.movsbl(mem, reg);
@ -1206,9 +1205,12 @@ public class CodeGenerator implements IRVisitor<Void,Void>, ELFConstants {
as.movzwl(mem, reg); as.movzwl(mem, reg);
} }
break; break;
default: // int, long, long_long case 4:
case 8: // int, long, long_long
as.mov(type, mem, reg.forType(type)); as.mov(type, mem, reg.forType(type));
break; break;
default:
throw new Error("unloadable value size: " + type.size());
} }
} }
// #@@} // #@@}

View File

@ -2,7 +2,6 @@ package net.loveruby.cflat.compiler;
import net.loveruby.cflat.ast.*; import net.loveruby.cflat.ast.*;
import net.loveruby.cflat.ir.*; import net.loveruby.cflat.ir.*;
import net.loveruby.cflat.type.Type; import net.loveruby.cflat.type.Type;
import net.loveruby.cflat.type.TypeRef;
import net.loveruby.cflat.type.TypeTable; import net.loveruby.cflat.type.TypeTable;
import net.loveruby.cflat.asm.Label; import net.loveruby.cflat.asm.Label;
import net.loveruby.cflat.exception.*; import net.loveruby.cflat.exception.*;
@ -463,11 +462,14 @@ class IRGenerator implements ASTVisitor<Void, Expr> {
// evaluate rhs before lhs. // evaluate rhs before lhs.
Expr rhs = transform(node.rhs()); Expr rhs = transform(node.rhs());
Expr lhs = transformLHS(node.lhs()); Expr lhs = transformLHS(node.lhs());
return transformOpAssign(lhs, Op.internBinary(node.operator()), rhs); return transformOpAssign(lhs,
Op.internBinary(node.operator()),
rhs,
node.lhs().type());
} }
private Expr transformOpAssign(Expr lhs, Op op, Expr _rhs) { private Expr transformOpAssign(Expr lhs, Op op, Expr _rhs, Type lhsType) {
Expr rhs = expandPointerArithmetic(_rhs, op, lhs.type()); Expr rhs = expandPointerArithmetic(_rhs, op, lhsType);
if (isStatement()) { if (isStatement()) {
if (lhs.isConstantAddress()) { if (lhs.isConstantAddress()) {
// lhs = lhs op rhs // lhs = lhs op rhs
@ -476,7 +478,7 @@ class IRGenerator implements ASTVisitor<Void, Expr> {
else { else {
// a = &lhs, *a = *a op rhs // a = &lhs, *a = *a op rhs
Expr addr = addressOf(lhs); Expr addr = addressOf(lhs);
DefinedVariable a = tmpVar(addr.type()); DefinedVariable a = tmpVar(pointerTo(lhsType));
assign(ref(a), addr); assign(ref(a), addr);
assign(deref(a), new Bin(lhs.type(), op, deref(a), rhs)); assign(deref(a), new Bin(lhs.type(), op, deref(a), rhs));
} }
@ -485,7 +487,7 @@ class IRGenerator implements ASTVisitor<Void, Expr> {
else { else {
// a = &lhs, *a = *a op rhs, *a // a = &lhs, *a = *a op rhs, *a
Expr addr = addressOf(lhs); Expr addr = addressOf(lhs);
DefinedVariable a = tmpVar(addr.type()); DefinedVariable a = tmpVar(pointerTo(lhsType));
assignBeforeStmt(ref(a), addr); assignBeforeStmt(ref(a), addr);
assignBeforeStmt(deref(a), new Bin(lhs.type(), op, deref(a), rhs)); assignBeforeStmt(deref(a), new Bin(lhs.type(), op, deref(a), rhs));
return deref(a); return deref(a);
@ -508,7 +510,8 @@ class IRGenerator implements ASTVisitor<Void, Expr> {
public Expr visit(PrefixOpNode node) { public Expr visit(PrefixOpNode node) {
return transformOpAssign(transformLHS(node.expr()), return transformOpAssign(transformLHS(node.expr()),
binOp(node.operator()), binOp(node.operator()),
intValue(1)); intValue(1),
node.expr().type());
} }
public Expr visit(SuffixOpNode node) { public Expr visit(SuffixOpNode node) {
@ -516,27 +519,29 @@ class IRGenerator implements ASTVisitor<Void, Expr> {
Op op = binOp(node.operator()); Op op = binOp(node.operator());
if (isStatement()) { if (isStatement()) {
// expr++; -> expr += 1; // expr++; -> expr += 1;
return transformOpAssign(lhs, op, intValue(1)); return transformOpAssign(lhs, op, intValue(1), node.expr().type());
} }
else if (lhs.isConstantAddress()) { else if (lhs.isConstantAddress()) {
// f(expr++) -> v = expr; expr = expr + 1, f(v) // f(expr++) -> v = expr; expr = expr + 1, f(v)
DefinedVariable v = tmpVar(lhs.type()); DefinedVariable v = tmpVar(node.expr().type());
assignBeforeStmt(ref(v), lhs); assignBeforeStmt(ref(v), lhs);
Expr rhs = expandPointerArithmetic(intValue(1), op, lhs.type()); Expr rhs = expandPointerArithmetic(intValue(1),
op, node.expr().type());
assignBeforeStmt(lhs, new Bin(lhs.type(), op, lhs, rhs)); assignBeforeStmt(lhs, new Bin(lhs.type(), op, lhs, rhs));
return ref(v); return ref(v);
} }
else { else {
// f(expr++) -> a = &expr, v = *a; *a = *a + 1, f(v) // f(expr++) -> a = &expr, v = *a; *a = *a + 1, f(v)
Expr addr = addressOf(lhs); Expr addr = addressOf(lhs);
DefinedVariable a = tmpVar(addr.type()); DefinedVariable a = tmpVar(pointerTo(node.expr().type()));
DefinedVariable v = tmpVar(lhs.type()); DefinedVariable v = tmpVar(node.expr().type());
assignBeforeStmt(ref(a), addr); assignBeforeStmt(ref(a), addr);
assignBeforeStmt(ref(v), deref(a)); assignBeforeStmt(ref(v), deref(a));
assignBeforeStmt(deref(a), assignBeforeStmt(deref(a),
new Bin(lhs.type(), op, new Bin(lhs.type(), op,
deref(a), deref(a),
expandPointerArithmetic(intValue(1), op, lhs.type()))); expandPointerArithmetic(intValue(1),
op, node.expr().type())));
return ref(v); return ref(v);
} }
} }
@ -547,7 +552,7 @@ class IRGenerator implements ASTVisitor<Void, Expr> {
while (args.hasPrevious()) { while (args.hasPrevious()) {
newArgs.add(0, transform(args.previous())); newArgs.add(0, transform(args.previous()));
} }
return new Call(node.type(), transform(node.expr()), newArgs); return new Call(asmType(node.type()), transform(node.expr()), newArgs);
} }
// //
@ -559,16 +564,18 @@ class IRGenerator implements ASTVisitor<Void, Expr> {
Expr left = transform(node.left()); Expr left = transform(node.left());
Expr right = transform(node.right()); Expr right = transform(node.right());
if (node.operator().equals("+") || node.operator().equals("-")) { if (node.operator().equals("+") || node.operator().equals("-")) {
if (left.type().isDereferable()) { if (node.left().type().isDereferable()) {
right = new Bin(right.type(), Op.MUL, right = new Bin(ptrDiffType(), Op.MUL,
right, ptrDiff(left.type().baseType().size())); right, ptrDiff(node.left().type().baseType().size()));
} }
else if (right.type().isDereferable()) { else if (node.right().type().isDereferable()) {
left = new Bin(left.type(), Op.MUL, left = new Bin(ptrDiffType(), Op.MUL,
left, ptrDiff(right.type().baseType().size())); left, ptrDiff(node.right().type().baseType().size()));
} }
} }
return new Bin(node.type(), Op.internBinary(node.operator()), left, right); return new Bin(asmType(node.type()),
Op.internBinary(node.operator()),
left, right);
} }
// #@@} // #@@}
@ -578,17 +585,18 @@ class IRGenerator implements ASTVisitor<Void, Expr> {
return transform(node.expr()); return transform(node.expr());
} }
else { else {
return new Uni(node.type(), Op.internUnary(node.operator()), return new Uni(asmType(node.type()),
Op.internUnary(node.operator()),
transform(node.expr())); transform(node.expr()));
} }
} }
public Expr visit(ArefNode node) { public Expr visit(ArefNode node) {
Expr offset = new Bin(typeTable.signedInt(), Op.MUL, Expr offset = new Bin(signedInt(), Op.MUL,
intValue(node.elementSize()), transformArrayIndex(node)); intValue(node.elementSize()), transformArrayIndex(node));
return deref( return deref(
new Bin(pointerTo(node.type()), Op.ADD, new Bin(pointer(), Op.ADD, transform(node.baseExpr()), offset),
transform(node.baseExpr()), offset)); node.type());
} }
// For multidimension array: t[e][d][c][b][a]; // For multidimension array: t[e][d][c][b][a];
@ -599,10 +607,9 @@ class IRGenerator implements ASTVisitor<Void, Expr> {
// #@@range/transformArrayIndex{ // #@@range/transformArrayIndex{
private Expr transformArrayIndex(ArefNode node) { private Expr transformArrayIndex(ArefNode node) {
if (node.isMultiDimension()) { if (node.isMultiDimension()) {
return new Bin( return new Bin(signedInt(), Op.ADD,
typeTable.signedInt(), Op.ADD,
transform(node.index()), transform(node.index()),
new Bin(typeTable.signedInt(), Op.MUL, new Bin(signedInt(), Op.MUL,
intValue(node.length()), intValue(node.length()),
transformArrayIndex((ArefNode)node.expr()))); transformArrayIndex((ArefNode)node.expr())));
} }
@ -613,21 +620,21 @@ class IRGenerator implements ASTVisitor<Void, Expr> {
// #@@} // #@@}
public Expr visit(MemberNode node) { public Expr visit(MemberNode node) {
Expr addr = new Bin(pointerTo(node.type()), Op.ADD, Expr addr = new Bin(pointer(), Op.ADD,
addressOf(transform(node.expr())), addressOf(transform(node.expr())),
intValue(node.offset())); intValue(node.offset()));
return node.shouldEvaluatedToAddress() ? addr : deref(addr); return node.shouldEvaluatedToAddress() ? addr : deref(addr, node.type());
} }
public Expr visit(PtrMemberNode node) { public Expr visit(PtrMemberNode node) {
Expr addr = new Bin(pointerTo(node.type()), Op.ADD, Expr addr = new Bin(pointer(), Op.ADD,
transform(node.expr()), transform(node.expr()),
intValue(node.offset())); intValue(node.offset()));
return node.shouldEvaluatedToAddress() ? addr : deref(addr); return node.shouldEvaluatedToAddress() ? addr : deref(addr, node.type());
} }
public Expr visit(DereferenceNode node) { public Expr visit(DereferenceNode node) {
return new Mem(node.type(), transform(node.expr())); return new Mem(asmType(node.type()), transform(node.expr()));
} }
public Expr visit(AddressNode node) { public Expr visit(AddressNode node) {
@ -642,7 +649,8 @@ class IRGenerator implements ASTVisitor<Void, Expr> {
public Expr visit(CastNode node) { public Expr visit(CastNode node) {
if (node.isEffectiveCast()) { if (node.isEffectiveCast()) {
return new Uni(node.type(), Op.CAST, transform(node.expr())); return new Uni(asmType(node.type()),
Op.CAST, transform(node.expr()));
} }
else { else {
return transform(node.expr()); return transform(node.expr());
@ -658,16 +666,16 @@ class IRGenerator implements ASTVisitor<Void, Expr> {
} }
public Expr visit(VariableNode node) { public Expr visit(VariableNode node) {
Var var = new Var(node.entity()); Var var = new Var(varType(node.type()), node.entity());
return node.shouldEvaluatedToAddress() ? addressOf(var) : var; return node.shouldEvaluatedToAddress() ? addressOf(var) : var;
} }
public Expr visit(IntegerLiteralNode node) { public Expr visit(IntegerLiteralNode node) {
return new IntValue(node.type(), node.value()); return new IntValue(asmType(node.type()), node.value());
} }
public Expr visit(StringLiteralNode node) { public Expr visit(StringLiteralNode node) {
return new StringValue(node.type(), node.entry()); return new StringValue(asmType(node.type()), node.entry());
} }
// //
@ -685,45 +693,68 @@ class IRGenerator implements ASTVisitor<Void, Expr> {
return ((Mem)expr).expr(); return ((Mem)expr).expr();
} }
else { else {
Type base = expr.type(); return new Addr(pointer(), expr);
Type t = shouldEvalutedToAddress(expr) ? base : pointerTo(base);
return new Addr(t, expr);
} }
} }
private boolean shouldEvalutedToAddress(Expr expr) {
return expr.type().isArray()
|| ((expr instanceof Var) && ((Var)expr).entity().cannotLoad());
}
private Var ref(DefinedVariable var) { private Var ref(DefinedVariable var) {
return new Var(var); return new Var(varType(var.type()), var);
} }
// add DereferenceNode on top of the var. // add DereferenceNode on top of the var.
private Mem deref(DefinedVariable var) { private Mem deref(DefinedVariable var) {
return deref(ref(var)); return deref(ref(var), var.type().baseType());
} }
// add DereferenceNode on top of the expr. // add DereferenceNode on top of the expr.
private Mem deref(Expr expr) { private Mem deref(Expr expr, Type t) {
return new Mem(expr.type().baseType(), expr); return new Mem(asmType(t), expr);
}
private IntValue intValue(long n) {
return new IntValue(signedInt(), n);
}
private IntValue ptrDiff(long n) {
return new IntValue(ptrDiffType(), n);
} }
private Type pointerTo(Type t) { private Type pointerTo(Type t) {
return typeTable.pointerTo(t); return typeTable.pointerTo(t);
} }
private IntValue intValue(long n) { private net.loveruby.cflat.asm.Type asmType(Type t) {
return new IntValue(typeTable.signedInt(), n); if (t.isVoid()) return signedInt();
return net.loveruby.cflat.asm.Type.get(
t.isInteger() && t.isSigned(),
t.size());
} }
private IntValue ptrDiff(long n) { private net.loveruby.cflat.asm.Type varType(Type t) {
return new IntValue(typeTable.ptrDiffType(), n); if (t.size() == 0 || t.size() > typeTable.maxIntSize()) {
return null;
}
return net.loveruby.cflat.asm.Type.get(
t.isInteger() && t.isSigned(),
t.size());
} }
private void bindType(TypeNode t) { private net.loveruby.cflat.asm.Type signedInt() {
t.setType(typeTable.get(t.typeRef())); return net.loveruby.cflat.asm.Type.get(
true,
(int)typeTable.intSize());
}
private net.loveruby.cflat.asm.Type pointer() {
return net.loveruby.cflat.asm.Type.get(
false,
(int)typeTable.pointerSize());
}
private net.loveruby.cflat.asm.Type ptrDiffType() {
return net.loveruby.cflat.asm.Type.get(
true,
(int)typeTable.pointerSize());
} }
private void error(Node n, String msg) { private void error(Node n, String msg) {

View File

@ -1,5 +1,5 @@
package net.loveruby.cflat.ir; package net.loveruby.cflat.ir;
import net.loveruby.cflat.type.Type; import net.loveruby.cflat.asm.Type;
public class Addr extends Expr { public class Addr extends Expr {
protected Expr expr; protected Expr expr;

View File

@ -1,5 +1,5 @@
package net.loveruby.cflat.ir; package net.loveruby.cflat.ir;
import net.loveruby.cflat.type.Type; import net.loveruby.cflat.asm.Type;
public class Bin extends Expr { public class Bin extends Expr {
protected Op op; protected Op op;

View File

@ -1,5 +1,5 @@
package net.loveruby.cflat.ir; package net.loveruby.cflat.ir;
import net.loveruby.cflat.type.Type; import net.loveruby.cflat.asm.Type;
import net.loveruby.cflat.ast.Function; import net.loveruby.cflat.ast.Function;
import java.util.List; import java.util.List;
import java.util.ListIterator; import java.util.ListIterator;

View File

@ -2,8 +2,7 @@ package net.loveruby.cflat.ir;
import net.loveruby.cflat.ast.DefinedVariable; import net.loveruby.cflat.ast.DefinedVariable;
import net.loveruby.cflat.ast.DefinedFunction; import net.loveruby.cflat.ast.DefinedFunction;
import net.loveruby.cflat.ast.Location; import net.loveruby.cflat.ast.Location;
import net.loveruby.cflat.asm.Label; import net.loveruby.cflat.asm.*;
import net.loveruby.cflat.type.Type;
import java.util.List; import java.util.List;
import java.io.PrintStream; import java.io.PrintStream;
@ -46,7 +45,11 @@ public class Dumper {
printPair(name, memb.toString()); printPair(name, memb.toString());
} }
public void printMember(String name, Type memb) { public void printMember(String name, net.loveruby.cflat.asm.Type memb) {
printPair(name, memb.toString());
}
public void printMember(String name, net.loveruby.cflat.type.Type memb) {
printPair(name, memb.toString()); printPair(name, memb.toString());
} }

View File

@ -1,5 +1,4 @@
package net.loveruby.cflat.ir; package net.loveruby.cflat.ir;
import net.loveruby.cflat.type.Type;
import net.loveruby.cflat.asm.*; import net.loveruby.cflat.asm.*;
abstract public class Expr implements Dumpable { abstract public class Expr implements Dumpable {

View File

@ -7,8 +7,7 @@ import net.loveruby.cflat.ast.DefinedFunction;
import net.loveruby.cflat.ast.UndefinedFunction; import net.loveruby.cflat.ast.UndefinedFunction;
import net.loveruby.cflat.ast.ConstantTable; import net.loveruby.cflat.ast.ConstantTable;
import net.loveruby.cflat.ast.ToplevelScope; import net.loveruby.cflat.ast.ToplevelScope;
import net.loveruby.cflat.type.TypeTable; import net.loveruby.cflat.asm.Type;
import net.loveruby.cflat.type.Type;
import java.io.PrintStream; import java.io.PrintStream;
import java.util.*; import java.util.*;
@ -19,15 +18,13 @@ public class IR {
protected List<UndefinedFunction> funcdecls; protected List<UndefinedFunction> funcdecls;
protected ToplevelScope scope; protected ToplevelScope scope;
protected ConstantTable constantTable; protected ConstantTable constantTable;
protected TypeTable typeTable;
public IR(Location source, public IR(Location source,
List<DefinedVariable> defvars, List<DefinedVariable> defvars,
List<DefinedFunction> defuns, List<DefinedFunction> defuns,
List<UndefinedFunction> funcdecls, List<UndefinedFunction> funcdecls,
ToplevelScope scope, ToplevelScope scope,
ConstantTable constantTable, ConstantTable constantTable) {
TypeTable typeTable) {
super(); super();
this.source = source; this.source = source;
this.defvars = defvars; this.defvars = defvars;
@ -35,7 +32,6 @@ public class IR {
this.funcdecls = funcdecls; this.funcdecls = funcdecls;
this.scope = scope; this.scope = scope;
this.constantTable = constantTable; this.constantTable = constantTable;
this.typeTable = typeTable;
} }
public String fileName() { public String fileName() {
@ -88,8 +84,9 @@ public class IR {
return constantTable; return constantTable;
} }
public Type naturalType() { public net.loveruby.cflat.asm.Type naturalType() {
return this.typeTable.unsignedLong(); // platform dependent!!!
return Type.S_INT32;
} }
public void dump() { public void dump() {

View File

@ -1,8 +1,5 @@
package net.loveruby.cflat.ir; package net.loveruby.cflat.ir;
import net.loveruby.cflat.type.Type; import net.loveruby.cflat.asm.*;
import net.loveruby.cflat.asm.IntegerLiteral;
import net.loveruby.cflat.asm.ImmediateValue;
import net.loveruby.cflat.asm.MemoryReference;
public class IntValue extends Expr { public class IntValue extends Expr {
protected long value; protected long value;

View File

@ -1,5 +1,5 @@
package net.loveruby.cflat.ir; package net.loveruby.cflat.ir;
import net.loveruby.cflat.type.Type; import net.loveruby.cflat.asm.Type;
public class Mem extends Expr { public class Mem extends Expr {
protected Expr expr; protected Expr expr;

View File

@ -1,5 +1,4 @@
package net.loveruby.cflat.ir; package net.loveruby.cflat.ir;
import net.loveruby.cflat.type.Type;
import net.loveruby.cflat.ast.ConstantEntry; import net.loveruby.cflat.ast.ConstantEntry;
import net.loveruby.cflat.asm.*; import net.loveruby.cflat.asm.*;

View File

@ -1,5 +1,5 @@
package net.loveruby.cflat.ir; package net.loveruby.cflat.ir;
import net.loveruby.cflat.type.Type; import net.loveruby.cflat.asm.Type;
public class Uni extends Expr { public class Uni extends Expr {
protected Op op; protected Op op;

View File

@ -1,16 +1,22 @@
package net.loveruby.cflat.ir; package net.loveruby.cflat.ir;
import net.loveruby.cflat.ast.Entity; import net.loveruby.cflat.ast.Entity;
import net.loveruby.cflat.asm.AsmOperand; import net.loveruby.cflat.asm.*;
import net.loveruby.cflat.asm.MemoryReference;
public class Var extends Expr { public class Var extends Expr {
protected Entity entity; protected Entity entity;
public Var(Entity entity) { public Var(Type type, Entity entity) {
super(entity.type()); super(type);
this.entity = entity; this.entity = entity;
} }
public Type type() {
if (super.type() == null) {
throw new Error("Var is too big to load by 1 insn");
}
return super.type();
}
public String name() { return entity.name(); } public String name() { return entity.name(); }
public Entity entity() { return entity; } public Entity entity() { return entity; }

View File

@ -12,7 +12,7 @@ public class TypeTable {
static private TypeTable newTable(int charsize, int shortsize, static private TypeTable newTable(int charsize, int shortsize,
int intsize, int longsize, int ptrsize) { int intsize, int longsize, int ptrsize) {
TypeTable table = new TypeTable(ptrsize); TypeTable table = new TypeTable(intsize, ptrsize);
table.put(new VoidTypeRef(), new VoidType()); table.put(new VoidTypeRef(), new VoidType());
table.put(IntegerTypeRef.charRef(), table.put(IntegerTypeRef.charRef(),
new IntegerType(charsize, true, "char")); new IntegerType(charsize, true, "char"));
@ -33,12 +33,14 @@ public class TypeTable {
return table; return table;
} }
protected int intSize;
protected int pointerSize; protected int pointerSize;
protected Map<TypeRef, Type> table; protected Map<TypeRef, Type> table;
public TypeTable(int ptrsize) { public TypeTable(int intSize, int pointerSize) {
pointerSize = ptrsize; this.intSize = intSize;
table = new HashMap<TypeRef, Type>(); this.pointerSize = pointerSize;
this.table = new HashMap<TypeRef, Type>();
} }
public boolean isDefined(TypeRef ref) { public boolean isDefined(TypeRef ref) {
@ -88,7 +90,15 @@ public class TypeTable {
return type; return type;
} }
public long pointerSize() { public int intSize() {
return this.intSize;
}
public int pointerSize() {
return this.pointerSize;
}
public int maxIntSize() {
return this.pointerSize; return this.pointerSize;
} }