* net/loveruby/cflat/compiler/CodeGenerator.java: should access file-local gvar directly (with @GOTOFF) in PIE.

* net/loveruby/cflat/ast/Entity.java: all entities should have memref or address.
* net/loveruby/cflat/ast/Variable.java: ditto.
* net/loveruby/cflat/ast/DefinedVariable.java: ditto.
* net/loveruby/cflat/ast/UndefinedVariable.java: ditto.
* net/loveruby/cflat/ast/Function.java: ditto.
* net/loveruby/cflat/ast/DefinedFunction.java: ditto.
* import/stdlib.hb: add new declarations.
* import/unistd.hb: add new declarations.


git-svn-id: file:///Users/aamine/c/gitwork/public/cbc/trunk@4082 1b9489fe-b721-0410-924e-b54b9192deb8
This commit is contained in:
Minero Aoki 2008-11-16 11:01:10 +00:00
parent 6b24625a87
commit aa030b42b7
11 changed files with 102 additions and 118 deletions

View File

@ -1,3 +1,25 @@
Sun Nov 16 20:01:06 2008 Minero Aoki <aamine@loveruby.net>
* net/loveruby/cflat/compiler/CodeGenerator.java: should access
file-local gvar directly (with @GOTOFF) in PIE.
* net/loveruby/cflat/ast/Entity.java: all entities should have
memref or address.
* net/loveruby/cflat/ast/Variable.java: ditto.
* net/loveruby/cflat/ast/DefinedVariable.java: ditto.
* net/loveruby/cflat/ast/UndefinedVariable.java: ditto.
* net/loveruby/cflat/ast/Function.java: ditto.
* net/loveruby/cflat/ast/DefinedFunction.java: ditto.
* import/stdlib.hb: add new declarations.
* import/unistd.hb: add new declarations.
Sun Nov 2 18:27:01 2008 Minero Aoki <aamine@loveruby.net>
* net/loveruby/cflat/compiler/Options.java: new option

2
ToDo
View File

@ -6,9 +6,9 @@
* "extern char*[] sys_errlist" is array, not pointer
* &puts should be typed as int(*)(char*)*, not int(*)(char*)**
* check opassign semantic as operator
* use enum for compiler mode.
* -fPIE, -pie
* implement difference against PIC
* remove all FIXME
== Done

View File

@ -1 +1,9 @@
// stdlib.hb
import stddef; // for size_t
extern void exit(int status);
extern void* calloc(size_t nmemb, size_t size);
extern void* malloc(size_t size);
extern void free(void* ptr);
extern void* realloc(void* ptr, size_t size);

View File

@ -6,3 +6,4 @@ extern void _exit(int status);
extern pid_t fork(void);
extern pid_t getpid(void);
extern pid_t getppid(void);
extern unsigned int sleep(unsigned int secs);

View File

@ -1,8 +1,6 @@
package net.loveruby.cflat.ast;
import net.loveruby.cflat.compiler.ErrorHandler;
import net.loveruby.cflat.type.*;
import net.loveruby.cflat.asm.Symbol;
import net.loveruby.cflat.asm.BaseSymbol;
import net.loveruby.cflat.asm.Label;
import net.loveruby.cflat.exception.*;
import java.util.*;

View File

@ -23,16 +23,6 @@ public class DefinedVariable extends Variable {
this.sequence = seq;
}
public Symbol symbol() {
if (symbol != null) {
return symbol;
}
else {
symbol = new NamedSymbol(symbolString());
return symbol;
}
}
public String symbolString() {
return (sequence < 0) ? name : (name + "." + sequence);
}

View File

