clarify licensing
[nestedvm.git] / src / org / ibex / nestedvm / Compiler.java
index b5835dd..acf1c48 100644 (file)
@@ -1,4 +1,6 @@
-// Copyright 2003 Adam Megacz, see the COPYING file for licensing [GPL]
+// Copyright 2000-2005 the Contributors, as shown in the revision logs.
+// Licensed under the Apache License 2.0 ("the License").
+// You may not use this file except in compliance with the License.
 
 package org.ibex.nestedvm;
 
@@ -7,38 +9,36 @@ import java.io.*;
 
 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;
+    ELF elf;
     
     /** The name of the class beging generated */
-    protected final String fullClassName;
+    final String fullClassName;
     
     /** The name of the binary this class is begin generated from */
-    protected String source = "unknown.mips.binary";
+    String source = "unknown.mips.binary";
     public void setSource(String source) { this.source = source; }
         
     /** Thrown when the compilation fails for some reason */
-    protected static class Exn extends Exception { public Exn(String s) { super(s); } }
+    static class Exn extends Exception { public Exn(String s) { super(s); } }
     
     // Set this to true to enable fast memory access 
     // When this is enabled a Java RuntimeException will be thrown when a page fault occures. When it is disabled
     // a FaultException will be throw which is easier to catch and deal with, however. as the name implies, this is slower
-    protected boolean fastMem = true;
+    boolean fastMem = true;
     
     // This MUST be a power of two. If it is not horrible things will happen
     // NOTE: This value can be much higher without breaking the classfile 
     // specs (around 1024) but Hotstop seems to do much better with smaller
     // methods. 
-    protected int maxInsnPerMethod = 128;
+    int maxInsnPerMethod = 128;
     
     // non-configurable
