import org.ibex.nestedvm.util.*;
+// FEATURE: -d option for classfilecompiler (just like javac's -d)
+
public abstract class Compiler implements Registers {
/** The ELF binary being read */
protected ELF elf;
protected boolean assumeTailCalls = true;
- protected boolean optimizedMemcpy = true;
-
// True to insert some code in the output to help diagnore compiler problems
protected boolean debugCompiler = false;
protected boolean onePage;
protected void pageSizeInit() throws Exn {
- try {
- Runtime.checkPageSize(pageSize,totalPages);
- } catch(IllegalArgumentException e) {
- throw new Exn(e.getMessage());
- }
+ if((pageSize&(pageSize-1)) != 0) throw new Exn("pageSize not a multiple of two");
+ if((totalPages&(totalPages-1)) != 0) throw new Exn("totalPages not a multiple of two");
while(pageSize>>>pageShift != 1) pageShift++;
}
- /** The address of the memcpy function in the binary (used for optimizedMemcpy) */
- protected int memcpy;
-
- /** The address of the memset function in the binary (used for optimizedMemcpy) */
- protected int memset;
-
/** A set of all addresses that can be jumped too (only available if pruneCases == true) */
- protected Set jumpableAddresses;
+ protected Hashtable jumpableAddresses;
/** Some important symbols */
ELF.Symbol userInfo, gp;
if(symtab == null) throw new Exn("Binary has no symtab (did you strip it?)");
ELF.Symbol sym;
- // Check for some functions we can override
- sym = symtab.getGlobalSymbol("memcpy");
- memcpy = sym == null ? -1 : sym.addr;
-
- sym = symtab.getGlobalSymbol("memset");
- memset = sym == null ? -1 : sym.addr;
-
userInfo = symtab.getGlobalSymbol("user_info");
gp = symtab.getGlobalSymbol("_gp");
if(gp == null) throw new Exn("no _gp symbol (did you strip the binary?)");
if(pruneCases) {
// Find all possible branches
- jumpableAddresses = new HashSet();
+ jumpableAddresses = new Hashtable();
- jumpableAddresses.add(new Integer(elf.header.entry));
+ jumpableAddresses.put(new Integer(elf.header.entry),Boolean.TRUE);
ELF.SHeader text = elf.sectionWithName(".text");
if(text == null) throw new Exn("No .text segment");
_go();
}
- private void findBranchesInSymtab(ELF.Symtab symtab, Set jumps) {
+ private void findBranchesInSymtab(ELF.Symtab symtab, Hashtable jumps) {
ELF.Symbol[] symbols = symtab.symbols;
int n=0;
for(int i=0;i<symbols.length;i++) {
ELF.Symbol s = symbols[i];
if(s.type == ELF.Symbol.STT_FUNC) {
- if(jumps.add(new Integer(s.addr))) {
+ if(jumps.put(new Integer(s.addr),Boolean.TRUE) == null) {
//System.err.println("Adding symbol from symtab: " + s.name + " at " + toHex(s.addr));
n++;
}
if(printStats) System.err.println("Found " + n + " additional possible branch targets in Symtab");
}
- private void findBranchesInText(int base, DataInputStream dis, int size, Set jumps) throws IOException {
+ private void findBranchesInText(int base, DataInputStream dis, int size, Hashtable jumps) throws IOException {
int count = size/4;
int pc = base;
int n=0;
case 0:
switch(subcode) {
case 9: // JALR
- if(jumps.add(new Integer(pc+8))) n++; // return address
+ if(jumps.put(new Integer(pc+8),Boolean.TRUE) == null) n++; // return address
break;
case 12: // SYSCALL
- if(jumps.add(new Integer(pc+4))) n++;
+ if(jumps.put(new Integer(pc+4),Boolean.TRUE) == null) n++;
break;
}
break;
switch(rt) {
case 16: // BLTZAL
case 17: // BGTZAL
- if(jumps.add(new Integer(pc+8))) n++; // return address
+ if(jumps.put(new Integer(pc+8),Boolean.TRUE) == null) n++; // return address
// fall through
case 0: // BLTZ
case 1: // BGEZ
- if(jumps.add(new Integer(pc+branchTarget*4+4))) n++;
+ if(jumps.put(new Integer(pc+branchTarget*4+4),Boolean.TRUE) == null) n++;
break;
}
break;
case 3: // JAL
- if(jumps.add(new Integer(pc+8))) n++; // return address
+ if(jumps.put(new Integer(pc+8),Boolean.TRUE) == null) n++; // return address
// fall through
case 2: // J
- if(jumps.add(new Integer((pc&0xf0000000)|(jumpTarget << 2)))) n++;
+ if(jumps.put(new Integer((pc&0xf0000000)|(jumpTarget << 2)),Boolean.TRUE) == null) n++;
break;
case 4: // BEQ
case 5: // BNE
case 6: // BLEZ
case 7: // BGTZ
- if(jumps.add(new Integer(pc+branchTarget*4+4))) n++;
+ if(jumps.put(new Integer(pc+branchTarget*4+4),Boolean.TRUE) == null) n++;
break;
case 9: { // ADDIU
if(pc - lui_pc[rs] <= 4*32) {
int t = (lui_val[rs]<<16)+signedImmediate;
if((t&3)==0 && t >= base && t < base+size) {
- if(jumps.add(new Integer(t))) {
+ if(jumps.put(new Integer(t),Boolean.TRUE) == null) {
//System.err.println("Possible jump to " + toHex(t) + " (" + inter.sourceLine(t) + ") from " + toHex(pc) + " (" + inter.sourceLine(pc) + ")");
n++;
}
case 17: // FPU Instructions
switch(rs) {
case 8: // BC1F, BC1T
- if(jumps.add(new Integer(pc+branchTarget*4+4))) n++;
+ if(jumps.put(new Integer(pc+branchTarget*4+4),Boolean.TRUE) == null) n++;
break;
}
break;
if(printStats) System.err.println("Found " + n + " additional possible branch targets in Text segment");
}
- private void findBranchesInData(DataInputStream dis, int size, Set jumps, int textStart, int textEnd) throws IOException {
+ private void findBranchesInData(DataInputStream dis, int size, Hashtable jumps, int textStart, int textEnd) throws IOException {
int count = size/4;
int n=0;
for(int i=0;i<count;i++) {
int word = dis.readInt();
if((word&3)==0 && word >= textStart && word < textEnd) {
- if(jumps.add(new Integer(word))) {
+ if(jumps.put(new Integer(word),Boolean.TRUE) == null) {
//System.err.println("Added " + toHex(word) + " as possible branch target (fron data segment)");
n++;
}
public void set(Object val) {
if(field == null) return;
try {
- field.setAccessible(true);
+ /*field.setAccessible(true); NOT in JDK 1.1 */
field.set(Compiler.this,val);
} catch(IllegalAccessException e) {
System.err.println(e);
public Object get() {
if(field == null) return null;
try {
- field.setAccessible(true);
+ /*field.setAccessible(true); NOT in JDK 1.1 */
return field.get(Compiler.this);
} catch(IllegalAccessException e) {
System.err.println(e); return null;