mirror of https://github.com/aamine/cbc
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:
parent
6fef2ad6f7
commit
0837912b64
19
ChangeLog
19
ChangeLog
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue