# CS 3220 Processor Design Fall 2002

### iJVM2 Instructions

Below we list the instructions of the iJVM2 and their semantics.  We first introduce some notation.  If x is a 32-bit word and b is a byte then:
• C[x] is the byte in code whose address is x.
• S[x] is the 32-bit word in stack starting at address x.  (Recall that word are stored in big endian order.)
• Push[x] is a state where x has been pushed onto the stack (in big endian order).  This also means that sp has been incremented by 4.
• Pop[] is a state where sp is decremented by 4.
• L[b] is the bth local, which is stored at S[ap + 4*b], where b is treated as an unsigned byte.
• Cs[x] is the signed 16-word in C[x], C[x+1], where C[x] is the high-order byte.
Given an iJVM2 state s where  C[pc] is equal to the opcode of inst, the semantics (meaning) of the iJVM2 instructions specify how we obtain the next state, the state obtained by executing inst, by providing a list of commands that applied to the current state will result in the next state.  Each list of commands starts by incrementing the pc by 1 and for conciseness, we will not show this instruction explicitly.  In addition, all of the arithmetic and logical operations return 32 bit words. As per the discussion on bit vectors, we represent bit vectors as numbers. The semantics of the iJVM2 closely mimicks the semantics of the corresponding JVM instructions; the official specification of the JVM is maintained by Sun at http://java.sun.com/docs/books/vmspec/.

 Instruction Opcode Meaning (how to obtain the next state) NOP 0 ILOAD 21 Push[L[C[pc]]] pc:=pc+1 ISTORE 54 Pop[] val := S[sp] L[C[pc]] := val pc := pc+1 BIPUSH 16 Push[C[pc]], where C[pc] is treated as a signed number and extended to a 32-bit word. pc := pc+1 POP 87 Pop[] DUP 89 Push[S[sp-4]] SWAP 95 val1 := S[sp-4] val2 := S[sp-8] S[sp-8] := val1 S[sp-4] := val2 ISUB 100 val1 := S[sp-4] val2 := S[sp-8] S[sp-8] := val2-val1 sp := sp-4 IADD 96 val1 := S[sp-4] val2 := S[sp-8] S[sp-8] := val2+val1 sp := sp-4 IMUL 104 val1 := S[sp-4] val2 := S[sp-8] S[sp-8] := val2*val1 sp := sp-4 IAND 126 val1 := S[sp-4] val2 := S[sp-8] S[sp-8] := val2 AND val1 sp := sp-4 IOR 128 val1 := S[sp-4] val2 := S[sp-8] S[sp-8] := val2 OR val1 sp := sp-4 GOTO 167 pc :=  (pc-1)+ Cs[pc] IFEQ 153 Pop[] If S[sp] = 0 then pc := (pc-1) + Cs[pc]  else pc := pc+2 IFNE 154 Pop[] If !(S[sp] = 0) then pc := (pc-1) + Cs[pc]  else pc := pc+2 IFGT 157 Pop[] If S[sp] > 0 then pc := (pc-1) + Cs[pc]  else pc := pc+2 INVOKESTATIC1 184 old-pc :=  pc+2 old-fp := fp old-ap := ap pc :=  (pc-1)+ Cs[pc] nargs := C[pc] pc := pc+1 nlocs := C[pc] pc := pc+1 ap := sp - (4*nargs) fp := sp + (4* nlocs) sp := fp Push[old-ap] Push[old-fp] Push[old-pc] IRETURN 172 val := S[sp-4] sp := ap ap := S[fp] pc := S[fp+8] fp := S[fp+4] push[val]

1: The part that differs signficantly from the iJVM is the call/return mechanism.  iJVM2 does not have classes and there is no need to resolve method calls.  An invokestatic instruction specifies the beginning address of the method.  At that address, the first byte indicates the number of arguments to the method  and the second byte is the number of local variables in the method.  The method can access the arguments and locals using iload and istore.  The arguments are numbered 0, ..., nargs-1 and the locals are numbered nargs, ..., nargs+nlocs-1.   An ireturn instruction saves the top of the stack, restores the previous frame and pushes the saved value onto the new stack.