# # Extensions to MAL: # ------------------ # # - absolute labels; the syntax for labels have been extended to # allow for absolute placement of instructions, as required # by the implementation of IJVM. To have an instruction # placed e.g. at address 0x2A, write: # # imul = 0x2A: # MAR = SP = SP - 1; rd # ... # # The micro code immediately following is guaranteed to be # placed at address 0x2A, provided it does not collide with # other absolute labels. The label `imul' will also serve as # a target for both conditional and unconditional gotos. # # - nop instruction; since the assembler ignores blank lines, a # means to instruct the assembler to generate an empty cycle # is needed. This is used in the implementation of pop and # ireturn. More specifically, in the control word generated # by nop, NEXT_ADDRESS points to the following instruction, # the JAM field is 0, the ALU operation is unspecified, all C # and memory bits are 0 and B is unspecified. # # # Wed Apr 21 19:48:26 CEST 1999 # ----------------------------- # # Okay, "nop" is not a clever name since it is a java bytecode. # How about "empty"? But what about the label "goto"? # goto mic1_entry main: PC = PC + 1; fetch; goto (MBR) nop = 0x00: goto main iadd = 0x60: MAR = SP = SP - 1; rd H = TOS MDR = TOS = MDR + H; wr; goto main isub = 0x64: MAR = SP = SP - 1; rd H = TOS MDR = TOS = MDR - H; wr; goto main iand = 0x7E: MAR = SP = SP - 1; rd H = TOS MDR = TOS = MDR AND H; wr; goto main ior = 0x80: MAR = SP = SP - 1; rd H = TOS MDR = TOS = MDR OR H; wr; goto main dup = 0x59: MAR = SP = SP + 1 MDR = TOS; wr; goto main pop = 0x57: MAR = SP = SP - 1; rd empty TOS = MDR; goto main swap = 0x5F: MAR = SP - 1; rd MAR = SP H = MDR; wr MDR = TOS MAR = SP - 1; wr TOS = H; goto main bipush = 0x10: SP = MAR = SP + 1 PC = PC + 1; fetch MDR = TOS = MBR; wr; goto main iload = 0x15: H = LV MAR = MBRU + H; rd iload_cont: MAR = SP = SP + 1 PC = PC + 1; fetch; wr TOS = MDR; goto main istore = 0x36: H = LV MAR = MBRU + H istore_cont: MDR = TOS; wr SP = MAR = SP - 1; rd PC = PC + 1; fetch TOS = MDR; goto main wide = 0xC4: PC = PC + 1; fetch; goto (MBR OR 0x100) wide_iload = 0x115: PC = PC + 1; fetch H = MBRU << 8 H = MBRU OR H MAR = LV + H; rd; goto iload_cont wide_istore = 0x136: PC = PC + 1; fetch H = MBRU << 8 H = MBRU OR H MAR = LV + H; goto istore_cont ldc_w = 0x13: PC = PC + 1; fetch H = MBRU << 8 H = MBRU OR H MAR = H + CPP; rd; goto iload_cont iinc = 0x84: H = LV MAR = MBRU + H; rd PC = PC + 1; fetch H = MDR PC = PC + 1; fetch MDR = MBR + H; wr; goto main ijvm_goto = 0xA7: OPC = PC - 1 goto_cont: PC = PC + 1; fetch H = MBR << 8 H = MBRU OR H PC = OPC + H; fetch goto main iflt = 0x9B: MAR = SP = SP - 1; rd OPC = TOS TOS = MDR N = OPC; if (N) goto T; else goto F ifeq = 0x99: MAR = SP = SP - 1; rd OPC = TOS TOS = MDR Z = OPC; if (Z) goto T; else goto F if_icmpeq = 0x9F: MAR = SP = SP - 1; rd MAR = SP = SP - 1 H = MDR; rd OPC = TOS TOS = MDR Z = OPC - H; if (Z) goto T; else goto F T: OPC = PC - 1; fetch; goto goto_cont F: PC = PC + 1 PC = PC + 1; fetch goto main invokevirtual = 0xB6: PC = PC + 1; fetch H = MBRU << 8 H = MBRU OR H mic1_entry: MAR = CPP + H; rd OPC = PC + 1 PC = MDR; fetch PC = PC + 1; fetch H = MBRU << 8 H = MBRU OR H PC = PC + 1; fetch TOS = SP - H TOS = MAR = TOS + 1 PC = PC + 1; fetch H = MBRU << 8 H = MBRU OR H MDR = SP + H + 1; wr MAR = SP = MDR MDR = OPC; wr MAR = SP = SP + 1 MDR = LV; wr PC = PC + 1; fetch LV = TOS; goto main ireturn = 0xAC: MAR = SP = LV; rd empty LV = MAR = MDR; rd MAR = LV + 1 PC = MDR; rd; fetch MAR = SP LV = MDR MDR = TOS; wr Z = PC - 1; if (Z) goto mic1_exit; else goto main mic1_exit: halt ishl = 0x78: # It is possible to use the value of # the MBRU register to create the mask. H = MBRU >> 1 # MBRU = 1111000, H = 111100 H = H >> 1 # H = 11110 H = H + 1 # H = 11111 # Read second-to-top word from stack and # set SP to point to this position. MAR = SP = SP - 1; rd TOS = TOS AND H # Apply bit mask to the top word from # the stack which signifies the number # of shifts to perform. H = OPC = MDR # Load the value to be shifted. ishl_loop: # If the counter (TOS) is 0, end loop. Z = TOS; if (Z) goto ishl_end; else goto ishl_shift ishl_shift: H = OPC = OPC + H # Perform an arithmetic left-shift by # multiplying H and OPC. H and OPC is # loaded with the result to prepare for # possible further multiplications. TOS = TOS - 1 # Decrease the counter by one. goto ishl_loop ishl_end: # Customary push of result to the TOS # register and the stack in memory. # MAR = SP is not necessary, due to # MAR already being set to SP earlier. MDR = TOS = H; wr; goto main ishr = 0x7A: # It is possible to use the value of # the MBRU register to create the mask. H = MBRU >> 1 # MBRU = 1111010, H = 111101 H = H >> 1 # H = 11110 H = H + 1 # H = 11111 # Read second-to-top word from stack and # set SP to point to this position. MAR = SP = SP - 1; rd TOS = TOS AND H # Apply bit mask to the top word from # the stack. H = MDR # Load the value to be shifted into H. ishr_loop: # If the counter (TOS) is 0, end loop. Z = TOS; if (Z) goto ishr_end; else goto ishr_shift ishr_shift: # The actual shifting takes place here H = H >> 1 # The value is shifted arithmetically # right by 1-bit using the ALU. TOS = TOS - 1 # The counter is decreased. goto ishr_loop ishr_end: # Customary push of result to the TOS # register and the stack in memory. MDR = TOS = H; wr; goto main iushr = 0x7C: H = MBRU >> 1 # MBRU = 1111100, H = 111110 # Set H to the value of OPC to prepare # for the creation of a new bit-mask # later in the instruction. OPC = H = H >> 1 # H = 11111 # Read second-to-top word from stack and # set SP to point to this position. MAR = SP = SP - 1; rd TOS = TOS AND H # Apply bit mask to the top word from # the stack. # Create new bit mask from the previous # bit mask. H = OPC = OPC + 1 # H = 100000 H = OPC = H + OPC # H, OPC = 01000000 # The value of OPC after the following # instructions is listed in the # comments of each line: OPC = H + OPC # 00000000 00000000 00000000 10000000 OPC = OPC << 8 # 00000000 00000000 10000000 00000000 OPC = OPC << 8 # 00000000 10000000 00000000 00000000 OPC = OPC << 8 # 10000000 00000000 00000000 00000000 OPC = inv(OPC) # 01111111 11111111 11111111 11111111 # If anything is AND with OPC, it will # remove the most significant bit of # that value with OPC. H = MDR # Load H with the value to be shifted iushr_loop: Z = TOS; if (Z) goto iushr_end; else goto iushr_shift iushr_shift: H = H >> 1 # Do a 1-bit arithmetic right-shift H = H AND OPC # Use the bit-mask to remove the most # significant bit, effectively making # the arithmetic right-shift into a # logical right-shift. TOS = TOS - 1 # Decrease the counter by one. goto iushr_loop iushr_end: # Customary push of result to the TOS # register and the stack in memory. MDR = TOS = H; wr; goto main