* net/loveruby/cflat/asm/Assembler.java: objectify instructions, directives, comments and labels.

* net/loveruby/cflat/asm/Label.java: inherits Assembly instead of AsmEntity.
* net/loveruby/cflat/asm/Address.java: new method #isAddress.
* net/loveruby/cflat/asm/ImmediateValue.java: accept Literals.
* net/loveruby/cflat/asm/AbsoluteAddress.java: new file.
* net/loveruby/cflat/asm/AsmComment.java: new file.
* net/loveruby/cflat/asm/Assembly.java: new file.
* net/loveruby/cflat/asm/Directive.java: new file.
* net/loveruby/cflat/asm/Reference.java -> DirectAddress.java: new file.
* net/loveruby/cflat/asm/SimpleAddress.java, CompositeAddress.java -> IndirectAddress.java
* net/loveruby/cflat/asm/Instruction.java: new file.
* net/loveruby/cflat/asm/IntegerLiteral.java: new file.
* net/loveruby/cflat/asm/Literal.java: new file.
* net/loveruby/cflat/asm/Symbol.java: new file.
* net/loveruby/cflat/compiler/CodeGenerator.java: follow asm changes.
* net/loveruby/cflat/ast/UndefinedVariable.java: 
* net/loveruby/cflat/ast/Function.java


git-svn-id: file:///Users/aamine/c/gitwork/public/cbc/trunk@4022 1b9489fe-b721-0410-924e-b54b9192deb8
This commit is contained in:
Minero Aoki 2008-09-15 15:21:14 +00:00
parent ae0f46cee4
commit 7314d4bf6f
23 changed files with 452 additions and 251 deletions

View File

@ -1,3 +1,44 @@
Tue Sep 16 00:21:10 2008 Minero Aoki <aamine@loveruby.net>
* net/loveruby/cflat/asm/Assembler.java: objectify instructions,
directives, comments and labels.
* net/loveruby/cflat/asm/Label.java: inherits Assembly instead of
AsmEntity.
* net/loveruby/cflat/asm/Address.java: new method #isAddress.
* net/loveruby/cflat/asm/ImmediateValue.java: accept Literals.
* net/loveruby/cflat/asm/AbsoluteAddress.java: new file.
* net/loveruby/cflat/asm/AsmComment.java: new file.
* net/loveruby/cflat/asm/Assembly.java: new file.
* net/loveruby/cflat/asm/Directive.java: new file.
* net/loveruby/cflat/asm/Reference.java -> DirectAddress.java: new
file.
* net/loveruby/cflat/asm/SimpleAddress.java, CompositeAddress.java
-> IndirectAddress.java
* net/loveruby/cflat/asm/Instruction.java: new file.
* net/loveruby/cflat/asm/IntegerLiteral.java: new file.
* net/loveruby/cflat/asm/Literal.java: new file.
* net/loveruby/cflat/asm/Symbol.java: new file.
* net/loveruby/cflat/compiler/CodeGenerator.java: follow asm
changes.
* net/loveruby/cflat/ast/UndefinedVariable.java:
* net/loveruby/cflat/ast/Function.java
Mon Sep 15 21:19:05 2008 Minero Aoki <aamine@loveruby.net>
* net/loveruby/cflat/compiler/Compiler.java: link libcbc on making

2
ToDo
View File

@ -14,6 +14,7 @@
* imull $1, %eax => NONE
* label renaming
* remove useless jump
* generate prologue/epilogue after function body.
* -fPIC (PIC generation)
* -shared
* remove all FIXME
@ -234,3 +235,4 @@
- -Wa, -Xassembler
- write install.sh
- va_list
- objectify instruction

View File

@ -0,0 +1,17 @@
package net.loveruby.cflat.asm;
public class AbsoluteAddress extends Address {
protected Register register;
public AbsoluteAddress(Register reg) {
this.register = reg;
}
public AsmEntity register() {
return this.register;
}
public String toString() {
return "*" + register.toString();
}
}

View File

@ -1,4 +1,7 @@
package net.loveruby.cflat.asm;
abstract public class Address extends AsmEntity {
public boolean isAddress() {
return true;
}
}

