r5103@macbookpro: aamine | 2009-06-13 22:37:55 +0900

* net/loveruby/cflat/entity/ToplevelScope.java: move #definedGlobalVariables and #definedCommonSymbols to IR.
 * net/loveruby/cflat/ir/IR.java: ditto.
 * net/loveruby/cflat/ir/IR.java: new method #isGlobalVariableDefined.
 * net/loveruby/cflat/ir/IR.java: new method #isCommonSymbolDefined.
 * net/loveruby/cflat/ir/IR.java: new method #isStringLiteralDefined.
 * net/loveruby/cflat/sysdep/x86/CodeGenerator.java: use these methods.
 


git-svn-id: file:///Users/aamine/c/gitwork/public/cbc/trunk@4291 1b9489fe-b721-0410-924e-b54b9192deb8
This commit is contained in:
Minero Aoki 2009-06-13 13:46:35 +00:00
parent 6fef2ad6f7
commit 0837912b64
4 changed files with 129 additions and 105 deletions

View File

@ -1,3 +1,22 @@
Sat Jun 13 22:37:02 2009 Minero Aoki <aamine@loveruby.net>
* net/loveruby/cflat/entity/ToplevelScope.java: move
#definedGlobalVariables and #definedCommonSymbols to IR.
* net/loveruby/cflat/ir/IR.java: ditto.
* net/loveruby/cflat/ir/IR.java: new method
#isGlobalVariableDefined.
* net/loveruby/cflat/ir/IR.java: new method
#isCommonSymbolDefined.
* net/loveruby/cflat/ir/IR.java: new method
#isStringLiteralDefined.
* net/loveruby/cflat/sysdep/x86/CodeGenerator.java: use these
methods.
Sat Jun 13 17:41:13 2009 Minero Aoki <aamine@loveruby.net> Sat Jun 13 17:41:13 2009 Minero Aoki <aamine@loveruby.net>
* net/loveruby/cflat/utils/CommandUtils.java: better error * net/loveruby/cflat/utils/CommandUtils.java: better error

View File

@ -81,33 +81,7 @@ public class ToplevelScope extends Scope {
return result; return result;
} }
/** Returns the list of global variables. public List<DefinedVariable> definedGlobalScopeVariables() {
* A global variable is a variable which has
* global scope and is initialized. */
public List<DefinedVariable> definedGlobalVariables() {
List<DefinedVariable> result = new ArrayList<DefinedVariable>();
for (DefinedVariable var : definedGlobalScopeVariables()) {
if (var.hasInitializer()) {
result.add(var);
}
}
return result;
}
/** Returns the list of common symbols.
* A common symbol is a variable which has
* global scope and is not initialized. */
public List<DefinedVariable> definedCommonSymbols() {
List<DefinedVariable> result = new ArrayList<DefinedVariable>();
for (DefinedVariable var : definedGlobalScopeVariables()) {
if (!var.hasInitializer()) {
result.add(var);
}
}
return result;
}
protected List<DefinedVariable> definedGlobalScopeVariables() {
List<DefinedVariable> result = new ArrayList<DefinedVariable>(); List<DefinedVariable> result = new ArrayList<DefinedVariable>();
for (Entity ent : entities.values()) { for (Entity ent : entities.values()) {
if (ent instanceof DefinedVariable) { if (ent instanceof DefinedVariable) {
@ -118,7 +92,7 @@ public class ToplevelScope extends Scope {
return result; return result;
} }
protected List<DefinedVariable> staticLocalVariables() { public List<DefinedVariable> staticLocalVariables() {
if (staticLocalVariables == null) { if (staticLocalVariables == null) {
staticLocalVariables = new ArrayList<DefinedVariable>(); staticLocalVariables = new ArrayList<DefinedVariable>();
for (LocalScope s : children) { for (LocalScope s : children) {

View File

@ -6,12 +6,14 @@ import java.io.PrintStream;
import java.util.*; import java.util.*;
public class IR { public class IR {
protected Location source; Location source;
protected List<DefinedVariable> defvars; List<DefinedVariable> defvars;
protected List<DefinedFunction> defuns; List<DefinedFunction> defuns;
protected List<UndefinedFunction> funcdecls; List<UndefinedFunction> funcdecls;
protected ToplevelScope scope; ToplevelScope scope;
protected ConstantTable constantTable; ConstantTable constantTable;
List<DefinedVariable> gvars; // cache
List<DefinedVariable> comms; // cache
public IR(Location source, public IR(Location source,
List<DefinedVariable> defvars, List<DefinedVariable> defvars,
@ -40,7 +42,7 @@ public class IR {
return defvars; return defvars;
} }
public boolean functionDefined() { public boolean isFunctionDefined() {
return !defuns.isEmpty(); return !defuns.isEmpty();
} }
@ -64,14 +66,44 @@ public class IR {
return scope.allGlobalVariables(); return scope.allGlobalVariables();
} }
/** a list of defined initialized global variables */ public boolean isGlobalVariableDefined() {
public List<DefinedVariable> definedGlobalVariables() { return ! definedGlobalVariables().isEmpty();
return scope.definedGlobalVariables();
} }
/** a list of defined uninitialized global variables */ /** Returns the list of global variables.
* A global variable is a variable which has
* global scope and is initialized. */
public List<DefinedVariable> definedGlobalVariables() {
if (gvars == null) {
initVariables();
}
return gvars;
}
public boolean isCommonSymbolDefined() {
return ! definedCommonSymbols().isEmpty();
}
/** Returns the list of common symbols.
* A common symbol is a variable which has
* global scope and is not initialized. */
public List<DefinedVariable> definedCommonSymbols() { public List<DefinedVariable> definedCommonSymbols() {
return scope.definedCommonSymbols(); if (comms == null) {
initVariables();
}
return comms;
}
private void initVariables() {
gvars = new ArrayList<DefinedVariable>();
comms = new ArrayList<DefinedVariable>();
for (DefinedVariable var : scope.definedGlobalScopeVariables()) {
(var.hasInitializer() ? gvars : comms).add(var);
}
}
public boolean isStringLiteralDefined() {
return ! constantTable.isEmpty();
} }
public ConstantTable constantTable() { public ConstantTable constantTable() {

View File

@ -28,7 +28,7 @@ public class CodeGenerator implements net.loveruby.cflat.sysdep.CodeGenerator,
// #@@range/generate{ // #@@range/generate{
public AssemblyFile generate(IR ir) { public AssemblyFile generate(IR ir) {
locateSymbols(ir); locateSymbols(ir);
return compileIR(ir); return generateAssemblyCode(ir);
} }
// #@@} // #@@}
@ -138,39 +138,25 @@ public class CodeGenerator implements net.loveruby.cflat.sysdep.CodeGenerator,
// #@@} // #@@}
// //
// compileIR // generateAssemblyCode
// //
// #@@range/compileIR{ // #@@range/generateAssemblyCode{
private AssemblyFile compileIR(IR ir) { private AssemblyFile generateAssemblyCode(IR ir) {
AssemblyFile file = newAssemblyFile(); AssemblyFile file = newAssemblyFile();
file._file(ir.fileName()); file._file(ir.fileName());
// .data if (ir.isGlobalVariableDefined()) {
List<DefinedVariable> gvars = ir.definedGlobalVariables(); generateDataSection(file, ir.definedGlobalVariables());
if (!gvars.isEmpty()) {
file._data();
for (DefinedVariable gvar : gvars) {
compileGlobalVariable(file, gvar);
}
} }
if (!ir.constantTable().isEmpty()) { if (ir.isStringLiteralDefined()) {
file._section(".rodata"); generateReadOnlyDataSection(file, ir.constantTable());
for (ConstantEntry ent : ir.constantTable()) {
compileStringLiteral(file, ent);
}
} }
// .text if (ir.isFunctionDefined()) {
if (ir.functionDefined()) { generateTextSection(file, ir.definedFunctions());
file._text();
for (DefinedFunction func : ir.definedFunctions()) {
compileFunction(file, func);
}
} }
// .bss if (ir.isCommonSymbolDefined()) {
for (DefinedVariable var : ir.definedCommonSymbols()) { generateCommonSymbols(file, ir.definedCommonSymbols());
compileCommonSymbol(file, var);
} }
// others
if (options.isPositionIndependent()) { if (options.isPositionIndependent()) {
PICThunk(file, GOTBaseReg()); PICThunk(file, GOTBaseReg());
} }
@ -188,24 +174,27 @@ public class CodeGenerator implements net.loveruby.cflat.sysdep.CodeGenerator,
// #@@} // #@@}
/** Generates initialized entries */ /** Generates initialized entries */
// #@@range/compileGlobalVariable{ // #@@range/generateDataSection{
private void compileGlobalVariable( private void generateDataSection(AssemblyFile file,
AssemblyFile file, DefinedVariable ent) { List<DefinedVariable> gvars) {
Symbol sym = globalSymbol(ent.symbolString()); file._data();
if (!ent.isPrivate()) { for (DefinedVariable var : gvars) {
file._globl(sym); Symbol sym = globalSymbol(var.symbolString());
if (!var.isPrivate()) {
file._globl(sym);
}
file._align(var.alignment());
file._type(sym, "@object");
file._size(sym, var.allocSize());
file.label(sym);
generateImmediate(file, var.type().allocSize(), var.ir());
} }
file._align(ent.alignment());
file._type(sym, "@object");
file._size(sym, ent.allocSize());
file.label(sym);
compileImmediate(file, ent.type().allocSize(), ent.ir());
} }
// #@@} // #@@}
/** Generates immediate values for .data section */ /** Generates immediate values for .data section */
// #@@range/compileImmediates{ // #@@range/generateImmediate{
private void compileImmediate(AssemblyFile file, long size, Expr node) { private void generateImmediate(AssemblyFile file, long size, Expr node) {
if (node instanceof Int) { if (node instanceof Int) {
Int expr = (Int)node; Int expr = (Int)node;
switch ((int)size) { switch ((int)size) {
@ -232,22 +221,46 @@ public class CodeGenerator implements net.loveruby.cflat.sysdep.CodeGenerator,
} }
// #@@} // #@@}
/** Generates BSS entries */ /** Generates .rodata entries (constant strings) */
// #@@range/compileCommonSymbol{ // #@@range/generateReadOnlyDataSection{
private void compileCommonSymbol(AssemblyFile file, DefinedVariable var) { private void generateReadOnlyDataSection(AssemblyFile file,
Symbol sym = globalSymbol(var.symbolString()); ConstantTable constants) {
if (var.isPrivate()) { file._section(".rodata");
file._local(sym); for (ConstantEntry ent : constants) {
file.label(ent.symbol());
file._string(ent.value());
} }
file._comm(sym, var.allocSize(), var.alignment());
} }
// #@@} // #@@}
/** Generates .rodata entry (constant strings) */ // #@@range/generateTextSection{
// #@@range/compileStringLiteral{ private void generateTextSection(AssemblyFile file,
private void compileStringLiteral(AssemblyFile file, ConstantEntry ent) { List<DefinedFunction> functions) {
file.label(ent.symbol()); file._text();
file._string(ent.value()); for (DefinedFunction func : functions) {
Symbol sym = globalSymbol(func.name());
if (! func.isPrivate()) {
file._globl(sym);
}
file._type(sym, "@function");
file.label(sym);
compileFunctionBody(file, func);
file._size(sym, ".-" + sym.toSource());
}
}
// #@@}
/** Generates BSS entries */
// #@@range/generateCommonSymbols{
private void generateCommonSymbols(AssemblyFile file,
List<DefinedVariable> variables) {
for (DefinedVariable var : variables) {
Symbol sym = globalSymbol(var.symbolString());
if (var.isPrivate()) {
file._local(sym);
}
file._comm(sym, var.allocSize(), var.alignment());
}
} }
// #@@} // #@@}
@ -379,20 +392,6 @@ public class CodeGenerator implements net.loveruby.cflat.sysdep.CodeGenerator,
} }
// #@@} // #@@}
/** Compiles a function. */
// #@@range/compileFunction{
private void compileFunction(AssemblyFile file, DefinedFunction func) {
Symbol sym = globalSymbol(func.name());
if (! func.isPrivate()) {
file._globl(sym);
}
file._type(sym, "@function");
file.label(sym);
compileFunctionBody(file, func);
file._size(sym, ".-" + sym.toSource());
}
// #@@}
// #@@range/StackFrameInfo{ // #@@range/StackFrameInfo{
class StackFrameInfo { class StackFrameInfo {
List<Register> saveRegs; List<Register> saveRegs;