[llvm-commits] CVS: llvm-java/lib/Compiler/Compiler.cpp

Alkis Evlogimenos alkis at cs.uiuc.edu
Sat May 22 01:00:03 PDT 2004


Changes in directory llvm-java/lib/Compiler:

Compiler.cpp added (r1.1)

---
Log message:

Add an initial implementation of a Java bytecode to LLVM compiler.


---
Diffs of the changes:  (+428 -0)

Index: llvm-java/lib/Compiler/Compiler.cpp
diff -c /dev/null llvm-java/lib/Compiler/Compiler.cpp:1.1
*** /dev/null	Sat May 22 00:58:36 2004
--- llvm-java/lib/Compiler/Compiler.cpp	Sat May 22 00:58:26 2004
***************
*** 0 ****
--- 1,428 ----
+ //===-- Compiler.cpp - Java bytecode compiler -------------------*- C++ -*-===//
+ //
+ //                     The LLVM Compiler Infrastructure
+ //
+ // This file was developed by the LLVM research group and is distributed under
+ // the University of Illinois Open Source License. See LICENSE.TXT for details.
+ //
+ //===----------------------------------------------------------------------===//
+ //
+ // This file contains Java bytecode to LLVM bytecode compiler.
+ //
+ //===----------------------------------------------------------------------===//
+ 
+ #include <llvm/Java/Bytecode.h>
+ #include <llvm/Java/ClassFile.h>
+ #include <llvm/Java/Compiler.h>
+ #include <llvm/Constants.h>
+ #include <llvm/DerivedTypes.h>
+ #include <llvm/Instructions.h>
+ #include <llvm/Value.h>
+ #include <llvm/Type.h>
+ #include <stack>
+ #include <vector>
+ 
+ using namespace llvm;
+ 
+ namespace {
+ 
+     inline bool isTwoSlotValue(const Value* v) {
+         return v->getType() == Type::LongTy | v->getType() == Type::DoubleTy;
+     }
+ 
+     inline bool isOneSlotValue(const Value* v) {
+         return !isTwoSlotValue(v);
+     }
+ 
+     void compileMethod(Module& module, const Java::Method& method) {
+         using namespace llvm::Java::Opcode;
+ 
+         Function* function =
+             module.getOrInsertFunction(method.getName()->str(), Type::VoidTy);
+ 
+         const Java::CodeAttribute* codeAttr =
+             Java::getCodeAttribute(method.getAttributes());
+ 
+         std::stack<Value*> opStack;
+         std::vector<Value*> locals(codeAttr->getMaxLocals(), 0);
+ 
+         const uint8_t* code = codeAttr->getCode();
+         for (unsigned i = 0; i < codeAttr->getCodeSize(); ++i) {
+             bool wide = code[i] == WIDE;
+             i += wide;
+             switch (code[i]) {
+             case ACONST_NULL:
+                 // FIXME: should push a null pointer of type Object*
+                 opStack.push(
+                     ConstantPointerNull::get(PointerType::get(Type::VoidTy)));
+                 break;
+             case ICONST_M1:
+             case ICONST_0:
+             case ICONST_1:
+             case ICONST_2:
+             case ICONST_3:
+             case ICONST_4:
+             case ICONST_5:
+                 opStack.push(ConstantInt::get(Type::IntTy, code[i]-ICONST_0));
+                 break;
+             case LCONST_0:
+             case LCONST_1:
+                 opStack.push(ConstantInt::get(Type::LongTy, code[i]-LCONST_0));
+                 break;
+             case FCONST_0:
+             case FCONST_1:
+             case FCONST_2:
+                 opStack.push(ConstantFP::get(Type::FloatTy, code[i]-FCONST_0));
+                 break;
+             case DCONST_0:
+             case DCONST_1:
+                 opStack.push(ConstantFP::get(Type::DoubleTy, code[i]-DCONST_0));
+                 break;
+             case BIPUSH: {
+                 int imm = code[++i];
+                 opStack.push(ConstantInt::get(Type::IntTy, imm));
+                 break;
+             }
+             case SIPUSH: {
+                 int imm = (code[++i] << 8) | code[++i];
+                 opStack.push(ConstantInt::get(Type::IntTy, imm));
+                 break;
+             }
+             case LDC: {
+                 unsigned index = code[++i];
+                 // FIXME: load constant from constant pool
+             }
+             case LDC_W: {
+                 unsigned index = (code[++i] << 8) | code[++i];
+                 // FIXME: load constant from constant pool
+             }
+             case LDC2_W: {
+                 unsigned index = (code[++i] << 8) | code[++i];
+                 // FIXME: load constant from constant pool
+             }
+             case ILOAD:
+             case LLOAD:
+             case FLOAD:
+             case DLOAD:
+             case ALOAD: {
+                 // FIXME: use opcodes to perform type checking
+                 unsigned index = code[++i];
+                 opStack.push(locals[index]);
+                 break;
+             }
+             case ILOAD_0:
+             case ILOAD_1:
+             case ILOAD_2:
+             case ILOAD_3:
+                 opStack.push(locals[code[i]-ILOAD_0]);
+                 break;
+             case LLOAD_0:
+             case LLOAD_1:
+             case LLOAD_2:
+             case LLOAD_3:
+                 opStack.push(locals[code[i]-LLOAD_0]);
+                 break;
+             case FLOAD_0:
+             case FLOAD_1:
+             case FLOAD_2:
+             case FLOAD_3:
+                 opStack.push(locals[code[i]-FLOAD_0]);
+                 break;
+             case DLOAD_0:
+             case DLOAD_1:
+             case DLOAD_2:
+             case DLOAD_3:
+                 opStack.push(locals[code[i]-DLOAD_0]);
+                 break;
+             case ALOAD_0:
+             case ALOAD_1:
+             case ALOAD_2:
+             case ALOAD_3:
+                 opStack.push(locals[code[i]-ALOAD_0]);
+                 break;
+             case IALOAD:
+             case LALOAD:
+             case FALOAD:
+             case DALOAD:
+             case AALOAD:
+             case BALOAD:
+             case CALOAD:
+             case SALOAD:
+             case ISTORE:
+             case LSTORE:
+             case FSTORE:
+             case DSTORE:
+             case ASTORE:
+             case ISTORE_0:
+             case ISTORE_1:
+             case ISTORE_2:
+             case ISTORE_3:
+             case LSTORE_0:
+             case LSTORE_1:
+             case LSTORE_2:
+             case LSTORE_3:
+             case FSTORE_0:
+             case FSTORE_1:
+             case FSTORE_2:
+             case FSTORE_3:
+             case DSTORE_0:
+             case DSTORE_1:
+             case DSTORE_2:
+             case DSTORE_3:
+             case ASTORE_0:
+             case ASTORE_1:
+             case ASTORE_2:
+             case ASTORE_3:
+             case IASTORE:
+             case LASTORE:
+             case FASTORE:
+             case DASTORE:
+             case AASTORE:
+             case BASTORE:
+             case CASTORE:
+             case SASTORE:
+                 assert(0 && "not implemented");
+             case POP:
+                 opStack.pop();
+                 break;
+             case POP2:
+                 opStack.pop();
+                 opStack.pop();
+                 break;
+             case DUP:
+                 opStack.push(opStack.top());
+                 break;
+             case DUP_X1: {
+                 Value* v1 = opStack.top(); opStack.pop();
+                 Value* v2 = opStack.top(); opStack.pop();
+                 opStack.push(v1);
+                 opStack.push(v2);
+                 opStack.push(v1);
+                 break;
+             }
+             case DUP_X2: {
+                 Value* v1 = opStack.top(); opStack.pop();
+                 Value* v2 = opStack.top(); opStack.pop();
+                 if (isOneSlotValue(v2)) {
+                     Value* v3 = opStack.top(); opStack.pop();
+                     opStack.push(v1);
+                     opStack.push(v3);
+                     opStack.push(v2);
+                     opStack.push(v1);
+                 }
+                 else {
+                     opStack.push(v1);
+                     opStack.push(v2);
+                     opStack.push(v1);
+                 }
+                 break;
+             }
+             case DUP2: {
+                 Value* v1 = opStack.top(); opStack.pop();
+                 if (isOneSlotValue(v1)) {
+                     Value* v2 = opStack.top(); opStack.pop();
+                     opStack.push(v2);
+                     opStack.push(v1);
+                     opStack.push(v2);
+                     opStack.push(v1);
+                 }
+                 else {
+                     opStack.push(v1);
+                     opStack.push(v1);
+                 }
+                 break;
+             }
+             case DUP2_X1: {
+                 Value* v1 = opStack.top(); opStack.pop();
+                 Value* v2 = opStack.top(); opStack.pop();
+                 if (isOneSlotValue(v1)) {
+                     Value* v3 = opStack.top(); opStack.pop();
+                     opStack.push(v2);
+                     opStack.push(v1);
+                     opStack.push(v3);
+                     opStack.push(v2);
+                     opStack.push(v1);
+                 }
+                 else {
+                     opStack.push(v1);
+                     opStack.push(v2);
+                     opStack.push(v1);
+                 }
+                 break;
+             }
+             case DUP2_X2: {
+                 Value* v1 = opStack.top(); opStack.pop();
+                 Value* v2 = opStack.top(); opStack.pop();
+                 if (isOneSlotValue(v1)) {
+                     Value* v3 = opStack.top(); opStack.pop();
+                     if (isOneSlotValue(v3)) {
+                         Value* v4 = opStack.top(); opStack.pop();
+                         opStack.push(v2);
+                         opStack.push(v1);
+                         opStack.push(v4);
+                         opStack.push(v3);
+                         opStack.push(v2);
+                         opStack.push(v1);
+                     }
+                     else {
+                         opStack.push(v2);
+                         opStack.push(v1);
+                         opStack.push(v3);
+                         opStack.push(v2);
+                         opStack.push(v1);
+                     }
+                 }
+                 else {
+                     if (isOneSlotValue(v2)) {
+                         Value* v3 = opStack.top(); opStack.pop();
+                         opStack.push(v1);
+                         opStack.push(v3);
+                         opStack.push(v2);
+                         opStack.push(v1);
+                     }
+                     else {
+                         opStack.push(v1);
+                         opStack.push(v2);
+                         opStack.push(v1);
+                     }
+                 }
+                 break;
+             }
+             case SWAP: {
+                 Value* v1 = opStack.top(); opStack.pop();
+                 Value* v2 = opStack.top(); opStack.pop();
+                 opStack.push(v1);
+                 opStack.push(v2);
+                 break;
+             }
+             case IADD:
+             case LADD:
+             case FADD:
+             case DADD:
+             case ISUB:
+             case LSUB:
+             case FSUB:
+             case DSUB:
+             case IMUL:
+             case LMUL:
+             case FMUL:
+             case DMUL:
+             case IDIV:
+             case LDIV:
+             case FDIV:
+             case DDIV:
+             case IREM:
+             case LREM:
+             case FREM:
+             case DREM:
+             case INEG:
+             case LNEG:
+             case FNEG:
+             case DNEG:
+             case ISHL:
+             case LSHL:
+             case ISHR:
+             case LSHR:
+             case IUSHR:
+             case LUSHR:
+             case IAND:
+             case LAND:
+             case IOR:
+             case LOR:
+             case IXOR:
+             case LXOR:
+             case IINC:
+             case I2L:
+             case I2F:
+             case I2D:
+             case L2I:
+             case L2F:
+             case L2D:
+             case F2I:
+             case F2L:
+             case F2D:
+             case D2I:
+             case D2L:
+             case D2F:
+             case I2B:
+             case I2C:
+             case I2S:
+             case LCMP:
+             case FCMPL:
+             case FCMPG:
+             case DCMPL:
+             case DCMPG:
+             case IFEQ:
+             case IFNE:
+             case IFLT:
+             case IFGE:
+             case IFGT:
+             case IFLE:
+             case IF_ICMPEQ:
+             case IF_ICMPNE:
+             case IF_ICMPLT:
+             case IF_ICMPGE:
+             case IF_ICMPGT:
+             case IF_ICMPLE:
+             case IF_ICMPACMPEQ:
+             case IF_ICMPACMPNE:
+             case GOTO:
+             case JSR:
+             case RET:
+             case TABLESWITCH:
+             case LOOKUPSWITCH:
+             case IRETURN:
+             case LRETURN:
+             case FRETURN:
+             case DRETURN:
+             case ARETURN:
+             case RETURN:
+             case GETSTATIC:
+             case PUTSTATIC:
+             case GETFIELD:
+             case PUTFIELD:
+             case INVOKEVIRTUAL:
+             case INVOKESPECIAL:
+             case INVOKESTATIC:
+             case INVOKEINTERFACE:
+             case XXXUNUSEDXXX:
+             case NEW:
+             case NEWARRAY:
+             case ANEWARRAY:
+             case ARRAYLENGTH:
+             case ATHROW:
+             case CHECKCAST:
+             case INSTANCEOF:
+             case MONITORENTER:
+             case MONITOREXIT:
+             case WIDE:
+             case MULTIANEWARRAY:
+             case IFNULL:
+             case IFNONNULL:
+             case GOTO_W:
+             case JSR_W:
+             case BREAKPOINT:
+             case IMPDEP1:
+             case IMPDEP2:
+             case NOP:
+                 break;
+             }
+         }
+     }
+ 
+ } // namespace
+ 
+ Module* llvm::Java::compile(const ClassFile& cf)
+ {
+     Module* module = new Module(cf.getThisClass()->getName()->str());
+ 
+     std::vector<Value*> opStack;
+ 
+     const Java::Methods& methods = cf.getMethods();
+     for (Java::Methods::const_iterator
+              i = methods.begin(), e = methods.end(); i != e; ++i) {
+         compileMethod(*module, **i);
+     }
+ 
+     return module;
+ }





More information about the llvm-commits mailing list