-    protected int maxBytesPerMethod;
-    protected int methodMask;
-    protected int methodShift;
-    protected void maxInsnPerMethodInit() throws Exn {
+    int maxBytesPerMethod;
+    int methodMask;
+    int methodShift;
+    void maxInsnPerMethodInit() throws Exn {
         if((maxInsnPerMethod&(maxInsnPerMethod-1)) != 0) throw new Exn("maxBytesPerMethod is not a power of two");
         maxBytesPerMethod = maxInsnPerMethod*4;
         methodMask = ~(maxBytesPerMethod-1);
@@ -46,44 +46,46 @@ public abstract class Compiler implements Registers {
     }
     
     // True to try to determine which case statement are needed and only include them
-    protected boolean pruneCases = true;
+    boolean pruneCases = true;
     
-    protected boolean assumeTailCalls = true;
+    boolean assumeTailCalls = true;
     
     // True to insert some code in the output to help diagnore compiler problems
-    protected boolean debugCompiler = false;
+    boolean debugCompiler = false;
     
     // True to print various statistics about the compilation
-    protected boolean printStats = false;
+    boolean printStats = false;
     
     // True to generate runtime statistics that slow execution down significantly
-    protected boolean runtimeStats = false;
+    boolean runtimeStats = false;
+    
+    boolean supportCall = true;
     
-    protected boolean supportCall = true;
+    boolean nullPointerCheck = false;
     
-    protected boolean nullPointerCheck = false;
+    String runtimeClass = "org.ibex.nestedvm.Runtime";
     
-    protected String runtimeClass = "org.ibex.nestedvm.Runtime";
+    String hashClass = "java.util.Hashtable";
     
-    protected String hashClass = "java.util.Hashtable";
+    boolean unixRuntime;
     
-    protected boolean unixRuntime;
+    boolean lessConstants;
     
-    protected boolean lessConstants = false;
+    boolean singleFloat;
             
-    protected int pageSize = 4096;
-    protected int totalPages = 65536;
-    protected int pageShift;
-    protected boolean onePage;
+    int pageSize = 4096;
+    int totalPages = 65536;
+    int pageShift;
+    boolean onePage;
     
-    protected void pageSizeInit() throws Exn {
+    void pageSizeInit() throws Exn {
         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++;
     }
     
     /** A set of all addresses that can be jumped too (only available if pruneCases == true) */
-    protected Hashtable jumpableAddresses;
+    Hashtable jumpableAddresses;
     
     /** Some important symbols */
     ELF.Symbol userInfo, gp;
@@ -99,6 +101,7 @@ public abstract class Compiler implements Registers {
     
     public static void main(String[] args) throws IOException {
         String outfile = null;
+        String outdir = null;
         String o = null;
         String className = null;
         String mipsBinaryFileName = null;
@@ -110,6 +113,10 @@ public abstract class Compiler implements Registers {
                 arg++;
                 if(arg==args.length) usage();
                 outfile = args[arg];
+            } else if(args[arg].equals("-d")) {
+                arg++;
+                if(arg==args.length) usage();
+                outdir = args[arg];
             } else if(args[arg].equals("-outformat")) {
                 arg++;
                 if(arg==args.length) usage();
@@ -140,12 +147,20 @@ public abstract class Compiler implements Registers {
         OutputStream os = null;
         Compiler comp = null;
         if(outformat == null || outformat.equals("class")) {
-            if(outfile == null) {
+            if(outfile != null) {
+                os = new FileOutputStream(outfile);
+                comp = new ClassFileCompiler(mipsBinary,className,os);
+            } else if(outdir != null) {
+                File f = new File(outdir);
+                if(!f.isDirectory()) {
+                    System.err.println(outdir + " doesn't exist or is not a directory");
+                    System.exit(1);
+                }
+                comp = new ClassFileCompiler(mipsBinary,className,f);
+            } else {
                 System.err.println("Refusing to write a classfile to stdout - use -outfile foo.class");
                 System.exit(1);
             }
-            os = new FileOutputStream(outfile);
-            comp = new ClassFileCompiler(mipsBinary,className,os);
         } else if(outformat.equals("javasource") || outformat .equals("java")) {
             w = outfile == null ? new OutputStreamWriter(System.out): new FileWriter(outfile);
             comp = new JavaSourceCompiler(mipsBinary,className,w);
@@ -179,12 +194,12 @@ public abstract class Compiler implements Registers {
         this.fullClassName = fullClassName;
         elf = new ELF(binary);
         
-        if(elf.header.type != ELF.ELFHeader.ET_EXEC) throw new IOException("Binary is not an executable");
-        if(elf.header.machine != ELF.ELFHeader.EM_MIPS) throw new IOException("Binary is not for the MIPS I Architecture");
-        if(elf.ident.data != ELF.ELFIdent.ELFDATA2MSB) throw new IOException("Binary is not big endian");
+        if(elf.header.type != ELF.ET_EXEC) throw new IOException("Binary is not an executable");
+        if(elf.header.machine != ELF.EM_MIPS) throw new IOException("Binary is not for the MIPS I Architecture");
+        if(elf.ident.data != ELF.ELFDATA2MSB) throw new IOException("Binary is not big endian");
     }
 
-    protected abstract void _go() throws Exn, IOException;
+    abstract void _go() throws Exn, IOException;
     
     private boolean used;
     public void go() throws Exn, IOException {
@@ -236,7 +251,7 @@ public abstract class Compiler implements Registers {
         
         for(int i=0;i<elf.sheaders.length;i++) {
             String name = elf.sheaders[i].name;
-            if(elf.sheaders[i].addr != 0 && !(
+            if((elf.sheaders[i].flags & ELF.SHF_ALLOC) !=0 && !(
                 name.equals(".text")|| name.equals(".data") || name.equals(".sdata") || name.equals(".rodata") ||
                 name.equals(".ctors") || name.equals(".dtors") || name.equals(".bss") || name.equals(".sbss")))
                     throw new Exn("Unknown section: " + name);
@@ -363,8 +378,8 @@ public abstract class Compiler implements Registers {
     }
     
     // Helper functions for pretty output
-    protected final static String toHex(int n) { return "0x" + Long.toString(n & 0xffffffffL, 16); }
-    protected final static String toHex8(int n) {
+    final static String toHex(int n) { return "0x" + Long.toString(n & 0xffffffffL, 16); }
+    final static String toHex8(int n) {
         String s = Long.toString(n & 0xffffffffL, 16);
         StringBuffer sb = new StringBuffer("0x");
         for(int i=8-s.length();i>0;i--) sb.append('0');
@@ -372,7 +387,7 @@ public abstract class Compiler implements Registers {
         return sb.toString();
     }
 
-    protected final static String toOctal3(int n) {
+    final static String toOctal3(int n) {
         char[] buf = new char[3];
         for(int i=2;i>=0;i--) {
             buf[i] = (char) ('0' + (n & 7));
@@ -423,7 +438,8 @@ public abstract class Compiler implements Registers {
         "pageSize",         "The page size (must be a power of two)",
         "totalPages",       "Total number of pages (total mem = pageSize*totalPages, must be a power of two)",
         "onePage",          "One page hack (FIXME: document this better)",
-        "lessConstants",    "Use less constants at the cost of speed (FIXME: document this better)"
+        "lessConstants",    "Use less constants at the cost of speed (FIXME: document this better)",
+        "singleFloat",      "Support single precision (32-bit) FP ops only"
     };
         
     private Option getOption(String name) {
@@ -512,7 +528,7 @@ public abstract class Compiler implements Registers {
     
     // This ugliness is to work around a gcj static linking bug (Bug 12908)
     // The best solution is to force gnu.java.locale.Calendar to be linked in but this'll do
-    protected static String dateTime() {
+    static String dateTime() {
         try {
             return new Date().toString();
         } catch(RuntimeException e) {