mirror of https://github.com/aamine/cbc
* 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:
parent
8e8ae12043
commit
2f7019356a
14
ChangeLog
14
ChangeLog
|
|
@ -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>
|
||||
|
||||
* net/loveruby/cflat/compiler/CodeGenerator.java: remove simple
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
package net.loveruby.cflat.asm;
|
||||
import net.loveruby.cflat.type.*;
|
||||
import net.loveruby.cflat.utils.*;
|
||||
import java.util.*;
|
||||
|
||||
|
|
@ -92,7 +91,7 @@ public class Assembler {
|
|||
}
|
||||
|
||||
protected String typeSuffix(Type t) {
|
||||
switch ((int)t.size()) {
|
||||
switch (t.size()) {
|
||||
case 1: return "b";
|
||||
case 2: return "w";
|
||||
case 4: return "l";
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
package net.loveruby.cflat.asm;
|
||||
import net.loveruby.cflat.type.Type;
|
||||
|
||||
public class Instruction extends Assembly {
|
||||
protected String mnemonic;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
package net.loveruby.cflat.asm;
|
||||
import net.loveruby.cflat.type.*;
|
||||
|
||||
public class Register extends AsmOperand {
|
||||
protected int size;
|
||||
|
|
@ -18,11 +17,11 @@ public class Register extends AsmOperand {
|
|||
}
|
||||
|
||||
public Register forType(Type t) {
|
||||
switch ((int)t.size()) {
|
||||
switch (t.size()) {
|
||||
case 1:
|
||||
case 2:
|
||||
case 4:
|
||||
return new Register((int)t.size(), name);
|
||||
return new Register(t.size(), name);
|
||||
default:
|
||||
throw new Error("invalid register size: " + t.size());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -81,7 +81,8 @@ public class AST extends Node {
|
|||
declarations.defvars(),
|
||||
declarations.defuns(),
|
||||
declarations.funcdecls(),
|
||||
scope, constantTable, typeTable);
|
||||
scope,
|
||||
constantTable);
|
||||
}
|
||||
|
||||
protected void _dump(Dumper d) {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
package net.loveruby.cflat.compiler;
|
||||
import net.loveruby.cflat.ir.*;
|
||||
import net.loveruby.cflat.type.Type;
|
||||
import net.loveruby.cflat.ast.LocalScope;
|
||||
import net.loveruby.cflat.ast.ConstantEntry;
|
||||
import net.loveruby.cflat.ast.Entity;
|
||||
|
|
@ -176,16 +175,16 @@ public class CodeGenerator implements IRVisitor<Void,Void>, ELFConstants {
|
|||
as._type(sym, "@object");
|
||||
as._size(sym, ent.allocSize());
|
||||
as.label(sym);
|
||||
compileImmediate(ent.type(), ent.ir());
|
||||
compileImmediate(ent.type().allocSize(), ent.ir());
|
||||
}
|
||||
// #@@}
|
||||
|
||||
/** Generates immediate values for .data section */
|
||||
// #@@range/compileImmediates{
|
||||
protected void compileImmediate(Type type, Expr node) {
|
||||
protected void compileImmediate(long size, Expr node) {
|
||||
if (node instanceof IntValue) {
|
||||
IntValue expr = (IntValue)node;
|
||||
switch ((int)type.allocSize()) {
|
||||
switch ((int)size) {
|
||||
case 1: as._byte(expr.value()); break;
|
||||
case 2: as._value(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) {
|
||||
StringValue expr = (StringValue)node;
|
||||
switch ((int)type.allocSize()) {
|
||||
switch ((int)size) {
|
||||
case 4: as._long(expr.symbol()); break;
|
||||
case 8: as._quad(expr.symbol()); break;
|
||||
default:
|
||||
|
|
@ -840,7 +839,7 @@ public class CodeGenerator implements IRVisitor<Void,Void>, ELFConstants {
|
|||
}
|
||||
else if (node.right().isConstantAddress()) {
|
||||
compile(node.left());
|
||||
loadVariable(node.right(), reg("cx"));
|
||||
loadVariable((Var)node.right(), reg("cx"));
|
||||
right = reg("cx", node.type());
|
||||
}
|
||||
else {
|
||||
|
|
@ -937,7 +936,7 @@ public class CodeGenerator implements IRVisitor<Void,Void>, ELFConstants {
|
|||
default:
|
||||
// Comparison operators
|
||||
as.cmp(t, right, reg("ax", t));
|
||||
if (!t.isPointer() && t.isSigned()) {
|
||||
if (t.isSigned()) {
|
||||
switch (op) {
|
||||
case EQ: as.sete (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.
|
||||
*/
|
||||
// #@@range/loadVariable{
|
||||
protected void loadVariable(Expr node, Register dest) {
|
||||
protected void loadVariable(Var node, Register dest) {
|
||||
if (node.memref() == null) {
|
||||
as.mov(node.address(), dest);
|
||||
load(node.type(), mem(dest), dest);
|
||||
|
|
@ -1191,7 +1190,7 @@ public class CodeGenerator implements IRVisitor<Void,Void>, ELFConstants {
|
|||
|
||||
// #@@range/load{
|
||||
protected void load(Type type, MemoryReference mem, Register reg) {
|
||||
switch ((int)type.size()) {
|
||||
switch (type.size()) {
|
||||
case 1:
|
||||
if (type.isSigned()) { // signed char
|
||||
as.movsbl(mem, reg);
|
||||
|
|
@ -1206,9 +1205,12 @@ public class CodeGenerator implements IRVisitor<Void,Void>, ELFConstants {
|
|||
as.movzwl(mem, reg);
|
||||
}
|
||||
break;
|
||||
default: // int, long, long_long
|
||||
case 4:
|
||||
case 8: // int, long, long_long
|
||||
as.mov(type, mem, reg.forType(type));
|
||||
break;
|
||||
default:
|
||||
throw new Error("unloadable value size: " + type.size());
|
||||
}
|
||||
}
|
||||
// #@@}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ package net.loveruby.cflat.compiler;
|
|||
import net.loveruby.cflat.ast.*;
|
||||
import net.loveruby.cflat.ir.*;
|
||||
import net.loveruby.cflat.type.Type;
|
||||
import net.loveruby.cflat.type.TypeRef;
|
||||
import net.loveruby.cflat.type.TypeTable;
|
||||
import net.loveruby.cflat.asm.Label;
|
||||
import net.loveruby.cflat.exception.*;
|
||||
|
|
@ -463,11 +462,14 @@ class IRGenerator implements ASTVisitor<Void, Expr> {
|
|||
// evaluate rhs before lhs.
|
||||
Expr rhs = transform(node.rhs());
|
||||
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) {
|
||||
Expr rhs = expandPointerArithmetic(_rhs, op, lhs.type());
|
||||
private Expr transformOpAssign(Expr lhs, Op op, Expr _rhs, Type lhsType) {
|
||||
Expr rhs = expandPointerArithmetic(_rhs, op, lhsType);
|
||||
if (isStatement()) {
|
||||
if (lhs.isConstantAddress()) {
|
||||
// lhs = lhs op rhs
|
||||
|
|
@ -476,7 +478,7 @@ class IRGenerator implements ASTVisitor<Void, Expr> {
|
|||
else {
|
||||
// a = &lhs, *a = *a op rhs
|
||||
Expr addr = addressOf(lhs);
|
||||
DefinedVariable a = tmpVar(addr.type());
|
||||
DefinedVariable a = tmpVar(pointerTo(lhsType));
|
||||
assign(ref(a), addr);
|
||||
assign(deref(a), new Bin(lhs.type(), op, deref(a), rhs));
|
||||
}
|
||||
|
|
@ -485,7 +487,7 @@ class IRGenerator implements ASTVisitor<Void, Expr> {
|
|||
else {
|
||||
// a = &lhs, *a = *a op rhs, *a
|
||||
Expr addr = addressOf(lhs);
|
||||
DefinedVariable a = tmpVar(addr.type());
|
||||
DefinedVariable a = tmpVar(pointerTo(lhsType));
|
||||
assignBeforeStmt(ref(a), addr);
|
||||
assignBeforeStmt(deref(a), new Bin(lhs.type(), op, deref(a), rhs));
|
||||
return deref(a);
|
||||
|
|
@ -508,7 +510,8 @@ class IRGenerator implements ASTVisitor<Void, Expr> {
|
|||
public Expr visit(PrefixOpNode node) {
|
||||
return transformOpAssign(transformLHS(node.expr()),
|
||||
binOp(node.operator()),
|
||||
intValue(1));
|
||||
intValue(1),
|
||||
node.expr().type());
|
||||
}
|
||||
|
||||
public Expr visit(SuffixOpNode node) {
|
||||
|
|
@ -516,27 +519,29 @@ class IRGenerator implements ASTVisitor<Void, Expr> {
|
|||
Op op = binOp(node.operator());
|
||||
if (isStatement()) {
|
||||
// expr++; -> expr += 1;
|
||||
return transformOpAssign(lhs, op, intValue(1));
|
||||
return transformOpAssign(lhs, op, intValue(1), node.expr().type());
|
||||
}
|
||||
else if (lhs.isConstantAddress()) {
|
||||
// f(expr++) -> v = expr; expr = expr + 1, f(v)
|
||||
DefinedVariable v = tmpVar(lhs.type());
|
||||
DefinedVariable v = tmpVar(node.expr().type());
|
||||
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));
|
||||
return ref(v);
|
||||
}
|
||||
else {
|
||||
// f(expr++) -> a = &expr, v = *a; *a = *a + 1, f(v)
|
||||
Expr addr = addressOf(lhs);
|
||||
DefinedVariable a = tmpVar(addr.type());
|
||||
DefinedVariable v = tmpVar(lhs.type());
|
||||
DefinedVariable a = tmpVar(pointerTo(node.expr().type()));
|
||||
DefinedVariable v = tmpVar(node.expr().type());
|
||||
assignBeforeStmt(ref(a), addr);
|
||||
assignBeforeStmt(ref(v), deref(a));
|
||||
assignBeforeStmt(deref(a),
|
||||
new Bin(lhs.type(), op,
|
||||
deref(a),
|
||||
expandPointerArithmetic(intValue(1), op, lhs.type())));
|
||||
expandPointerArithmetic(intValue(1),
|
||||
op, node.expr().type())));
|
||||
return ref(v);
|
||||
}
|
||||
}
|
||||
|
|
@ -547,7 +552,7 @@ class IRGenerator implements ASTVisitor<Void, Expr> {
|
|||
while (args.hasPrevious()) {
|
||||
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 right = transform(node.right());
|
||||
if (node.operator().equals("+") || node.operator().equals("-")) {
|
||||
if (left.type().isDereferable()) {
|
||||
right = new Bin(right.type(), Op.MUL,
|
||||
right, ptrDiff(left.type().baseType().size()));
|
||||
if (node.left().type().isDereferable()) {
|
||||
right = new Bin(ptrDiffType(), Op.MUL,
|
||||
right, ptrDiff(node.left().type().baseType().size()));
|
||||
}
|
||||
else if (right.type().isDereferable()) {
|
||||
left = new Bin(left.type(), Op.MUL,
|
||||
left, ptrDiff(right.type().baseType().size()));
|
||||
else if (node.right().type().isDereferable()) {
|
||||
left = new Bin(ptrDiffType(), Op.MUL,
|
||||
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());
|
||||
}
|
||||
else {
|
||||
return new Uni(node.type(), Op.internUnary(node.operator()),
|
||||
return new Uni(asmType(node.type()),
|
||||
Op.internUnary(node.operator()),
|
||||
transform(node.expr()));
|
||||
}
|
||||
}
|
||||
|
||||
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));
|
||||
return deref(
|
||||
new Bin(pointerTo(node.type()), Op.ADD,
|
||||
transform(node.baseExpr()), offset));
|
||||
new Bin(pointer(), Op.ADD, transform(node.baseExpr()), offset),
|
||||
node.type());
|
||||
}
|
||||
|
||||
// For multidimension array: t[e][d][c][b][a];
|
||||
|
|
@ -599,10 +607,9 @@ class IRGenerator implements ASTVisitor<Void, Expr> {
|
|||
// #@@range/transformArrayIndex{
|
||||
private Expr transformArrayIndex(ArefNode node) {
|
||||
if (node.isMultiDimension()) {
|
||||
return new Bin(
|
||||
typeTable.signedInt(), Op.ADD,
|
||||
return new Bin(signedInt(), Op.ADD,
|
||||
transform(node.index()),
|
||||
new Bin(typeTable.signedInt(), Op.MUL,
|
||||
new Bin(signedInt(), Op.MUL,
|
||||
intValue(node.length()),
|
||||
transformArrayIndex((ArefNode)node.expr())));
|
||||
}
|
||||
|
|
@ -613,21 +620,21 @@ class IRGenerator implements ASTVisitor<Void, Expr> {
|
|||
// #@@}
|
||||
|
||||
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())),
|
||||
intValue(node.offset()));
|
||||
return node.shouldEvaluatedToAddress() ? addr : deref(addr);
|
||||
return node.shouldEvaluatedToAddress() ? addr : deref(addr, node.type());
|
||||
}
|
||||
|
||||
public Expr visit(PtrMemberNode node) {
|
||||
Expr addr = new Bin(pointerTo(node.type()), Op.ADD,
|
||||
Expr addr = new Bin(pointer(), Op.ADD,
|
||||
transform(node.expr()),
|
||||
intValue(node.offset()));
|
||||
return node.shouldEvaluatedToAddress() ? addr : deref(addr);
|
||||
return node.shouldEvaluatedToAddress() ? addr : deref(addr, node.type());
|
||||
}
|
||||
|
||||
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) {
|
||||
|
|
@ -642,7 +649,8 @@ class IRGenerator implements ASTVisitor<Void, Expr> {
|
|||
|
||||
public Expr visit(CastNode node) {
|
||||
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 {
|
||||
return transform(node.expr());
|
||||
|
|
@ -658,16 +666,16 @@ class IRGenerator implements ASTVisitor<Void, Expr> {
|
|||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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) {
|
||||
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();
|
||||
}
|
||||
else {
|
||||
Type base = expr.type();
|
||||
Type t = shouldEvalutedToAddress(expr) ? base : pointerTo(base);
|
||||
return new Addr(t, expr);
|
||||
return new Addr(pointer(), expr);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean shouldEvalutedToAddress(Expr expr) {
|
||||
return expr.type().isArray()
|
||||
|| ((expr instanceof Var) && ((Var)expr).entity().cannotLoad());
|
||||
}
|
||||
|
||||
private Var ref(DefinedVariable var) {
|
||||
return new Var(var);
|
||||
return new Var(varType(var.type()), var);
|
||||
}
|
||||
|
||||
// add DereferenceNode on top of the var.
|
||||
private Mem deref(DefinedVariable var) {
|
||||
return deref(ref(var));
|
||||
return deref(ref(var), var.type().baseType());
|
||||
}
|
||||
|
||||
// add DereferenceNode on top of the expr.
|
||||
private Mem deref(Expr expr) {
|
||||
return new Mem(expr.type().baseType(), expr);
|
||||
private Mem deref(Expr expr, Type t) {
|
||||
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) {
|
||||
return typeTable.pointerTo(t);
|
||||
}
|
||||
|
||||
private IntValue intValue(long n) {
|
||||
return new IntValue(typeTable.signedInt(), n);
|
||||
private net.loveruby.cflat.asm.Type asmType(Type t) {
|
||||
if (t.isVoid()) return signedInt();
|
||||
return net.loveruby.cflat.asm.Type.get(
|
||||
t.isInteger() && t.isSigned(),
|
||||
t.size());
|
||||
}
|
||||
|
||||
private IntValue ptrDiff(long n) {
|
||||
return new IntValue(typeTable.ptrDiffType(), n);
|
||||
private net.loveruby.cflat.asm.Type varType(Type t) {
|
||||
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) {
|
||||
t.setType(typeTable.get(t.typeRef()));
|
||||
private net.loveruby.cflat.asm.Type signedInt() {
|
||||
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) {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
package net.loveruby.cflat.ir;
|
||||
import net.loveruby.cflat.type.Type;
|
||||
import net.loveruby.cflat.asm.Type;
|
||||
|
||||
public class Addr extends Expr {
|
||||
protected Expr expr;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
package net.loveruby.cflat.ir;
|
||||
import net.loveruby.cflat.type.Type;
|
||||
import net.loveruby.cflat.asm.Type;
|
||||
|
||||
public class Bin extends Expr {
|
||||
protected Op op;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
package net.loveruby.cflat.ir;
|
||||
import net.loveruby.cflat.type.Type;
|
||||
import net.loveruby.cflat.asm.Type;
|
||||
import net.loveruby.cflat.ast.Function;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
|
|
|
|||
|
|
@ -2,8 +2,7 @@ package net.loveruby.cflat.ir;
|
|||
import net.loveruby.cflat.ast.DefinedVariable;
|
||||
import net.loveruby.cflat.ast.DefinedFunction;
|
||||
import net.loveruby.cflat.ast.Location;
|
||||
import net.loveruby.cflat.asm.Label;
|
||||
import net.loveruby.cflat.type.Type;
|
||||
import net.loveruby.cflat.asm.*;
|
||||
import java.util.List;
|
||||
import java.io.PrintStream;
|
||||
|
||||
|
|
@ -46,7 +45,11 @@ public class Dumper {
|
|||
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());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
package net.loveruby.cflat.ir;
|
||||
import net.loveruby.cflat.type.Type;
|
||||
import net.loveruby.cflat.asm.*;
|
||||
|
||||
abstract public class Expr implements Dumpable {
|
||||
|
|
|
|||
|
|
@ -7,8 +7,7 @@ import net.loveruby.cflat.ast.DefinedFunction;
|
|||
import net.loveruby.cflat.ast.UndefinedFunction;
|
||||
import net.loveruby.cflat.ast.ConstantTable;
|
||||
import net.loveruby.cflat.ast.ToplevelScope;
|
||||
import net.loveruby.cflat.type.TypeTable;
|
||||
import net.loveruby.cflat.type.Type;
|
||||
import net.loveruby.cflat.asm.Type;
|
||||
import java.io.PrintStream;
|
||||
import java.util.*;
|
||||
|
||||
|
|
@ -19,15 +18,13 @@ public class IR {
|
|||
protected List<UndefinedFunction> funcdecls;
|
||||
protected ToplevelScope scope;
|
||||
protected ConstantTable constantTable;
|
||||
protected TypeTable typeTable;
|
||||
|
||||
public IR(Location source,
|
||||
List<DefinedVariable> defvars,
|
||||
List<DefinedFunction> defuns,
|
||||
List<UndefinedFunction> funcdecls,
|
||||
ToplevelScope scope,
|
||||
ConstantTable constantTable,
|
||||
TypeTable typeTable) {
|
||||
ConstantTable constantTable) {
|
||||
super();
|
||||
this.source = source;
|
||||
this.defvars = defvars;
|
||||
|
|
@ -35,7 +32,6 @@ public class IR {
|
|||
this.funcdecls = funcdecls;
|
||||
this.scope = scope;
|
||||
this.constantTable = constantTable;
|
||||
this.typeTable = typeTable;
|
||||
}
|
||||
|
||||
public String fileName() {
|
||||
|
|
@ -88,8 +84,9 @@ public class IR {
|
|||
return constantTable;
|
||||
}
|
||||
|
||||
public Type naturalType() {
|
||||
return this.typeTable.unsignedLong();
|
||||
public net.loveruby.cflat.asm.Type naturalType() {
|
||||
// platform dependent!!!
|
||||
return Type.S_INT32;
|
||||
}
|
||||
|
||||
public void dump() {
|
||||
|
|
|
|||
|
|
@ -1,8 +1,5 @@
|
|||
package net.loveruby.cflat.ir;
|
||||
import net.loveruby.cflat.type.Type;
|
||||
import net.loveruby.cflat.asm.IntegerLiteral;
|
||||
import net.loveruby.cflat.asm.ImmediateValue;
|
||||
import net.loveruby.cflat.asm.MemoryReference;
|
||||
import net.loveruby.cflat.asm.*;
|
||||
|
||||
public class IntValue extends Expr {
|
||||
protected long value;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
package net.loveruby.cflat.ir;
|
||||
import net.loveruby.cflat.type.Type;
|
||||
import net.loveruby.cflat.asm.Type;
|
||||
|
||||
public class Mem extends Expr {
|
||||
protected Expr expr;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
package net.loveruby.cflat.ir;
|
||||
import net.loveruby.cflat.type.Type;
|
||||
import net.loveruby.cflat.ast.ConstantEntry;
|
||||
import net.loveruby.cflat.asm.*;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
package net.loveruby.cflat.ir;
|
||||
import net.loveruby.cflat.type.Type;
|
||||
import net.loveruby.cflat.asm.Type;
|
||||
|
||||
public class Uni extends Expr {
|
||||
protected Op op;
|
||||
|
|
|
|||
|
|
@ -1,16 +1,22 @@
|
|||
package net.loveruby.cflat.ir;
|
||||
import net.loveruby.cflat.ast.Entity;
|
||||
import net.loveruby.cflat.asm.AsmOperand;
|
||||
import net.loveruby.cflat.asm.MemoryReference;
|
||||
import net.loveruby.cflat.asm.*;
|
||||
|
||||
public class Var extends Expr {
|
||||
protected Entity entity;
|
||||
|
||||
public Var(Entity entity) {
|
||||
super(entity.type());
|
||||
public Var(Type type, Entity entity) {
|
||||
super(type);
|
||||
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 Entity entity() { return entity; }
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ public class TypeTable {
|
|||
|
||||
static private TypeTable newTable(int charsize, int shortsize,
|
||||
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(IntegerTypeRef.charRef(),
|
||||
new IntegerType(charsize, true, "char"));
|
||||
|
|
@ -33,12 +33,14 @@ public class TypeTable {
|
|||
return table;
|
||||
}
|
||||
|
||||
protected int intSize;
|
||||
protected int pointerSize;
|
||||
protected Map<TypeRef, Type> table;
|
||||
|
||||
public TypeTable(int ptrsize) {
|
||||
pointerSize = ptrsize;
|
||||
table = new HashMap<TypeRef, Type>();
|
||||
public TypeTable(int intSize, int pointerSize) {
|
||||
this.intSize = intSize;
|
||||
this.pointerSize = pointerSize;
|
||||
this.table = new HashMap<TypeRef, Type>();
|
||||
}
|
||||
|
||||
public boolean isDefined(TypeRef ref) {
|
||||
|
|
@ -88,7 +90,15 @@ public class TypeTable {
|
|||
return type;
|
||||
}
|
||||
|
||||
public long pointerSize() {
|
||||
public int intSize() {
|
||||
return this.intSize;
|
||||
}
|
||||
|
||||
public int pointerSize() {
|
||||
return this.pointerSize;
|
||||
}
|
||||
|
||||
public int maxIntSize() {
|
||||
return this.pointerSize;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue