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>
|
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
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue