Forums - Open Redstone Engineers
My new and most thought out IS. - Printable Version

+- Forums - Open Redstone Engineers (https://forum.openredstone.org)
+-- Forum: ORE General (https://forum.openredstone.org/forum-39.html)
+--- Forum: Projects & Inventions (https://forum.openredstone.org/forum-19.html)
+---- Forum: Completed Projects (https://forum.openredstone.org/forum-21.html)
+---- Thread: My new and most thought out IS. (/thread-5218.html)

Pages: 1 2 3


RE: My new and most thought out IS. - Chibill - 12-23-2014

I have no addc. I am going to be deleteing this thread after new years and reposting because of this 'war' on NOOP on 0000


RE: My new and most thought out IS. - TSO - 12-24-2014

My full reply and suggestions for alteration of your IS. This isn't all that edited, and considering how much time I spent formatting it, I'm sure you can see why I don't want to deal with this post anymore. I will also add that there is no reason to delete the thread simply because we disagree on the presence of an opcode at 0x00. This would be addressed at some point, and you were lucky enough to get stuck with it.


Code:
#    bin    hex    short    name        effect
___________________________________________________________________

0     00000    0x00    NOP    No Operation       Does Nothing
1     00001    0x01    AND    And                Logical And
2     00010    0x02    OR     Or                 Logical Or
3     00011    0x03    XOR    Xor                Logical Exclusive Or
4     00100    0x04    ADD    Add                Add
5     00101    0x05    SUB    Subtract           Subtract
6     00110    0x06    MUL    Multiply           Multiplies
7     00111    0x07    DIV    Divide             Divides
8     01000    0x08    PUH    Push               Push register to stack
9     01001    0x09    POP    Pop                Pops stack to register
10    01010    0x0A    PUI    Push Im            Push value to stack
11    01011    0x0B    SBM    Stack Bit Mode     Set Bit Mode Of Stack
12    01100    0x0C    STR    Store              Store to Register
13    01101    0x0D    LAD    Load               Load one register from another
14    01110    0x0E    STI    Store Im           Store immediate
15    01111    0x0F    RBM    Register Mode      Set bit size mode for register
16    10000    0x10    CSJ    Conditional Jmp    Jump stack conditionally
17    10001    0x11    JUP    Jump               Jump unconditionally
18    10010    0x12    CRJ    Cond. reg. jmp     Jump Register conditionally
19    10011    0x13    RTN    Return             Return point of subroutine
20    10100    0x14    SUT    Subroutine         Subroutine
21    10101    0x15    EBW    Bus Write          Write to external bus
22    10110    0x16    EBR    Bus Read           Read from external bus buffer
23    10111    0x17    RST    Reset              Clear all registers
24    11000    0x18    SME    Same               Same as previous operation
25    11001    0x19    HLT    Halt               Stop System
____________________________________________________________________________________

Groups:

Nop
Math (7, 3 logic, 4 arithmetic)
Stack (4, 2 redundant pairs)
Regs (4, 2 redundant pairs)
jumps (3, 1 redundant pair)
subroutines (2, semi-redundant to other instructions)
I/O (2)
Reset
SME (redundant)
HLT (could be better placed)
_____________________________________________________________________________

The first thing I'm going to do is define what I assume to be your machine
architecture, with a few modifications of my own.

This is a "stack machine" where there is only one directly operable stack as
well as a second stack on the instruction register. The individual registers
do not have their own stacks.

Registers: I will assume a total of 16 because 'cuz.

EAX-EJX (named E_X because 'cuz)
El Stacko (EST)
Instruction Stack (INS)
Instruction Pointer (INP)
I/O bus (IOP)
FLAGS:
    0: Carry Flag (set by add and mul)
    1: Overflow Flag (set by sub and div)
    2: Sign Flag (set if number is negative)
    3: Zero Flag (set if most recent output is zero)
    4&5: Register Bit flags (00: 4 bit, 01: 8 bit, 10: 16 bit, 11: 32 bit)
    6&7: Stack Bit flags (00: 4 bit, 01: 8 bit, 10: 16 bit, 11: 32 bit)

I will assume nothing about the instruction set except the following: the
Instruction set will be able to address two registers per instruction.

If we look at this instruction set immediately, issues, oversights, and
over-complications can be spotted. The most important: you have not defined a
Move operation. This means that you do not have a useful general operation
that simply moves values from one place to another. Instead, you define several
more complex operations for each case. This is important because SBM, STR, LAD,
STI (sort of), RBM, RTN, SME, EBW, and EBR are all the same instruction: MOV. This is why
all computers use a Move instruction.
    SBM nn: MOV val, FLAGS
    RBM nn: MOV val, FLAGS
    STR EAX, EBX: MOV EAX, EBX
    LAD EAX, EBX: MOV EBX, EAX
    STI EAX, val: MOV val, EAX
    RTN: MOV INS, INP
    SME: MOV INP-1, INP
    EBW EAX: MOV EAX, IOP
    EBR EAX: MOV IOP, EAX

So that fixes that, but still more repeats exist. If it is a dedicated stack
machine, then you should be fully aware that moving a value from a stack is
the same as popping it, so:
    POP EAX: MOV EST, EAX
    PUS EAX: MOV EAX, EST
    PUI val: MOV val, EST
    
Okay, so we have fixed some stuff. Now for useless opcodes and maybe even some
changes for better performance. (remember, the more directly your opcode
translates to actual hardware properties, the better)

Useless:
    CRJ/CSJ: what does CRJ even do? Anyway, it's a redundant pair, kill one.
    SME: are you really that lazy? Besides, how often do you perform
         sequential operations multiple times in a row on the same
         registers with the same opcode. Truly useless opcode.

So, a quick refresher:
    
0     00000    0x00    NOP    No Operation       Does Nothing
1     00001    0x01    AND    And                Logical And
2     00010    0x02    OR     Or                 Logical Or
3     00011    0x03    XOR    Xor                Logical Exclusive Or
4     00100    0x04    ADD    Add                Add
5     00101    0x05    SUB    Subtract           Subtract
6     00110    0x06    MUL    Multiply           Multiplies
7     00111    0x07    DIV    Divide             Divides
16    10000    0x10    CSJ    Conditional Jmp    Jumps conditionally
17    10001    0x11    JUP    Jump               Jumps unconditionally
20    10100    0x14    SUT    Subroutine         Subroutine
23    10111    0x17    RST    Reset              Clear all registers
25    11001    0x19    HLT    Halt               Stop System

            #MOV is in there somewhere

SUT is an interesting opcode. It codes as MOV INP, INS; MOV val, INP. In
English: push the instruction pointer to the stack, then jump somewhere.
Return then codes as, "pop the instruction stack," which would, of course, jump
back to the original location set by the SUT command. You can leave SUT out of
the instruction list if you know what it does, or you can keep it if you feel
lazy. That is entirely up to you.

Okay, so now we have (with move included):

0     00000    0x00    NOP    No Operation       Does Nothing
1     00001    0x01    AND    And                Logical And
2     00010    0x02    OR     Or                 Logical Or
3     00011    0x03    XOR    Xor                Logical Exclusive Or
4     00100    0x04    ADD    Add                Add
5     00101    0x05    SUB    Subtract           Subtract
6     00110    0x06    MUL    Multiply           Multiplies
7     00111    0x07    DIV    Divide             Divides
8     01000    0x08    CSJ    Conditional Jmp    Jumps conditionally
9     01001    0x09    JUP    Jump               Jumps unconditionally
10    01010    0x0A    RST    Reset              Clear all registers
11    01011    0x0B    HLT    Halt               Stop System
12    01100    0x0C    MOV    Move               Moves values between registers

So, now let's do some simple thought, and then we will reorganize.

ADD/SUB use the same unit, except that SUB EAX, EBX is ADC EAX, EBX', while
SBB is ADD EAX, EBX'. Therefore, those four operations are easily consolidated
into a single unit with opcodes where the 0 bit is the carry and the 1 bit is
the inverter. These all fall into the arithmetic group, along with the DIV and
MUL. Now, DIV will only return the integer portion of a division, so a special
operation is needed to determine the remainder: I call it MOD, and MOD EAX,
EBX = B mod(A), which is the remainder of B/A.

The logic unit can now be altered slightly using De Morgan's laws
AB = (A'+B')'
A+B = A+B = (A'B')'
(AB)' = A'+B'
(A+B)' = (A+B)' = A'B'
A XOR B = A'B + B'A = (A'B' + AB)'
A XNOR B = (A'B + B'A)' = A'B' + AB
A' = A'+0 = A'1 = A'0' = A'1 + 0A
AB' = (A'+B)'

This seems tricky, but it isn't once you think about it.
We have 8 opcodes in the logic unit and we have 3 different things to mess
with, piece of cake.

The selector is on bit 2. In section 0, the output inversion is bit 0, and the
AB inversion is on bit 1. In section 1, the output inversion is on bit 0 and
the A'B enable is on bit 1. If the A'B enable is zero, and the inversion is 1,
then A will be set to 0 throughout.

000 A+B
001 (A+B)'
010 A'+B'
011 (A'+B')'
100 AB'
101 A+B'
110 A'B + B'A
111 (A'B + B'A)'

Okay, now onto the "stack" section:
It's gone

The Register section:
I chose to keep MOV and MVI just for simplicity's sake. So moving an immediate
value is still a separate operation.

Jump:
We just have JMP and CSJ now, so that's that.

Subroutines and I/O were killed.

NOP, RST, and HLT are special control cases.

So, currently, NOP is on 0x00. This is... okay, but HLT is a much better
candidate for 0x00. If you make the instruction pointer increment by the OR of
all bits in the opcode AND'ed with the Clock, then if the opcode is zero, the
instruction pointer will not increment. OR the output of the mask with a Trap
control and you have the ability to override the HLT when the time comes. One
other thing comes to mind, though. NOP is only valid if the architecture has a
pipeline, so it isn't needed per se.

The new Instruction List now has several interesting properties that one would
not have forseen.

0     00000    0x00    HLT    Halt               Stop system
1     00001    0x01    MUL    Multiply           Multiplies
2     00010    0x02    DIV    Divide             Integer divide    
3     00011    0x03    MOD    Modulus            Remainder of divide
4     00100    0x04    ADD    Add                Add without carry
5     00101    0x05    ADC    Add Carry          Add with carry of 1
6     00110    0x06    SBB    Sub Borrow         Subtract with borrow of 1
7     00111    0x07    SUB    Subtract           Subtract without borrow
8     01000    0x08    OR     Logical OR         Bitwise OR of two registers
9     01001    0x09    NOR    Logical NOR        Bitwise NOR of two registers
10    01010    0x0A    NAND   Logical NAND       Bitwise NAND of two registers
11    01011    0x0B    AND    Logical AND        Bitwise AND of two registers
12    01100    0x0C    IMP    Implies            Bitwise AND of A with B'
13    01101    0x0D    NOT    Logical NOT        Bitwise inversion of register
14    01110    0x0E    XOR    Logical XOR        Bitwise XOR of two registers
15    01111    0x0F    XNOR   Logical XNOR       Bitwise XNOR of two registers
16    10000    0x10    MOV    Move               Move values between registers
19    10001    0x11    MVI    Move Immediate     Move Immediate value
17    10010    0x12    CSJ    Conditional jmp    Jump conditionally
18    10011    0x13    JMP    Jump               Jump unconditionally
19    10100    0x14    RST    Reset              Resets all registers
21-23 101xx    0x15-17 ???    ???                Undefined operations
24-32 11xxx    0x18-1F ROL    Rotate Left        Rotate to the left xxx places

I use rotate instead of shift because you can rotate an amount, then cut out
the bits that should be zero, therefore you can rotate in such a way as to
shift up or down all with the same instruction.

    ROL 111, EAX; AND 01111111, EAX = SHR 1, EAX
    ROL 001, EAX; AND 11111110, EAX = SHL 1, EAX

In this way, it becomes easy to perform any type of shift, but it doesn't stop
there. To shift a larger register, simply do the following (assuming a shift
up and [EBX,EAX] as the form):
    MOV EAX, ECX
    AND 00001111, EAX    
    ROT 100, EAX
    ROT 100, EBX
    AND 11110000, EBX
    AND 00001111, ECX
    OR  ECX, EBX
result: [EBX,EAX]

This is the 4 bit shift of a 16 bit number in two registers. The 4 bit
rotation has slightly more code.

One should note the opening of 3 undefined opcodes at 21-23. Do with
them as you may, they all are 101xx.

To finish, the groups are:

    00000: HLT
    00xxx: Arithmetic Operations
    01xxx: Logical Operations
    1000x: MOV, MVI
    1001x: Jump Operations
    10100: RST
    101xx: Undefined
    11xxx: Shift Operations

Or, more generally
    00000: HLT
    00xxx: Arithmetic
    01xxx: Logic
    10xxx: Data flow
    11xxx: Shift

As you can see, I broke the groups up by eight so that the related operations all have the same prefix. This, along with killing your MOV duplicates, was my goal the entire time.



RE: My new and most thought out IS. - Chibill - 12-24-2014

SBM and RBM are nothing like move.. They change how big of numbers they hold in bit size and actuall should be combined into Set Bit Mode to set you bit mod. Also I still don't understand what ADDC is used for because if that instrucrion exists the uses could break the whole Multi-bit system.


RE: My new and most thought out IS. - TSO - 12-24-2014

(12-24-2014, 07:03 PM)Chibill Wrote: SBM and RBM are nothing like move.. They change how big of numbers they hold in bit size and actuall should be combined into Set Bit Mode to set you bit mod. Also I still don't understand what ADDC is used for because if that instrucrion exists the uses could break the whole Multi-bit system.

That is because you don't understand how I was able to integrate your bit modes into MOV. I made it so that your FLAGS control the bit mode, and then you move the value you want your bit mode to be into the FLAGS. What you would have found is that this is pretty much how SBM and RBM would have worked anyway, except you would have just put each of them into their own arbitrary two bit control registers.

ADD EAX, EBX = A + B --> A
ADC EAX, EBX = A + B + 1 --> A, where 1 is the carry in. You're going to need this operation if you want your multi bit stuff to work.


RE: My new and most thought out IS. - Chibill - 12-24-2014

Multi- Bit stuff is all hardware based. And also every Register in the whole CPU (Prog counter,etc...) is addressable.


RE: My new and most thought out IS. - TSO - 12-24-2014

*head desk* all right, lets try this again.

No matter how you intend to do this, the SBM and RBM must store the value you set them to somewhere in the god damn computer. If you store these values somewhere in the computer, then you can perform a MOV to alter the location they were stored to because every register is addressable in the computer. To save registers, you then throw them all into your FLAGS register and you're done. It's still redundant to MOV.