r4984@macbookpro: aamine | 2009-05-26 15:11:36 +0900

* net/loveruby/cflat/compiler/Compiler.java: change CodeGenerator output: String -> AssemblyFile.
 * net/loveruby/cflat/sysdep/AssemblyFile.java: new interface.
 * net/loveruby/cflat/sysdep/x86/AssemblyFile.java: implement it.
 * net/loveruby/cflat/sysdep/CodeGenerator.java: #generate returns AssemblyFile.
 * net/loveruby/cflat/sysdep/x86/CodeGenerator.java: ditto.
 


git-svn-id: file:///Users/aamine/c/gitwork/public/cbc/trunk@4262 1b9489fe-b721-0410-924e-b54b9192deb8
This commit is contained in:
Minero Aoki 2009-05-26 07:52:42 +00:00
parent b38ec78fdc
commit 1729dbaac0
6 changed files with 116 additions and 67 deletions

View File

@ -1,3 +1,17 @@
Tue May 26 15:11:19 2009 Minero Aoki <aamine@loveruby.net>
* net/loveruby/cflat/compiler/Compiler.java: change CodeGenerator
output: String -> AssemblyFile.
* net/loveruby/cflat/sysdep/AssemblyFile.java: new interface.
* net/loveruby/cflat/sysdep/x86/AssemblyFile.java: implement it.
* net/loveruby/cflat/sysdep/CodeGenerator.java: #generate returns
AssemblyFile.
* net/loveruby/cflat/sysdep/x86/CodeGenerator.java: ditto.
Tue May 26 13:40:13 2009 Minero Aoki <aamine@loveruby.net>
* net/loveruby/cflat/sysdep/x86: rename class: RegKind ->

View File

@ -6,6 +6,7 @@ import net.loveruby.cflat.ast.ExprNode;
import net.loveruby.cflat.type.TypeTable;
import net.loveruby.cflat.ir.IR;
import net.loveruby.cflat.sysdep.CodeGenerator;
import net.loveruby.cflat.sysdep.AssemblyFile;
import net.loveruby.cflat.utils.ErrorHandler;
import net.loveruby.cflat.exception.*;
import java.util.*;
@ -113,9 +114,9 @@ public class Compiler {
if (dumpSemant(sem, opts.mode())) return;
IR ir = new IRGenerator(types, errorHandler).generate(sem);
if (dumpIR(ir, opts.mode())) return;
String asm = generateAssembly(ir, opts);
AssemblyFile asm = generateAssembly(ir, opts);
if (dumpAsm(asm, opts.mode())) return;
writeFile(destPath, asm);
writeFile(destPath, asm.toSource());
}
public AST parseFile(String path, Options opts)
@ -138,9 +139,8 @@ public class Compiler {
return ast;
}
public String generateAssembly(IR ir, Options opts) {
CodeGenerator gen = opts.codeGenerator(errorHandler);
return gen.generate(ir);
public AssemblyFile generateAssembly(IR ir, Options opts) {
return opts.codeGenerator(errorHandler).generate(ir);
}
public void assemble(String srcPath, String destPath,
@ -250,9 +250,9 @@ public class Compiler {
}
}
private boolean dumpAsm(String asm, CompilerMode mode) {
private boolean dumpAsm(AssemblyFile asm, CompilerMode mode) {
if (mode == CompilerMode.DumpAsm) {
System.out.print(asm);
System.out.print(asm.toSource());
return true;
}
else {

View File

@ -0,0 +1,8 @@
package net.loveruby.cflat.sysdep;
import java.io.PrintStream;
public interface AssemblyFile {
String toSource();
void dump();
void dump(PrintStream s);
}

View File

@ -1,5 +1,5 @@
package net.loveruby.cflat.sysdep;
public interface CodeGenerator {
String generate(net.loveruby.cflat.ir.IR ir);
AssemblyFile generate(net.loveruby.cflat.ir.IR ir);
}

View File

@ -1,19 +1,23 @@
package net.loveruby.cflat.sysdep.x86;
import net.loveruby.cflat.asm.*;
import net.loveruby.cflat.utils.TextUtils;
import java.util.*;
import java.util.List;
import java.util.ArrayList;
import java.io.PrintStream;
public class AssemblyFile {
private List<Assembly> assemblies;
private Type naturalType;
private long stackWordSize;
private boolean verbose;
public class AssemblyFile implements net.loveruby.cflat.sysdep.AssemblyFile {
private final List<Assembly> assemblies;
private final Type naturalType;
private final long stackWordSize;
private final SymbolTable labelSymbols;
private final boolean verbose;
private int commentIndentLevel;
public AssemblyFile(
Type naturalType, long stackWordSize, boolean verbose) {
public AssemblyFile(Type naturalType, long stackWordSize,
SymbolTable labelSymbols, boolean verbose) {
this.naturalType = naturalType;
this.stackWordSize = stackWordSize;
this.labelSymbols = labelSymbols;
this.verbose = verbose;
this.assemblies = new ArrayList<Assembly>();
this.commentIndentLevel = 0;
@ -28,15 +32,23 @@ public class AssemblyFile {
this.assemblies.addAll(assemblies);
}
public String toSource(SymbolTable symbolTable) {
public String toSource() {
StringBuffer buf = new StringBuffer();
for (Assembly asm : assemblies) {
buf.append(asm.toSource(symbolTable));
buf.append(asm.toSource(labelSymbols));
buf.append("\n");
}
return buf.toString();
}
public void dump() {
dump(System.out);
}
public void dump(PrintStream s) {
// FIXME
}
public void comment(String str) {
assemblies.add(new Comment(str, commentIndentLevel));
}

View File

@ -29,10 +29,21 @@ public class CodeGenerator
/** Compiles IR and generates assembly code. */
// #@@range/generate{
static final private String CONST_SYMBOL_BASE = ".LC";
static final private String LABEL_SYMBOL_BASE = ".L";
public AssemblyFile generate(IR ir) {
locateSymbols(ir);
return compileIR(ir);
}
// #@@}
public String generate(IR ir) {
static final String LABEL_SYMBOL_BASE = ".L";
static final String CONST_SYMBOL_BASE = ".LC";
//
// locateSymbols
//
// #@@range/locateSymbols{
private void locateSymbols(IR ir) {
SymbolTable constSymbols = new SymbolTable(CONST_SYMBOL_BASE);
for (ConstantEntry ent : ir.constantTable().entries()) {
locateConstant(ent, constSymbols);
@ -43,52 +54,6 @@ public class CodeGenerator
for (Function func : ir.allFunctions()) {
locateFunction(func);
}
AssemblyFile file = compileIR(ir);
return file.toSource(new SymbolTable(LABEL_SYMBOL_BASE));
}
// #@@}
// #@@range/newAssemblyFile{
private AssemblyFile newAssemblyFile() {
return new AssemblyFile(
naturalType, STACK_WORD_SIZE, options.isVerboseAsm());
}
// #@@}
// #@@range/compileIR{
private AssemblyFile compileIR(IR ir) {
AssemblyFile file = newAssemblyFile();
file._file(ir.fileName());
// .data
List<DefinedVariable> gvars = ir.definedGlobalVariables();
if (!gvars.isEmpty()) {
file._data();
for (DefinedVariable gvar : gvars) {
dataEntry(file, gvar);
}
}
if (!ir.constantTable().isEmpty()) {
file._section(".rodata");
for (ConstantEntry ent : ir.constantTable()) {
compileStringLiteral(file, ent);
}
}
// .text
if (ir.functionDefined()) {
file._text();
for (DefinedFunction func : ir.definedFunctions()) {
compileFunction(file, func);
}
}
// .bss
for (DefinedVariable var : ir.definedCommonSymbols()) {
compileCommonSymbol(file, var);
}
// others
if (options.isPositionIndependent()) {
PICThunk(file, GOTBaseReg());
}
return file;
}
// #@@}
@ -175,6 +140,56 @@ public class CodeGenerator
}
// #@@}
//
// compileIR
//
// #@@range/compileIR{
private AssemblyFile compileIR(IR ir) {
AssemblyFile file = newAssemblyFile();
file._file(ir.fileName());
// .data
List<DefinedVariable> gvars = ir.definedGlobalVariables();
if (!gvars.isEmpty()) {
file._data();
for (DefinedVariable gvar : gvars) {
dataEntry(file, gvar);
}
}
if (!ir.constantTable().isEmpty()) {
file._section(".rodata");
for (ConstantEntry ent : ir.constantTable()) {
compileStringLiteral(file, ent);
}
}
// .text
if (ir.functionDefined()) {
file._text();
for (DefinedFunction func : ir.definedFunctions()) {
compileFunction(file, func);
}
}
// .bss
for (DefinedVariable var : ir.definedCommonSymbols()) {
compileCommonSymbol(file, var);
}
// others
if (options.isPositionIndependent()) {
PICThunk(file, GOTBaseReg());
}
return file;
}
// #@@}
// #@@range/newAssemblyFile{
private AssemblyFile newAssemblyFile() {
return new AssemblyFile(
naturalType, STACK_WORD_SIZE,
new SymbolTable(LABEL_SYMBOL_BASE),
options.isVerboseAsm());
}
// #@@}
/** Generates initialized entries */
// #@@range/dataEntry{
private void dataEntry(AssemblyFile file, DefinedVariable ent) {