dComArk15/Aflevering4-IJVM-Udvidelse/ijvm_ext.mal
Christoffer Müller Madsen e2e36f9f0d initial commit
2016-01-03 13:29:05 +01:00

304 lines
7.3 KiB
Plaintext

#
# 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