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>
* net/loveruby/cflat/utils/CommandUtils.java: better error

View File

@ -81,33 +81,7 @@ public class ToplevelScope extends Scope {
return result;
}
/** Returns the list of global variables.
* 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() {
public List<DefinedVariable> definedGlobalScopeVariables() {
List<DefinedVariable> result = new ArrayList<DefinedVariable>();
for (Entity ent : entities.values()) {
if (ent instanceof DefinedVariable) {
@ -118,7 +92,7 @@ public class ToplevelScope extends Scope {
return result;
}
protected List<DefinedVariable> staticLocalVariables() {
public List<DefinedVariable> staticLocalVariables() {
if (staticLocalVariables == null) {
staticLocalVariables = new ArrayList<DefinedVariable>();
for (LocalScope s : children) {

View File

@ -6,12 +6,14 @@ import java.io.PrintStream;
import java.util.*;
public class IR {
protected Location source;
protected List<DefinedVariable> defvars;
protected List<DefinedFunction> defuns;
protected List<UndefinedFunction> funcdecls;
protected ToplevelScope scope;
protected ConstantTable constantTable;
Location source;
List<DefinedVariable> defvars;
List<DefinedFunction> defuns;
List<UndefinedFunction> funcdecls;
ToplevelScope scope;
ConstantTable constantTable;
List<DefinedVariable> gvars; // cache
List<DefinedVariable> comms; // cache
public IR(Location source,
List<DefinedVariable> defvars,
@ -40,7 +42,7 @@ public class IR {
return defvars;
}
public boolean functionDefined() {
public boolean isFunctionDefined() {
return !defuns.isEmpty();
}
@ -64,14 +66,44 @@ public class IR {
return scope.allGlobalVariables();
}
/** a list of defined initialized global variables */
public List<DefinedVariable> definedGlobalVariables() {
return scope.definedGlobalVariables();
public boolean isGlobalVariableDefined() {
return ! definedGlobalVariables().isEmpty();
}
/** 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() {
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() {

View File

@ -28,7 +28,7 @@ public class CodeGenerator implements net.loveruby.cflat.sysdep.CodeGenerator,
// #@@range/generate{
public AssemblyFile generate(IR 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{
private AssemblyFile compileIR(IR ir) {
// #@@range/generateAssemblyCode{
private AssemblyFile generateAssemblyCode(IR ir) {
AssemblyFile file = newAssemblyFile();
file._file(ir.fileName());
// .data
List<DefinedVariable> gvars = ir.definedGlobalVariables();
if (!gvars.isEmpty()) {
file._data();
for (DefinedVariable gvar : gvars) {
compileGlobalVariable(file, gvar);
}
if (ir.isGlobalVariableDefined()) {
generateDataSection(file, ir.definedGlobalVariables());
}
if (!ir.constantTable().isEmpty()) {
file._section(".rodata");
for (ConstantEntry ent : ir.constantTable()) {
compileStringLiteral(file, ent);
}
if (ir.isStringLiteralDefined()) {
generateReadOnlyDataSection(file, ir.constantTable());
}
// .text
if (ir.functionDefined()) {
file._text();
for (DefinedFunction func : ir.definedFunctions()) {
compileFunction(file, func);
}
if (ir.isFunctionDefined()) {
generateTextSection(file, ir.definedFunctions());
}
// .bss
for (DefinedVariable var : ir.definedCommonSymbols()) {
compileCommonSymbol(file, var);
if (ir.isCommonSymbolDefined()) {
generateCommonSymbols(file, ir.definedCommonSymbols());
}
// others
if (options.isPositionIndependent()) {
PICThunk(file, GOTBaseReg());
}
@ -188,24 +174,27 @@ public class CodeGenerator implements net.loveruby.cflat.sysdep.CodeGenerator,
// #@@}
/** Generates initialized entries */
// #@@range/compileGlobalVariable{
private void compileGlobalVariable(
AssemblyFile file, DefinedVariable ent) {
Symbol sym = globalSymbol(ent.symbolString());
if (!ent.isPrivate()) {
file._globl(sym);
// #@@range/generateDataSection{
private void generateDataSection(AssemblyFile file,
List<DefinedVariable> gvars) {
file._data();
for (DefinedVariable var : gvars) {
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 */
// #@@range/compileImmediates{
private void compileImmediate(AssemblyFile file, long size, Expr node) {
// #@@range/generateImmediate{
private void generateImmediate(AssemblyFile file, long size, Expr node) {
if (node instanceof Int) {
Int expr = (Int)node;
switch ((int)size) {
@ -232,22 +221,46 @@ public class CodeGenerator implements net.loveruby.cflat.sysdep.CodeGenerator,
}
// #@@}
/** Generates BSS entries */
// #@@range/compileCommonSymbol{
private void compileCommonSymbol(AssemblyFile file, DefinedVariable var) {
Symbol sym = globalSymbol(var.symbolString());
if (var.isPrivate()) {
file._local(sym);
/** Generates .rodata entries (constant strings) */
// #@@range/generateReadOnlyDataSection{
private void generateReadOnlyDataSection(AssemblyFile file,
ConstantTable constants) {
file._section(".rodata");
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/compileStringLiteral{
private void compileStringLiteral(AssemblyFile file, ConstantEntry ent) {
file.label(ent.symbol());
file._string(ent.value());
// #@@range/generateTextSection{
private void generateTextSection(AssemblyFile file,
List<DefinedFunction> functions) {
file._text();
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{
class StackFrameInfo {
List<Register> saveRegs;