1 ; `Deep Thought', a softcore CPU implemented on a FPGA
3 ; Copyright (C) 2010 Markus Hofstaetter <markus.manrow@gmx.at>
4 ; Copyright (C) 2010 Martin Perner <e0725782@student.tuwien.ac.at>
5 ; Copyright (C) 2010 Stefan Rebernig <stefan.rebernig@gmail.com>
6 ; Copyright (C) 2010 Manfred Schwarz <e0725898@student.tuwien.ac.at>
7 ; Copyright (C) 2010 Bernhard Urban <lewurm@gmail.com>
9 ; This program is free software: you can redistribute it and/or modify
10 ; it under the terms of the GNU General Public License as published by
11 ; the Free Software Foundation, either version 3 of the License, or
12 ; (at your option) any later version.
14 ; This program is distributed in the hope that it will be useful,
15 ; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 ; GNU General Public License for more details.
19 ; You should have received a copy of the GNU General Public License
20 ; along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #define PROGINSTR stw r0, PDATA(r13)
47 ;assuming that no more than 42 instr are used
57 .ifill ldis r8, 0;0xed400004
58 .ifill mov r0, r7;0xe1038000
59 .ifill andx r0, 1;0xe2800008
60 .ifill adddnz r8, r8, r6;0x00443001
61 .ifill subinz r7, r7, 1;0x01bb8008
62 .ifill addizs r7, r7, 0;0x113b8000
64 .ifill adddnz r8, r8, r6;0x00443001
65 .ifill adddnz r8, r8, r6;0x00443001
66 .ifill subi r7, r7, 2;0xe1bb8010
67 .fill 0x0b7ffe83;brnz+ loop
72 .fill 0xed300004;ldis r6, CONST
76 .ifill add r6, r7, r6;0xe03bb000
80 .ifill sub r7, r7, r6;0xe0bbb000
85 .ifill cmp r7, r6;0xec3b0000
93 .ifill cmpi r6,0;0xecb00000
96 .fill 1, 0x0b000003;brne+ CONST
100 .fill 1, 0xed300000;ldil r6, CONST
101 .fill 1, 0xed300002;ldih r6, CONST
112 .ifill not r6;0xe4b7fffa
135 ;set address of input
136 ldis r1, inputdata@lo
137 ldih r1, inputdata@hi
139 ;set address of program start
140 ldis r2, (prog_start/4)@lo
141 ldih r2, (prog_start/4)@hi
143 ;set address to instruction table
144 ldis r3, instrtable@lo
145 ldih r3, instrtable@hi
147 ;set address to defer table
148 ldis r9, defertable@lo
149 ldih r9, defertable@hi
154 ;set programmer address
160 ;set address to stack
164 ;make r15 a 0-register
166 ;make r14 a 8-bit -1-register
177 subi r0, r0, 0xc ; offset abziehen
194 ;first version only supports backward jumps
196 ;r1 ... address to input, every byte is a new input
197 ; includes pc implicitly
198 ;r2 ... address to program start
199 ;r3 ... address of instruction table
200 ;r4 ... gets loaded with instr. prog. addr.
202 ;r9 ... address to actual entry in defer table
203 ;r10... address to defer table
204 ;r13 .. programmer address
206 ;load address of program
207 ldil r14, prog_mul@lo
208 ldih r14, prog_mul@hi
210 ldil r15, prog_consts@lo
211 ldih r15, prog_consts@hi
213 ;backup defer table address
219 ;increment input address
222 ;store address of next instruction in table
224 ;increment instr. table
229 ;we need to multiply input by 4 to get correct address offset
231 ;calc position in jumptable
232 ldw r0, jumptable(r0)
237 ;load address of program
240 ;program instruction (2)
247 ;now it is time to clear up the defer table
251 ;load branch template
254 ;if actual and base are equal, no entry
260 ;load pointer to where to jump to
262 ;load where to jump to
264 ;load where to save from defer table
270 ;set the upper 16 bit 0
272 ;shift to the position of imm in br
287 ;program instruction (14)
321 ;load address of program
325 ;program instruction (5)
339 ;load address of program
343 ;program instruction (5)
356 ;case 0 1 2 3 4 5 6 7 8 9
359 ;program instruction (3)
363 ;the first instr. loads r6 with the number
364 ;thus we shall emulate this
368 ;shift 3 bits left, as the immediate in ldi has
371 ;now 'add' this to the ldi
374 ;store this 'dynamic' instruction
385 ;load address of program
386 ldil r4, prog_lessthan@lo
387 ldih r4, prog_lessthan@hi
389 ;program instruction (6)
410 ;program instruction (3)
422 ;the following instructions calculate the immediate
444 ;now we will generate ldih/l which will store this
445 ;immediate into a register
447 ;load address of program
482 ;gespeicherte instrs sollten input indepentent sein
484 ;fuer forward jumps muss deferrer table gemacht werden *puke*
486 ;load address of program
495 ;program instruction (2)
500 ;we add the offset to this instruction
504 ;we know calculate the jump destination
505 ;set r6 to 0 (to clear upper bytes)
509 ;compare input with neg. max of 8 bit
515 ;generate negativ offset
517 ;r6 is now the 'real' negativ number
519 ;todo: testing showed (at least once) we are off by 2 instr.
521 ;multiply by to get the offset
523 ;generate address in table
525 ;r0 now has the target address
530 ;we shift 2 bits out, because rel. br takes instr.
531 ;count and not address amount ...
533 ;set the upper 16 bit 0
535 ;shift to the position of imm in br
549 ;we know save the address in the instrtable where the addr to jump to stands
550 ;the value doesn't exists at the moment, but it will at evaluation
552 ;save position to save the instr into defer table
555 ;we need one instruction to have the correct offset (?)
558 ;todo: check if -1 is needed
560 ;multiply with 2 to get offset right
564 ;save the address to defer table
566 ;increment defer table address
575 ;load address of program
579 ;program instruction (1)
591 ;load address of program
595 ;program instruction (4)
611 ;load address of program
615 ;program instruction (3)
629 .fill 41, vm_default/4
635 .fill 1, vm_default/4
639 .fill 2, vm_default/4
641 .fill 10, vm_consts/4
643 .fill 2, vm_default/4
645 .fill 1, vm_lessthan/4
647 .fill 7, vm_default/4
651 .fill 4, vm_default/4
657 .fill 5, vm_default/4
661 .fill 7, vm_default/4
665 .fill 37, vm_default/4
669 .fill 129, vm_default/4
671 ;we assume not more than 3 entries