@ -1,7 +1,6 @@
package net.loveruby.cflat.ast;
import net.loveruby.cflat.type.*;
import net.loveruby.cflat.asm.Symbol;
import net.loveruby.cflat.asm.NamedSymbol;
import net.loveruby.cflat.asm.AsmOperand;
import net.loveruby.cflat.asm.MemoryReference;
@ -10,6 +9,8 @@ abstract public class Entity extends Node {
protected boolean isPrivate;
protected TypeNode typeNode;
protected long nRefered;
protected MemoryReference memref;
protected MemoryReference address;
public Entity(boolean priv, TypeNode type, String name) {
this.name = name;
@ -22,8 +23,8 @@ abstract public class Entity extends Node {
return name;
}
public Symbol symbol() {
return new NamedSymbol(name);
public String symbolString() {
return name();
}
abstract public boolean isDefined();
@ -61,8 +62,29 @@ abstract public class Entity extends Node {
abstract public boolean cannotLoad();
abstract public MemoryReference memref();
abstract public AsmOperand address();
public void setMemref(MemoryReference mem) {
this.memref = mem;
}
public MemoryReference memref() {
checkAddress();
return memref;
}
public void setAddress(MemoryReference mem) {
this.address = mem;
}
public AsmOperand address() {
checkAddress();
return address;
}
protected void checkAddress() {
if (memref == null && address == null) {
throw new Error("address did not resolved: " + name);
}
}
public Location location() {
return typeNode.location();

View File

@ -1,16 +1,12 @@
package net.loveruby.cflat.ast;
import net.loveruby.cflat.type.*;
import net.loveruby.cflat.asm.Label;
import net.loveruby.cflat.asm.Symbol;
import net.loveruby.cflat.asm.NamedSymbol;
import net.loveruby.cflat.asm.AsmOperand;
import net.loveruby.cflat.asm.MemoryReference;
import net.loveruby.cflat.asm.Label;
import java.util.*;
abstract public class Function extends Entity {
protected Symbol symbol;
protected Symbol callingSymbol;
protected Label label;
protected AsmOperand address;
public Function(boolean priv, TypeNode t, String name) {
super(priv, t, name);
@ -37,18 +33,18 @@ abstract public class Function extends Entity {
return true;
}
public void setSymbol(Symbol sym) {
if (this.symbol != null) {
throw new Error("must not happen: Function#symbol was set again");
public void setCallingSymbol(Symbol sym) {
if (this.callingSymbol != null) {
throw new Error("must not happen: Function#callingSymbol was set again");
}
this.symbol = sym;
this.callingSymbol = sym;
}
public Symbol symbol() {
if (this.symbol == null) {
throw new Error("must not happen: Function#symbol called but null");
public Symbol callingSymbol() {
if (this.callingSymbol == null) {
throw new Error("must not happen: Function#callingSymbol called but null");
}
return this.symbol;
return this.callingSymbol;
}
public Label label() {
@ -56,22 +52,7 @@ abstract public class Function extends Entity {
return label;
}
else {
return label = new Label(symbol());
return label = new Label(callingSymbol());
}
}
public MemoryReference memref() {
return null;
}
public void setAddress(AsmOperand addr) {
this.address = addr;
}
public AsmOperand address() {
if (address == null) {
throw new Error("must not happen: Function.address == null");
}
return this.address;
}
}

View File

@ -10,10 +10,6 @@ public class UndefinedVariable extends Variable {
public boolean isPrivate() { return false; }
public boolean isInitialized() { return false; }
public String symbolString() {
return name();
}
protected void _dump(Dumper d) {
d.printMember("name", name);
d.printMember("isPrivate", isPrivate());

View File

@ -1,43 +1,12 @@
package net.loveruby.cflat.ast;
import net.loveruby.cflat.type.*;
import net.loveruby.cflat.asm.AsmOperand;
import net.loveruby.cflat.asm.MemoryReference;
abstract public class Variable extends Entity {
protected MemoryReference memref;
protected MemoryReference address;
public Variable(boolean priv, TypeNode type, String name) {
super(priv, type, name);
}
abstract public String symbolString();
public boolean cannotLoad() {
return type().isAllocatedArray();
}
public void setMemref(MemoryReference mem) {
this.memref = mem;
}
public MemoryReference memref() {
checkAddress();
return memref;
}
public void setAddress(MemoryReference mem) {
this.address = mem;
}
public AsmOperand address() {
checkAddress();
return address;
}
protected void checkAddress() {
if (memref == null && address == null) {
throw new Error("address did not resolved: " + name);
}
}
}

View File

@ -81,7 +81,7 @@ public class CodeGenerator
compileCommonSymbol(var);
}
// others
if (options.isPICRequired()) {
if (options.isPositionIndependent()) {
PICThunk(GOTBaseReg());
}
}
@ -89,7 +89,7 @@ public class CodeGenerator
protected void locateConstant(ConstantEntry ent, SymbolTable symbols) {
ent.setSymbol(symbols.newSymbol());
if (options.isPICRequired()) {
if (options.isPositionIndependent()) {
Symbol offset = localGOTSymbol(ent.symbol());
ent.setMemref(mem(offset, GOTBaseReg()));
}
@ -99,52 +99,49 @@ public class CodeGenerator
}
}
protected void locateGlobalVariable(Variable var) {
MemoryReference mem;
if (options.isPICRequired()) {
if (var.isPrivate()) {
mem = mem(localGOTSymbol(var.symbol()), GOTBaseReg());
var.setMemref(mem);
protected void locateGlobalVariable(Entity ent) {
Symbol sym = ent.isPrivate() ? privateSymbol(ent.symbolString())
: globalSymbol(ent.symbolString());
if (options.isPositionIndependent()) {
MemoryReference mem;
if (ent.isPrivate() || optimizeGvarAccess(ent)) {
mem = mem(localGOTSymbol(sym), GOTBaseReg());
ent.setMemref(mem);
}
else {
mem = mem(globalGOTSymbol(var.symbol()), GOTBaseReg());
var.setAddress(mem);
mem = mem(globalGOTSymbol(sym), GOTBaseReg());
ent.setAddress(mem);
}
}
else {
mem = mem(globalSymbol(var.symbolString()));
var.setMemref(mem);
ent.setMemref(mem(sym));
}
}
protected void locateFunction(Function func) {
func.setSymbol(functionSymbol(func));
func.setAddress(functionAddress(func));
func.setCallingSymbol(callingSymbol(func));
locateGlobalVariable(func);
}
protected Symbol functionSymbol(Function func) {
if (func.isDefined()) {
return globalSymbol(func.name());
protected Symbol callingSymbol(Function func) {
if (func.isPrivate()) {
return privateSymbol(func.symbolString());
}
else {
Symbol sym = privateSymbol(func.name());
return options.isPICRequired() ? PLTSymbol(sym) : sym;
Symbol sym = globalSymbol(func.symbolString());
return doesIndirectAccess(func) ? PLTSymbol(sym) : sym;
}
}
protected AsmOperand functionAddress(Function func) {
Symbol sym = new NamedSymbol(func.name());
if (options.isPICRequired()) {
if (func.isPrivate()) {
return mem(localGOTSymbol(sym), GOTBaseReg());
}
else {
return mem(globalGOTSymbol(sym), GOTBaseReg());
}
}
else {
return imm(sym);
}
// condition to use indirect access (using PLT to call, GOT to refer).
// In PIC, we do use indirect access for all global variables.
// In PIE, we do use direct access for file-local reference.
protected boolean doesIndirectAccess(Entity ent) {
return options.isPositionIndependent() && !optimizeGvarAccess(ent);
}
protected boolean optimizeGvarAccess(Entity ent) {
return options.isPIERequired() && ent.isDefined();
}
/** Generates initialized entries */
@ -225,7 +222,7 @@ public class CodeGenerator
// #@@}
//
// PIC related constants and codes
// PIC/PIE related constants and codes
//
static protected final Symbol GOT = new NamedSymbol("_GLOBAL_OFFSET_TABLE_");
@ -314,7 +311,7 @@ public class CodeGenerator
long lvarBytes = allocateLocalVariables(func.body().scope(),
saveRegs.size());
prologue(func, saveRegs, lvarBytes);
if (options.isPICRequired() && stats.doesRegisterUsed(GOTBaseReg())) {
if (options.isPositionIndependent() && stats.doesRegisterUsed(GOTBaseReg())) {
loadGOTBaseAddress(GOTBaseReg());
}
as.addAll(bodyAsms);
@ -551,7 +548,7 @@ public class CodeGenerator
// call
if (node.isStaticCall()) {
// call via function name
call(node.function().symbol());
call(node.function().callingSymbol());
}
else {
// call via pointer