mirror of https://github.com/aamine/cbc
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:
parent
b38ec78fdc
commit
1729dbaac0
14
ChangeLog
14
ChangeLog
|
@ -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 ->
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
package net.loveruby.cflat.sysdep;
|
||||
import java.io.PrintStream;
|
||||
|
||||
public interface AssemblyFile {
|
||||
String toSource();
|
||||
void dump();
|
||||
void dump(PrintStream s);
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue