diff --git a/ChangeLog b/ChangeLog index 3d507c1..4d2c532 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,21 @@ +Sat May 16 17:20:36 2009 Minero Aoki + + * net/loveruby/cflat/asm/Register.java: use enum for register + name. + + * net/loveruby/cflat/sysdep/x86/RegKind.java: new enum. + + * net/loveruby/cflat/sysdep/x86/Register.java: move system + dependent code to sysdep/x86/Register. + + * net/loveruby/cflat/asm/IndirectMemoryReference.java: reduce + dependency to Register method. + + * net/loveruby/cflat/sysdep/x86/AssemblyFile.java: use RegKind. + + * net/loveruby/cflat/sysdep/x86/CodeGenerator.java: reg(*) -> + ax(), bx(), cx(), ... + Wed May 13 03:22:46 2009 Minero Aoki * compiler/Compiler.java: grand refactoring. diff --git a/net/loveruby/cflat/asm/IndirectMemoryReference.java b/net/loveruby/cflat/asm/IndirectMemoryReference.java index 21a5828..b90ff1d 100644 --- a/net/loveruby/cflat/asm/IndirectMemoryReference.java +++ b/net/loveruby/cflat/asm/IndirectMemoryReference.java @@ -68,12 +68,6 @@ public class IndirectMemoryReference extends MemoryReference { } protected int cmp(IndirectMemoryReference mem) { - int c = base.baseName().compareTo(mem.base.baseName()); - if (c != 0) { - return c; - } - else { - return offset.compareTo(mem.offset); - } + return offset.compareTo(mem.offset); } } diff --git a/net/loveruby/cflat/asm/Register.java b/net/loveruby/cflat/asm/Register.java index 239d31c..b07a4ca 100644 --- a/net/loveruby/cflat/asm/Register.java +++ b/net/loveruby/cflat/asm/Register.java @@ -1,43 +1,10 @@ package net.loveruby.cflat.asm; abstract public class Register extends AsmOperand { - protected int size; - protected String name; - - public Register(int size, String name) { - this.size = size; - this.name = name; - } - - abstract public Register forType(Type t); - public boolean isRegister() { return true; } - public boolean equals(Object other) { - if (!(other instanceof Register)) return false; - return equals((Register)other); - } - - public int hashCode() { - return name.hashCode(); - } - - /** size difference does NOT matter. */ - public boolean equals(Register reg) { - return name.equals(reg.baseName()); - } - - public String baseName() { - return name; - } - - // default implementation - public String name() { - return name; - } - public void collectStatistics(AsmStatistics stats) { stats.registerUsed(this); } diff --git a/net/loveruby/cflat/sysdep/x86/AssemblyFile.java b/net/loveruby/cflat/sysdep/x86/AssemblyFile.java index 3593063..5987457 100644 --- a/net/loveruby/cflat/sysdep/x86/AssemblyFile.java +++ b/net/loveruby/cflat/sysdep/x86/AssemblyFile.java @@ -213,14 +213,15 @@ public class AssemblyFile { // #@@range/stackTop{ IndirectMemoryReference stackTop() { - return new IndirectMemoryReference(-stackPointer, new Register("bp")); + return new IndirectMemoryReference( + -stackPointer, new Register(RegKind.BP, naturalType)); } // #@@} // #@@range/virtualPush{ void virtualPush(Register reg) { if (verbose) { - comment("push " + reg.name() + " -> " + stackTop()); + comment("push " + reg.baseName() + " -> " + stackTop()); } extendVirtualStack(stackWordSize); relocatableMov(reg, stackTop()); @@ -230,7 +231,7 @@ public class AssemblyFile { // #@@range/virtualPop{ void virtualPop(Register reg) { if (verbose) { - comment("pop " + reg.name() + " <- " + stackTop()); + comment("pop " + reg.baseName() + " <- " + stackTop()); } relocatableMov(stackTop(), reg); rewindVirtualStack(stackWordSize); diff --git a/net/loveruby/cflat/sysdep/x86/CodeGenerator.java b/net/loveruby/cflat/sysdep/x86/CodeGenerator.java index f749ed0..3efa9ba 100644 --- a/net/loveruby/cflat/sysdep/x86/CodeGenerator.java +++ b/net/loveruby/cflat/sysdep/x86/CodeGenerator.java @@ -250,7 +250,7 @@ public class CodeGenerator } private Register GOTBaseReg() { - return reg("bx"); + return bx(); } // #@@} @@ -502,10 +502,10 @@ public class CodeGenerator private List calleeSavedRegisters() { if (calleeSavedRegistersCache == null) { List regs = new ArrayList(); - regs.add(reg("bx")); - regs.add(reg("si")); - regs.add(reg("di")); - regs.add(reg("bp")); + regs.add(bx()); + regs.add(si()); + regs.add(di()); + regs.add(bp()); calleeSavedRegistersCache = regs; } return calleeSavedRegistersCache; @@ -645,7 +645,7 @@ public class CodeGenerator ListIterator args = node.finalArg(); while (args.hasPrevious()) { compile(args.previous()); - as.push(reg("ax")); + as.push(ax()); } // call if (node.isStaticCall()) { @@ -655,7 +655,7 @@ public class CodeGenerator else { // call via pointer compile(node.expr()); - as.callAbsolute(reg("ax")); + as.callAbsolute(ax()); } // rewind stack // >4 bytes arguments are not supported. @@ -703,7 +703,7 @@ public class CodeGenerator // #@@range/compile_BranchIf{ public Void visit(BranchIf node) { compile(node.cond()); - testCond(node.cond().type(), reg("ax")); + testCond(node.cond().type(), ax()); as.jnz(node.thenLabel()); as.jmp(node.elseLabel()); return null; @@ -715,8 +715,8 @@ public class CodeGenerator compile(node.cond()); Type t = node.cond().type(); for (Case c : node.cases()) { - as.mov(imm(c.value), reg("cx")); - as.cmp(t, reg("cx", t), reg("ax", t)); + as.mov(imm(c.value), cx()); + as.cmp(t, cx(t), ax(t)); as.je(c.label); } as.jmp(node.defaultLabel()); @@ -765,17 +765,17 @@ public class CodeGenerator } else if (node.right().isConstantAddress()) { compile(node.left()); - loadVariable(((Var)node.right()), reg("cx")); - right = reg("cx", node.type()); + loadVariable(((Var)node.right()), cx()); + right = cx(node.type()); } else { compile(node.right()); - as.virtualPush(reg("ax")); + as.virtualPush(ax()); compile(node.left()); - as.virtualPop(reg("cx")); - right = reg("cx", node.type()); + as.virtualPop(cx()); + right = cx(node.type()); } - compileBinaryOp(node.type(), node.op(), reg("ax", node.type()), right); + compileBinaryOp(node.type(), node.op(), ax(node.type()), right); return null; } // #@@} @@ -815,17 +815,17 @@ public class CodeGenerator case S_DIV: case S_MOD: as.cltd(); - as.idiv(t, reg("cx", t)); + as.idiv(t, cx(t)); if (op == Op.S_MOD) { - as.mov(reg("dx"), left); + as.mov(dx(), left); } break; case U_DIV: case U_MOD: - as.mov(imm(0), reg("dx")); - as.div(t, reg("cx", t)); + as.mov(imm(0), dx()); + as.div(t, cx(t)); if (op == Op.U_MOD) { - as.mov(reg("dx"), left); + as.mov(dx(), left); } break; // #@@} @@ -852,7 +852,7 @@ public class CodeGenerator // #@@range/compileBinaryOp_cmpops{ default: // Comparison operators - as.cmp(t, right, reg("ax", t)); + as.cmp(t, right, ax(t)); switch (op) { case EQ: as.sete (al()); break; case NEQ: as.setne(al()); break; @@ -867,7 +867,7 @@ public class CodeGenerator default: throw new Error("unknown binary operator: " + op); } - as.movzb(t, al(), reg("ax", t)); + as.movzb(t, al(), ax(t)); } // #@@} // #@@range/compileBinaryOp_end{ @@ -879,30 +879,28 @@ public class CodeGenerator compile(node.expr()); switch (node.op()) { case UMINUS: - as.neg(node.expr().type(), reg("ax", node.expr().type())); + as.neg(node.expr().type(), ax(node.expr().type())); break; case BIT_NOT: - as.not(node.expr().type(), reg("ax", node.expr().type())); + as.not(node.expr().type(), ax(node.expr().type())); break; case NOT: - testCond(node.expr().type(), reg("ax")); + testCond(node.expr().type(), ax()); as.sete(al()); - as.movzbl(al(), reg("ax")); + as.movzbl(al(), ax()); break; case S_CAST: { Type src = node.expr().type(); Type dest = node.type(); - as.movsx(src, dest, - reg("ax").forType(src), reg("ax").forType(dest)); + as.movsx(src, dest, ax(src), ax(dest)); } break; case U_CAST: { Type src = node.expr().type(); Type dest = node.type(); - as.movzx(src, dest, - reg("ax").forType(src), reg("ax").forType(dest)); + as.movzx(src, dest, ax(src), ax(dest)); } break; default: @@ -914,21 +912,21 @@ public class CodeGenerator // #@@range/compile_Var{ public Void visit(Var node) { - loadVariable(node, reg("ax")); + loadVariable(node, ax()); return null; } // #@@} // #@@range/compile_Int{ public Void visit(Int node) { - loadConstant(node, reg("ax")); + loadConstant(node, ax()); return null; } // #@@} // #@@range/compile_Str{ public Void visit(Str node) { - loadConstant(node, reg("ax")); + loadConstant(node, ax()); return null; } // #@@} @@ -941,21 +939,21 @@ public class CodeGenerator public Void visit(Assign node) { if (node.lhs().isConstantAddress() && node.lhs().memref() != null) { compile(node.rhs()); - save(node.lhs().type(), reg("ax"), node.lhs().memref()); + save(node.lhs().type(), ax(), node.lhs().memref()); } else if (node.rhs().isConstant()) { compile(node.lhs()); - as.mov(reg("ax"), reg("cx")); - loadConstant(node.rhs(), reg("ax")); - save(node.lhs().type(), reg("ax"), mem(reg("cx"))); + as.mov(ax(), cx()); + loadConstant(node.rhs(), ax()); + save(node.lhs().type(), ax(), mem(cx())); } else { compile(node.rhs()); - as.virtualPush(reg("ax")); + as.virtualPush(ax()); compile(node.lhs()); - as.mov(reg("ax"), reg("cx")); - as.virtualPop(reg("ax")); - save(node.lhs().type(), reg("ax"), mem(reg("cx"))); + as.mov(ax(), cx()); + as.virtualPop(ax()); + save(node.lhs().type(), ax(), mem(cx())); } return null; } @@ -964,14 +962,14 @@ public class CodeGenerator // #@@range/compile_Mem{ public Void visit(Mem node) { compile(node.expr()); - load(node.type(), mem(reg("ax")), reg("ax")); + load(node.type(), mem(ax()), ax()); return null; } // #@@} // #@@range/compile_Addr{ public Void visit(Addr node) { - loadAddress(node.entity(), reg("ax")); + loadAddress(node.entity(), ax()); return null; } // #@@} @@ -1023,21 +1021,21 @@ public class CodeGenerator } // #@@} - // #@@range/dsl_regs{ - private Register bp() { return reg("bp"); } - private Register sp() { return reg("sp"); } - private Register al() { return new Register(1, "ax"); } - private Register cl() { return new Register(1, "cx"); } - // #@@} + // #@@range/reg_dsls{ + private Register ax() { return new Register(RegKind.AX, NATURAL_TYPE); } + private Register bx() { return new Register(RegKind.BX, NATURAL_TYPE); } + private Register cx() { return new Register(RegKind.CX, NATURAL_TYPE); } + private Register dx() { return new Register(RegKind.DX, NATURAL_TYPE); } + private Register si() { return new Register(RegKind.SI, NATURAL_TYPE); } + private Register di() { return new Register(RegKind.DI, NATURAL_TYPE); } + private Register bp() { return new Register(RegKind.BP, NATURAL_TYPE); } + private Register sp() { return new Register(RegKind.SP, NATURAL_TYPE); } - // #@@range/reg{ - private Register reg(String name, Type type) { - return new Register(name).forType(type); - } + private Register al() { return new Register(RegKind.AX, Type.INT8); } + private Register cl() { return new Register(RegKind.CX, Type.INT8); } - private Register reg(String name) { - return new Register(name); - } + private Register ax(Type t) { return new Register(RegKind.AX, t); } + private Register cx(Type t) { return new Register(RegKind.AX, t); } // #@@} // #@@range/mem{ diff --git a/net/loveruby/cflat/sysdep/x86/RegKind.java b/net/loveruby/cflat/sysdep/x86/RegKind.java new file mode 100644 index 0000000..5bb6d0b --- /dev/null +++ b/net/loveruby/cflat/sysdep/x86/RegKind.java @@ -0,0 +1,5 @@ +package net.loveruby.cflat.sysdep.x86; + +enum RegKind { + AX, BX, CX, DX, SI, DI, SP, BP; +} diff --git a/net/loveruby/cflat/sysdep/x86/Register.java b/net/loveruby/cflat/sysdep/x86/Register.java index 7af7d12..22a4972 100644 --- a/net/loveruby/cflat/sysdep/x86/Register.java +++ b/net/loveruby/cflat/sysdep/x86/Register.java @@ -1,54 +1,67 @@ package net.loveruby.cflat.sysdep.x86; import net.loveruby.cflat.asm.*; -public class Register extends net.loveruby.cflat.asm.Register { - static final private int naturalSize = 4; +class Register extends net.loveruby.cflat.asm.Register { + RegKind kind; + Type type; - public Register(String name) { - super(naturalSize, name); + Register(RegKind kind, Type type) { + this.kind = kind; + this.type = type; } - public Register(int size, String name) { - super(size, name); + Register forType(Type t) { + return new Register(kind, t); } - public Register forType(Type t) { - switch (t.size()) { - case 1: - case 2: - case 4: - return new Register(t.size(), name); - default: - throw new Error("invalid register size: " + t.size()); - } + public boolean isRegister() { return true; } + + public boolean equals(Object other) { + return (other instanceof Register) && equals((Register)other); } - public String name() { - switch (size) { - case 1: return lowerByteRegister(name); - case 2: return name; - case 4: return "e" + name; - default: - throw new Error("invalid register size: " + size); - } + /** size difference does NOT matter. */ + public boolean equals(Register reg) { + return kind.equals(reg.kind); } - private String lowerByteRegister(String baseName) { - if (! hasLowerByteRegister(baseName)) { - throw new Error("does not have lower-byte register: " + baseName); - } - return baseName.substring(0, 1) + "l"; + public int hashCode() { + return kind.hashCode(); } - private boolean hasLowerByteRegister(String baseName) { - if (baseName.equals("ax")) return true; - if (baseName.equals("bx")) return true; - if (baseName.equals("cx")) return true; - if (baseName.equals("dx")) return true; - return false; + RegKind kind() { + return kind; + } + + String baseName() { + return kind.toString().toLowerCase(); } public String toSource(SymbolTable table) { - return "%" + name(); + // GNU assembler dependent + return "%" + typedName(); + } + + private String typedName() { + switch (type) { + case INT8: return lowerByteRegister(); + case INT16: return baseName(); + case INT32: return "e" + baseName(); + case INT64: return "r" + baseName(); + default: + throw new Error("unknown register Type: " + type); + } + } + + private String lowerByteRegister() { + switch (kind) { + case AX: + case BX: + case CX: + case DX: + return baseName().substring(0, 1) + "l"; + default: + throw new Error("does not have lower-byte register: " + kind); + } } }