HarryW
Dec 6th, 2000, 12:12 AM
Well I doubt if this is the kind of question anybody is used to seeing.
I am writing an instruction for the IJVM instruction set on a very simple CPU, which has to multiply two 32-bit 2's complement signed operands on the stack and place the result into two 32-bit operands back on the stack, as a high word and a low word.
I am posting it here because being an assembler forum I fugured a lot of people would probably know about the internal workings of a CPU. Maybe even know how to do what I'm trying to do :)
Essentially I have these registers:
MAR - Memory Address Register
MDR - Memory Data Register
PC - Program Counter
MBR - Memory Buffer Register
SP - Stack Pointer
LV - Local Variable pointer
CPP - Constant Pool Pointer
TOS - Top Of Stack register (can be used as a temp. space)
OPC - temporary (ie scratch) register
H - Holding register, used for a second input to the ALU/shifter
I need to make a microprogram using microcode that will basically read in data from the stack to MDR, move values from register to register, use the ALU and shifter on the values in the registers, and write data back to the stack from MDR.
Okay, here's what I'm asking :)
I would very much appreciate any ideas for algorithms to multiply operands with sign extension. I also would like to know how to get the result into two 32-bit words. I have a few ideas running around in my head for all these things but nothing concrete.
Now if anybody fancies trying their hand at some microcode (or if they've done it before) then that would be greatly appreciated. I will outline the basic syntax:
First a quick example:
MAR = SP = SP + 1 Increment SP and copy to MAR
MDR = TOS; wr Write new stack word
That is the IJVM idup instruction, which duplicates the word on top of the stack, placing the duplicate on the stack too.
Each line represents one CPU cycle, and seperate actions are divided by semicolons (;).
"wr" represents a write to the stack at the position the value in SP (stack pointer) points to, writing the value contained in MDR (memory data register). "rd" does the opposite, placing the value pointed to by SP into MDR. At the beginning of each instruction (ie at the beginning of the microprogram) TOS contains the value on the top of the stack. This is for convenience, and it can be overwritten and used as a temporary workspace if necessary.
MAR and MBR work with bytes (8 bits). MDR and SP and the others use words (32 bits). When you assign a word value to MAR, it gets shifted automatically so you don't have to worry about it. You can also use MBRU, which is the unsigned version of the value in MBR. You can use "fetch" to get a byte value at the address in MAR and put it in MBR.
Here is another example, iload, which loads a variable onto the stack.
The offset of the local variable to put on the stack is in MBRU.
H = LV MBR contains index; Copy LV to H
MAR = MBRU + H; rd MAR = address of local variable to push
MAR = SP = SP + 1 SP points to new top of stack; prepare write
PC = PC + 1; fetch; wr Inc PC; get next opcode; write top of stack
TOS = MDR Update top of stack
I feel like I'm the only person in the world that is doing this at the moment. Does anybody even know what I'm talking about?
Well I know this is probably all really boring, so it's a good thing that I think I can handle the microcode. Actually just writing this has helped me to understand it :)
I would really, really, appreciate some help on the algorithm to do the multiplication though.
Right that's it, thanks for your time if you've read this far :)
I am writing an instruction for the IJVM instruction set on a very simple CPU, which has to multiply two 32-bit 2's complement signed operands on the stack and place the result into two 32-bit operands back on the stack, as a high word and a low word.
I am posting it here because being an assembler forum I fugured a lot of people would probably know about the internal workings of a CPU. Maybe even know how to do what I'm trying to do :)
Essentially I have these registers:
MAR - Memory Address Register
MDR - Memory Data Register
PC - Program Counter
MBR - Memory Buffer Register
SP - Stack Pointer
LV - Local Variable pointer
CPP - Constant Pool Pointer
TOS - Top Of Stack register (can be used as a temp. space)
OPC - temporary (ie scratch) register
H - Holding register, used for a second input to the ALU/shifter
I need to make a microprogram using microcode that will basically read in data from the stack to MDR, move values from register to register, use the ALU and shifter on the values in the registers, and write data back to the stack from MDR.
Okay, here's what I'm asking :)
I would very much appreciate any ideas for algorithms to multiply operands with sign extension. I also would like to know how to get the result into two 32-bit words. I have a few ideas running around in my head for all these things but nothing concrete.
Now if anybody fancies trying their hand at some microcode (or if they've done it before) then that would be greatly appreciated. I will outline the basic syntax:
First a quick example:
MAR = SP = SP + 1 Increment SP and copy to MAR
MDR = TOS; wr Write new stack word
That is the IJVM idup instruction, which duplicates the word on top of the stack, placing the duplicate on the stack too.
Each line represents one CPU cycle, and seperate actions are divided by semicolons (;).
"wr" represents a write to the stack at the position the value in SP (stack pointer) points to, writing the value contained in MDR (memory data register). "rd" does the opposite, placing the value pointed to by SP into MDR. At the beginning of each instruction (ie at the beginning of the microprogram) TOS contains the value on the top of the stack. This is for convenience, and it can be overwritten and used as a temporary workspace if necessary.
MAR and MBR work with bytes (8 bits). MDR and SP and the others use words (32 bits). When you assign a word value to MAR, it gets shifted automatically so you don't have to worry about it. You can also use MBRU, which is the unsigned version of the value in MBR. You can use "fetch" to get a byte value at the address in MAR and put it in MBR.
Here is another example, iload, which loads a variable onto the stack.
The offset of the local variable to put on the stack is in MBRU.
H = LV MBR contains index; Copy LV to H
MAR = MBRU + H; rd MAR = address of local variable to push
MAR = SP = SP + 1 SP points to new top of stack; prepare write
PC = PC + 1; fetch; wr Inc PC; get next opcode; write top of stack
TOS = MDR Update top of stack
I feel like I'm the only person in the world that is doing this at the moment. Does anybody even know what I'm talking about?
Well I know this is probably all really boring, so it's a good thing that I think I can handle the microcode. Actually just writing this has helped me to understand it :)
I would really, really, appreciate some help on the algorithm to do the multiplication though.
Right that's it, thanks for your time if you've read this far :)