View File

@ -0,0 +1,13 @@
package net.loveruby.cflat.asm;
public class AsmComment extends Assembly {
protected String string;
public AsmComment(String string) {
this.string = string;
}
public String toSource() {
return "\t# " + string;
}
}

View File

@ -2,4 +2,8 @@ package net.loveruby.cflat.asm;
abstract public class AsmEntity {
abstract public String toString();
public boolean isAddress() {
return false;
}
}

View File

@ -4,7 +4,7 @@ import net.loveruby.cflat.utils.*;
import java.util.*;
public class Assembler {
protected List list;
protected List list; // List<Assembly>
protected Type naturalType;
static public long align(long n, long alignment) {
@ -20,154 +20,55 @@ public class Assembler {
StringBuffer buf = new StringBuffer();
Iterator i = list.iterator();
while (i.hasNext()) {
buf.append((String)i.next());
Assembly asm = (Assembly)i.next();
buf.append(asm.toSource());
buf.append("\n");
}
return buf.toString();
}
protected void op(String op) {
list.add("\t" + op);
}
protected void op(String op, AsmEntity ent) {
list.add("\t" + op + "\t" + ent.toString());
}
protected void op(String op, AsmEntity ent1, AsmEntity ent2) {
list.add("\t" + op + "\t" + ent1.toString() + ", " + ent2.toString());
}
protected void op(String op, String arg) {
list.add("\t" + op + "\t" + arg);
}
protected void op(String op, String arg1, String arg2) {
list.add("\t" + op + "\t" + arg1 + ", " + arg2);
}
protected void op(String op, String arg1, String arg2, String arg3) {
list.add("\t" + op + "\t" + arg1 + ", " + arg2 + ", " + arg3);
}
public void comment(String str) {
list.add("\t# " + str);
list.add(new AsmComment(str));
}
public void line(String str) {
list.add(str);
}
public void _file(String name) {
line("\t.file\t" + TextUtils.dumpString(name));
}
public void _text() {
line("\t.text");
}
public void _data() {
line("\t.data");
}
public void _section(String name) {
line("\t.section\t" + name);
}
public void _globl(String sym) {
line(".globl " + sym);
}
public void _local(String sym) {
line(".local " + sym);
}
public void _comm(String sym, long size, long alignment) {
line("\t.comm\t" + sym + "," + size + "," + alignment);
}
public void _align(long n) {
line("\t.align\t" + n);
}
public void _type(String sym, String type) {
line("\t.type\t" + sym + ", " + type);
}
public void _size(String sym, long size) {
_size(sym, new Long(size).toString());
}
public void _size(String sym, String size) {
line("\t.size\t" + sym + ", " + size);
}
public void _byte(long n) {
line(".byte\t" + n);
}
public void _value(long n) {
line(".value\t" + n);
}
public void _long(long n) {
line(".long\t" + n);
}
public void _long(Label label) {
line(".long\t" + label);
}
public void _quad(long n) {
line(".quad\t" + n);
}
public void _quad(Label label) {
line(".quad\t" + label);
}
public void _string(String str) {
line("\t.string\t" + TextUtils.dumpString(str));
}
public void label(String label) {
line(label + ":");
public void label(String sym) {
list.add(new Label(sym));
}
public void label(Label label) {
line(label.toString() + ":");
list.add(label);
}
public void jmp(Label label) {
op("jmp", label);
protected void directive(String direc) {
list.add(new Directive(direc));
}
public void jz(Label label) {
op("jz", label);
protected void insn(String op) {
list.add(new Instruction(op));
}
public void jnz(Label label) {
op("jnz", label);
protected void insn(String op, AsmEntity a) {
list.add(new Instruction(op, "", a));
}
public void je(Label label) {
op("je", label);
protected void insn(String op, String suffix, AsmEntity a) {
list.add(new Instruction(op, suffix, a));
}
public void jne(Label label) {
op("jne", label);
protected void insn(Type t, String op, AsmEntity a) {
list.add(new Instruction(op, typeSuffix(t), a));
}
protected void typedOp(Type t, String op, AsmEntity a) {
op(addSuffix(op, t), a);
protected void insn(String op, String suffix, AsmEntity a, AsmEntity b) {
list.add(new Instruction(op, suffix, a, b));
}
protected void typedOp(Type t, String op, AsmEntity a, AsmEntity b) {
op(addSuffix(op, t), a, b);
protected void insn(Type t, String op, AsmEntity a, AsmEntity b) {
list.add(new Instruction(op, typeSuffix(t), a, b));
}
protected String addSuffix(String op, Type t) {
return op + typeSuffix(t);
protected String typeSuffix(Type t1, Type t2) {
return typeSuffix(t1) + typeSuffix(t2);
}
protected String typeSuffix(Type t) {
@ -180,82 +81,174 @@ public class Assembler {
}
}
//
// directives
//
public void _file(String name) {
directive(".file\t" + TextUtils.dumpString(name));
}
public void _text() {
directive("\t.text");
}
public void _data() {
directive("\t.data");
}
public void _section(String name) {
directive("\t.section\t" + name);
}
public void _globl(String sym) {
directive(".globl " + sym);
}
public void _local(String sym) {
directive(".local " + sym);
}
public void _comm(String sym, long size, long alignment) {
directive("\t.comm\t" + sym + "," + size + "," + alignment);
}
public void _align(long n) {
directive("\t.align\t" + n);
}
public void _type(String sym, String type) {
directive("\t.type\t" + sym + "," + type);
}
public void _size(String sym, long size) {
_size(sym, new Long(size).toString());
}
public void _size(String sym, String size) {
directive("\t.size\t" + sym + "," + size);
}
public void _byte(long n) {
directive(".byte\t" + n);
}
public void _value(long n) {
directive(".value\t" + n);
}
public void _long(long n) {
directive(".long\t" + n);
}
public void _long(Label sym) {
directive(".long\t" + sym.toString());
}
public void _quad(long n) {
directive(".quad\t" + n);
}
public void _quad(Label sym) {
directive(".quad\t" + sym.toString());
}
public void _string(String str) {
directive("\t.string\t" + TextUtils.dumpString(str));
}
//
// Instructions
//
public void jmp(Label label) {
insn("jmp", new Symbol(label));
}
public void jz(Label label) {
insn("jz", new Symbol(label));
}
public void jnz(Label label) {
insn("jnz", new Symbol(label));
}
public void je(Label label) {
insn("je", new Symbol(label));
}
public void jne(Label label) {
insn("jne", new Symbol(label));
}
public void cmp(Type t, Register a, Register b) {
typedOp(t, "cmp", a, b);
insn(t, "cmp", a, b);
}
public void sete(Register reg) {
op("sete", reg);
insn("sete", reg);
}
public void setne(Register reg) {
op("setne", reg);
insn("setne", reg);
}
public void seta(Register reg) {
op("seta", reg);
insn("seta", reg);
}
public void setae(Register reg) {
op("setae", reg);
insn("setae", reg);
}
public void setb(Register reg) {
op("setb", reg);
insn("setb", reg);
}
public void setbe(Register reg) {
op("setbe", reg);
insn("setbe", reg);
}
public void setg(Register reg) {
op("setg", reg);
insn("setg", reg);
}
public void setge(Register reg) {
op("setge", reg);
insn("setge", reg);
}
public void setl(Register reg) {
op("setl", reg);
insn("setl", reg);
}
public void setle(Register reg) {
op("setle", reg);
insn("setle", reg);
}
public void test(Type type, Register a, Register b) {
typedOp(type, "test", a, b);
insn(type, "test", a, b);
}
public void push(Register reg) {
push(naturalType, reg);
}
public void push(Type t, Register reg) {
typedOp(t, "push", reg);
insn("push", typeSuffix(naturalType), reg);
}
public void pop(Register reg) {
pop(naturalType, reg);
}
public void pop(Type t, Register reg) {
op("popl", reg);
insn("pop", typeSuffix(naturalType), reg);
}
// call function by relative address
public void call(String sym) {
op("call", sym);
insn("call", new Symbol(new Label(sym)));
}
// call function by absolute address
public void callAbsolute(Register reg) {
op("call", "*" + reg.toString());
insn("call", new AbsoluteAddress(reg));
}
public void ret() {
op("ret");
insn("ret");
}
public void mov(AsmEntity src, AsmEntity dest) {
@ -263,35 +256,35 @@ public class Assembler {
}
public void mov(Type type, AsmEntity src, AsmEntity dest) {
typedOp(type, "mov", src, dest);
insn(type, "mov", src, dest);
}
public void movsx(Type from, Type to, AsmEntity src, AsmEntity dest) {
op("movs" + typeSuffix(from) + typeSuffix(to), src, dest);
public void movsx(Type t1, Type t2, AsmEntity src, AsmEntity dest) {
insn("movs", typeSuffix(t1, t2), src, dest);
}
public void movsbl(AsmEntity src, AsmEntity dest) {
op("movsbl", src, dest);
insn("movs", "bl", src, dest);
}
public void movswl(AsmEntity src, AsmEntity dest) {
op("movswl", src, dest);
insn("movs", "wl", src, dest);
}
public void movzx(Type from, Type to, AsmEntity src, AsmEntity dest) {
op("movz" + typeSuffix(from) + typeSuffix(to), src, dest);
public void movzx(Type t1, Type t2, AsmEntity src, AsmEntity dest) {
insn("movz", typeSuffix(t1, t2), src, dest);
}
public void movzb(Type type, AsmEntity src, AsmEntity dest) {
typedOp(type, "movzb", src, dest);
public void movzb(Type t, AsmEntity src, AsmEntity dest) {
insn("movz", "b" + typeSuffix(t), src, dest);
}
public void movzbl(AsmEntity src, AsmEntity dest) {
op("movzbl", src, dest);
insn("movz", "bl", src, dest);
}
public void movzwl(AsmEntity src, AsmEntity dest) {
op("movzwl", src, dest);
insn("movz", "wl", src, dest);
}
public void lea(AsmEntity src, AsmEntity dest) {
@ -299,19 +292,19 @@ public class Assembler {
}
public void lea(Type type, AsmEntity src, AsmEntity dest) {
typedOp(type, "lea", src, dest);
insn(type, "lea", src, dest);
}
public void neg(Type type, Register reg) {
typedOp(type, "neg", reg);
insn(type, "neg", reg);
}
public void inc(Type type, AsmEntity reg) {
typedOp(type, "inc", reg);
insn(type, "inc", reg);
}
public void dec(Type type, AsmEntity reg) {
typedOp(type, "dec", reg);
insn(type, "dec", reg);
}
public void add(AsmEntity diff, AsmEntity base) {
@ -319,7 +312,7 @@ public class Assembler {
}
public void add(Type type, AsmEntity diff, AsmEntity base) {
typedOp(type, "add", diff, base);
insn(type, "add", diff, base);
}
public void sub(AsmEntity diff, AsmEntity base) {
@ -327,7 +320,7 @@ public class Assembler {
}
public void sub(Type type, AsmEntity diff, AsmEntity base) {
typedOp(type, "sub", diff, base);
insn(type, "sub", diff, base);
}
public void imul(AsmEntity m, Register base) {
@ -335,46 +328,46 @@ public class Assembler {
}
public void imul(Type type, AsmEntity m, Register base) {
typedOp(type, "imul", m, base);
insn(type, "imul", m, base);
}
public void cltd() {
op("cltd");
insn("cltd");
}
public void div(Type type, Register base) {
typedOp(type, "div", base);
insn(type, "div", base);
}
public void idiv(Type type, Register base) {
typedOp(type, "idiv", base);
insn(type, "idiv", base);
}
public void not(Type type, Register reg) {
typedOp(type, "not", reg);
insn(type, "not", reg);
}
public void and(Type type, Register bits, Register base) {
typedOp(type, "and", bits, base);
insn(type, "and", bits, base);
}
public void or(Type type, Register bits, Register base) {
typedOp(type, "or", bits, base);
insn(type, "or", bits, base);
}
public void xor(Type type, Register bits, Register base) {
typedOp(type, "xor", bits, base);
insn(type, "xor", bits, base);
}
public void sar(Type type, Register bits, Register base) {
typedOp(type, "sar", bits, base);
insn(type, "sar", bits, base);
}
public void sal(Type type, Register bits, Register base) {
typedOp(type, "sal", bits, base);
insn(type, "sal", bits, base);
}
public void shr(Type type, Register bits, Register base) {
typedOp(type, "shr", bits, base);
insn(type, "shr", bits, base);
}
}

View File

@ -0,0 +1,13 @@
package net.loveruby.cflat.asm;
abstract public class Assembly {
abstract public String toSource();
public boolean isInstruction() {
return false;
}
public boolean isLabel() {
return false;
}
}

View File

@ -1,23 +0,0 @@
package net.loveruby.cflat.asm;
public class CompositeAddress extends Address {
long offset;
Register base;
public CompositeAddress(long off, Register reg) {
offset = off;
base = reg;
}
public long offset() {
return offset;
}
public Register base() {
return base;
}
public String toString() {
return "" + offset + "(" + base.toString() + ")";
}
}

View File

@ -0,0 +1,21 @@
package net.loveruby.cflat.asm;
public class DirectAddress extends Address {
protected Literal value;
public DirectAddress(Label label) {
this.value = new Symbol(label);
}
public DirectAddress(IntegerLiteral n) {
this.value = n;
}
public Literal value() {
return this.value;
}
public String toString() {
return this.value.toString();
}
}

View File

@ -0,0 +1,13 @@
package net.loveruby.cflat.asm;
public class Directive extends Assembly {
protected String content;
public Directive(String content) {
this.content = content;
}
public String toSource() {
return this.content;
}
}

View File

@ -1,17 +1,25 @@
package net.loveruby.cflat.asm;
public class ImmediateValue extends AsmEntity {
long value;
protected AsmEntity entity;
public ImmediateValue(long n) {
value = n;
this(new IntegerLiteral(n));
}
public long value() {
return value;
public ImmediateValue(Label label) {
this(new Symbol(label));
}
public ImmediateValue(AsmEntity entity) {
this.entity = entity;
}
public AsmEntity entity() {
return this.entity;
}
public String toString() {
return "$" + value;
return "$" + entity.toString();
}
}

View File

@ -0,0 +1,27 @@
package net.loveruby.cflat.asm;
public class IndirectAddress extends Address {
protected long offset;
protected Register base;
public IndirectAddress(Register base) {
this(0, base);
}
public IndirectAddress(long offset, Register base) {
this.offset = offset;
this.base = base;
}
public long offset() {
return offset;
}
public Register base() {
return base;
}
public String toString() {
return (offset == 0 ? "" : "" + offset) + "(" + base.toString() + ")";
}
}

View File

@ -0,0 +1,62 @@
package net.loveruby.cflat.asm;
import net.loveruby.cflat.type.Type;
public class Instruction extends Assembly {
protected String mnemonic;
protected String suffix;
protected AsmEntity[] operands;
public Instruction(String mnemonic) {
this(mnemonic, "", new AsmEntity[0]);
}
public Instruction(String mnemonic, String suffix, AsmEntity a1) {
this(mnemonic, suffix, new AsmEntity[] { a1 });
}
public Instruction(String mnemonic, String suffix,
AsmEntity a1, AsmEntity a2) {
this(mnemonic, suffix, new AsmEntity[] { a1, a2 });
}
public Instruction(String mnemonic, String suffix, AsmEntity[] operands) {
this.mnemonic = mnemonic;
this.suffix = suffix;
this.operands = operands;
}
public boolean isInstruction() {
return true;
}
public String mnemonic() {
return this.mnemonic;
}
public int numOperands() {
return this.operands.length;
}
public AsmEntity operand1() {
return this.operands[0];
}
public AsmEntity operand2() {
return this.operands[1];
}
public String toSource() {
StringBuffer buf = new StringBuffer();
buf.append(mnemonic + suffix);
String sep = "\t";
for (int i = 0; i < operands.length; i++) {
buf.append(sep); sep = ", ";
buf.append(operands[i]);
}
return buf.toString();
}
public String toString() {
return "#<Insn " + mnemonic + ">";
}
}

View File

@ -0,0 +1,17 @@
package net.loveruby.cflat.asm;
public class IntegerLiteral extends Literal {
protected long value;
public IntegerLiteral(long n) {
this.value = n;
}
public long value() {
return this.value;
}
public String toString() {
return new Long(value).toString();
}
}

View File

@ -1,8 +1,8 @@
package net.loveruby.cflat.asm;
public class Label extends AsmEntity {
long seq;
String name;
public class Label extends Assembly {
protected long seq;
protected String name;
public Label(String n) {
seq = -1;
@ -22,6 +22,10 @@ public class Label extends AsmEntity {
return name;
}
public String toSource() {
return name + ":";
}
public String toString() {
return name;
}

View File

@ -0,0 +1,4 @@
package net.loveruby.cflat.asm;
abstract public class Literal extends AsmEntity {
}

View File

@ -1,17 +0,0 @@
package net.loveruby.cflat.asm;
public class Reference extends Address {
protected Label label;
public Reference(String sym) {
this(new Label(sym));
}
public Reference(Label label) {
this.label = label;
}
public String toString() {
return "$" + label.toString();
}
}

View File

@ -1,17 +0,0 @@
package net.loveruby.cflat.asm;
public class SimpleAddress extends Address {
Register base;
public SimpleAddress(Register reg) {
base = reg;
}
public Register base() {
return base;
}
public String toString() {
return "(" + base.toString() + ")";
}
}

View File

@ -0,0 +1,17 @@
package net.loveruby.cflat.asm;
public class Symbol extends Literal {
protected Label label;
public Symbol(Label label) {
this.label = label;
}
public String symbol() {
return label.name();
}
public String toString() {
return symbol();
}
}

View File

@ -26,6 +26,6 @@ abstract public class Function extends Entity {
}
public AsmEntity address() {
return new Reference(name());
return new DirectAddress(new Label(name()));
}
}

View File

@ -20,7 +20,7 @@ public class UndefinedVariable extends Variable {
}
public AsmEntity address() {
return new Label(symbol());
return new DirectAddress(new Label(symbol()));
}
protected void _dump(Dumper d) {

View File

@ -82,13 +82,13 @@ public class CodeGenerator extends Visitor implements ASTLHSVisitor {
/** Linux/IA-32 dependent */
// FIXME: PIC
protected AsmEntity globalVariableAddress(String sym) {
return new Label(csymbol(sym));
return new Symbol(new Label(csymbol(sym)));
}
/** Linux/IA-32 dependent */
// FIXME: PIC
protected AsmEntity commonSymbolAddress(String sym) {
return new Label(csymbol(sym));
return new Symbol(new Label(csymbol(sym)));
}
/** Generates static variable entries */
@ -866,20 +866,20 @@ public class CodeGenerator extends Visitor implements ASTLHSVisitor {
return new Register(name);
}
protected SimpleAddress mem(Register reg) {
return new SimpleAddress(reg);
protected IndirectAddress mem(Register reg) {
return new IndirectAddress(reg);
}
protected CompositeAddress mem(long offset, Register reg) {
return new CompositeAddress(offset, reg);
protected IndirectAddress mem(long offset, Register reg) {
return new IndirectAddress(offset, reg);
}
protected ImmediateValue imm(long n) {
return new ImmediateValue(n);
}
protected Reference imm(Label label) {
return new Reference(label);
protected ImmediateValue imm(Label label) {
return new ImmediateValue(label);
}
protected void load(Type type, AsmEntity addr, Register reg) {
@ -909,7 +909,6 @@ public class CodeGenerator extends Visitor implements ASTLHSVisitor {
}
public void comment(String str) { as.comment(str); }
public void line(String str) { as.line(str); }
public void _file(String name) { as._file(name); }
public void _text() { as._text(); }
public void _data() { as._data(); }