summaryrefslogtreecommitdiff
path: root/ASAP32-ISA.md
blob: 4b047bf6d01f96e9041f5d3a2ee91bd2f4dd9eca (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
# ASAP32 ISA, a KISS inspired architecture
**A**s **S**imple **A**s **P**ossible

-------------------------------------------

## General Instruction Format
        X = HEX
        B = BIN
        d = don't care

        MAX INSTRUCTIIONS = 256
        ALL INSTRUCTIONS ARE ATOMIC  -- maybe...

### C-Type, Control
        XX        X    X       XXXX
        Opcode    d    RS1     IMM

### I-Type, Immediate
        XX        X     X     XXXX
        Opcode    RD    RS1   IMM

### R-Type, Arithmetic
        XX        X      X      X      XXX
        Opcode    RD     RS1    RS2    Offset (Load/Store Only)

### JR-Type, Compare and Jump
        XX        X                   X      X        XXX
        Opcode    Jump Condition      RS1    RS2      ddd 

### JI-Type, Compare and Jump
        XX        X                X     XXXX            
        Opcode    Jump Condition   RS1   IMM

## Registers
        Maximum registers = 16
        Register width = 32

        Register 0X is always zero and read only (HW enforced)
        Register IP cannot be directly writen to (HW enforced)

        System mode: Registers AX - POG R/W, except IP (Read only)
        User mode: Registers AX - HX R/W, SP & CS0 R/W, others Read only

        ZX      Always Zero
        AX      GP-0
        BX      GP-1
        CX      GP-2
        DX      GP-3
        EX      GP-4
        FX      GP-5
        GX      GP-6
        HX      GP-7
        IP      Instruction Pointer
        SP      Stack Pointer
        FLG     Processor Flags
        CS0     Control status 0 (saves IP)
        CS1     Control status 1 (saves SP)
        CS2     Control status 2 (saves FLG)
        POG     Page Offset & Guard, lower 16 bits -> page offset, upper 16 bits -> guard

### FLG Flag Register Bitfield
        The lower half is read/write
        The upper half can be read or written to in supervisor mode only

        FLG[0]          Carry
        FLG[1]          Overflow
        FLG[2]          Zero
        FLG[3]          Sign
        FLG[4-15]       RESERVED

        FLG[16]         Interrupt enable
        FLG[17]         User mode
        FLG[18]         Paging enabled
        FLG[19]         Stop system clock (total shutdown if interupts are disabled)
        FLG[20-31]      RESERVED*

## Integer Instructions

### R-Type
        ADD     RD, RS1, RS2    RD = RS1 + RS2
        ADDC    RD, RS1, RS2    RD = RS1 + RS2 + FLG[0]
        SUB     RD, RS1, RS2    RD = RS1 - RS2
        SUBC    RD, RS1, RS2    RD = RS1 - RS2 - FLG[0]
        XOR     RD, RS1, RS2    RD = RS1 ^ RS2
        OR      RD, RS1, RS2    RD = RS1 | RS2
        AND     RD, RS1, RS2    RD = RS1 & RS2
        LSL     RD, RS1, RS2    RD = RS1 << RS2 (logical)
        LSR     RD, RS1, RS2    RD = RS1 >> RS2 (logical)
        ASR     RD, RS1, RS2    RD = RS1 >> RS2
        MULL    RD, RS1, RS2    RD = (RS1 * RS2) & 0xFFFFFFFF
        MULH    RD, RS1, RS2    RD = (RS1 * RS2) >> 32
        MULLU   RD, RS1, RS2    RD = RS1 * RS2 & 0xFFFFFFFF (unsigned)
        MULHU   RD, RS1, RS2    RD = (RS1 * RS2) >> 32 (unsigned)
        *DIV    RD, RS1, RS2    RD = RS1 / RS2
        *DIVU   RD, RS1, RS2    RD = RS1 / RS2 (unsigned)

        LDW     RD, RS1, offset         RD = MEM[RS1 + offset]
        LDWR    RD, RS1, RS2            RD = MEM[RS1 + RS2]
        STW     RD, RS1, RS2, offset    MEM[RS1 + offset] = RS2

        LDB     RD, RS1, offset         RD = MEM[RS1 + offset] & 0xFF
        LDBR    RD, RS1, RS2            RD = MEM[RS1 + RS2] & 0xFF
        STB     RD, RS1, RS2, offset    MEM[RS1 + offset] = RS2 & 0xFF

        ^ Do you think load and store byte are neccary?

        *DIV is based on shift-and-multiply algorithm
        *DIV Ex: 8000/192
                 (8000/64)/3
                 (8000>>6)/3
                 (8000>>6)*0x5555>>16=41
        ^ it may be better just to make a slow div in hw, because it will be faster than a slow div in software - I think

### I-Type
        ADDI    RD, RS, IMM     RD = RS + IMM
        ADDIC   RD, RS, IMM     RD = RS + IMM + FLG[0]
        SUBI    RD, RS, IMM     RD = RS - IMM
        SUBIC   RD, RS, IMM     RD = RS - IMM - FLG[0]
        XORI    RD, RS, IMM     RD = RS ^ IMM
        ORI     RD, RS, IMM     RD = RS | IMM
        ANDI    RD, RS, IMM     RD = RS & IMM
        LSLI    RD, RS, IMM     RD = RS << IMM (logical)
        LSRI    RD, RS, IMM     RD = RS >> IMM (logical)
        ASRI    RD, RS, IMM     RD = RS >> IMM
        MULIL   RD, RS, IMM     RD = (RS * IMM) & 0xFFFFFFFF
        MULIH   RD, RS, IMM     RD = (RS * IMM) >> 32
        MULILU  RD, RS, IMM     RD = (RS * IMM) & 0xFFFFFFFF  (unsigned)
        MULIHU  RD, RS, IMM     RD = (RS * IMM) >> 32 (unsigned)
        DIVI    RD, RS, IMM     RD = RS / IMM
        DIVIU   RD, RS, IMM     RD = RS / IMM (unsigned)

### JR Instructions
        Compare and then jump (IP = JMP) if true

        JMP     0       if (True)
        JMP     1       if (RS1 == RS2)
        JMP     2       if (RS1 != RS2)
        JMP     3       if (RS1 >  RS2)  Unsigned
        JMP     4       if (RS1 >= RS2)  Unsigned
        JMP     5       if (RS1 >  RS2)  Signed
        JMP     6       if (RS1 >= RS2)  Signed

### JI Instructions
        Compare and then jump (IP = JMP) if true

        JMPI     0          if (True)
        JMPI     1          if (RS1 == IMM)
        JMPI     2          if (RS1 != IMM)
        JMPI     3          if (RS1 >  IMM)  Unsigned
        JMPI     4          if (RS1 >= IMM)  Unsigned
        JMPI     5          if (RS1 >  IMM)  Signed
        JMPI     6          if (RS1 >= IMM)  Signed

### Jump Aliases
These instructions do not have op codes, the rely on the assembler to convert them to the correct instruction(s)

        JEQ     Jump if equal
        JLT     Jump if less than 
        JGT     Jump if greater than
        JLE     Jump if less than or equal
        JGE     Jump if greater than or equal
        JLTU    Jump if less than (unsigned)
        JGTU    Jump if greater than (unsigned)
        JLEU    Jump if less than or equal (unsigned)
        JGEU    Jump if greater than or equal (unsigned)


### Control Instructions
        NOP             Do nothing -> opcode = ZERO 
        INVP*   IMM     Invalidate entry in TLB    -- what does this do? Is it needed?
        CALL            CS0=IP; IP=CS0
        SCALL           Same as INT but is used to make calls to the kernel (fixed IDT address), can be used in user mode
        INT*    IMM     CS0=IP; CS1=SP; CS2=FLG; IP=IDT[IMM]; SP=CS1; FLG[16]=0; FLG[17]=0;
        IRET*           IP=CS0; SP=CS1; FLG=CS2; 

        *Requires processor to be in supervisor mode (FLG[17]=0)

### Control Alias instructions
These instructions do not have op codes, they rely on the assembler to convert them to the correct instruction(s)

        HLT*             FLG[16]=0; FLG[19]=1; Spinlock the CPU, total shutdown, only reset can restart
        SLP*             FLG[16]=1; FLG[19]=1; sleep until interrupt, pauses the cpu clock till interupt

        SIF*            Set interrupt flag
        CIF*            Clear interrupt flag

        RET             IP = CS0, this is implemented using jmp or call instruction

        assembler controls stack
        PUSHR   RS      SP+=1     ;*SP = RS
        POPR    RS      RS = *SP  ;SP-=1
        PUSHI   IMM     SP+=1     ;*SP = IMM

        *Requires processor to be in supervisor mode (FLG[17]=0)

## Interrupt Descriptor Table
This will be in a fixed memory location, this will contain pointers to the interupt
function.

        IDT[0]          Divide-by-zero exception
        IDT[1]          Hardware error (NMI)
        IDT[2]          Overflow
        IDT[3]          Invalid Opcode
        IDT[4]          General-protection fault
        IDT[5]          Page fault
        IDT[6]          Software interrupt (reserved for OS)
        IDT[7-31]       RESERVED
        IDT[32-255]     Platform interrupts (PIC, hard drive, keyboard, etc.)

## Page List

TODO: explain page list & sliding window