From b819c6be9396aac52fc9cf787286580ef19b01e4 Mon Sep 17 00:00:00 2001 From: Martin Perner Date: Sun, 16 Jan 2011 01:34:33 +0100 Subject: [PATCH] deepjit/sim: keep to element in r6 / print current pc at exec --- 3b_sim/ccpu.cpp | 2 +- progs/deepjit_reg.s | 659 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 660 insertions(+), 1 deletion(-) create mode 100644 progs/deepjit_reg.s diff --git a/3b_sim/ccpu.cpp b/3b_sim/ccpu.cpp index 06461d6..d314b5e 100644 --- a/3b_sim/ccpu.cpp +++ b/3b_sim/ccpu.cpp @@ -68,7 +68,7 @@ void CCpu::tick() } if(this->conditionMet(instr->getCondition())) { - cout << color(green,black) << "Executing: " << color(white,black) << colorifyInstr(instr->toString()) << endl; + cout << color(green,black) << "Executing: " << color(white,black) << colorifyInstr(instr->toString()) << " (0x" << std::hex << m_pc << std::dec << ")" << endl; instr->execInstr(); this->incPerfBy(instr->getClockCount()); } diff --git a/progs/deepjit_reg.s b/progs/deepjit_reg.s new file mode 100644 index 0000000..e9e20fc --- /dev/null +++ b/progs/deepjit_reg.s @@ -0,0 +1,659 @@ +#define PROGINSTR stw r0, PDATA(r13) +#include "dt_inc.s" +.data +.org 0x10 +inputdata: +;8 * 8 4 +.fill 1, 0x382A3834 +;1 X * 8 +.fill 1, 0x31582A38 +;+ D X - +.fill 1, 0x2B44582D +;P \xF8 J D +.fill 1, 0x50F84A44 +;+ * 8 6 +.fill 1, 0x2B2A3836 +;\000 \020 I D +.fill 1, 0x00204944 +;~ < \000 \000 +.fill 1, 0x7E3C0000 +;8 P \005 J +.fill 1, 0x3850054A +;* 8 +.fill 1, 0x2A38 + +stack: +.fill 256, 0 + +;needed for jumps +;assuming that no more than 42 instr are used +instrtable: +.fill 42, 0 + +prog_eof: +.ifill mov r0, r6 +.ifill ret+ + +prog_mul: +.ifill pop r7 +.ifill ldis r8, 0;0xed400004 +.ifill mov r0, r7;0xe1038000 +.ifill andx r0, 1;0xe2800008 +.ifill adddnz r8, r8, r6;0x00443001 +.ifill subinz r7, r7, 1;0x01bb8008 +.ifill addizs r7, r7, 0;0x113b8000 +;loop: +.ifill adddnz r8, r8, r6;0x00443001 +.ifill adddnz r8, r8, r6;0x00443001 +.ifill subi r7, r7, 2;0xe1bb8010 +.fill 0x0b7ffe83;brnz+ loop +.ifill mov r6, r8 + +prog_consts: +.ifill push r6 +.fill 0xed300004;ldis r6, CONST + +prog_add: +.ifill pop r7 +.ifill add r6, r7, r6;0xe03bb000 + +prog_sub: +.ifill pop r7 +.ifill sub r6, r7, r6;0xe0bbb000 + +prog_lessthan: +.ifill pop r7 +.ifill cmp r7, r6;0xec3b0000 +.ifill movlt r6, r14 +.ifill movge r6, r15 + +prog_dup: +.ifill push r6 + +prog_jmp: +.ifill cmpi r6,0;0xecb00000 +.ifill pop r6 +;static calced +.fill 1, 0x1b000103;breq- vm_next +.fill 1, 0xeb000003;br+ CONST + +prog_imm: +.ifill push r6 +.fill 1, 0xed400000;ldil r6, CONST +.fill 1, 0xed400002;ldih r6, CONST + +prog_pop: +.ifill pop r6 + +prog_xch: +.ifill pop r7 +.ifill push r6 +.ifill mov r6, r7 + +prog_not: +.ifill not r6;0xe4b7fffa + +.text +.org 0 +start: + call+ main + call+ main + ret + + +main: + + call+ u_init + call+ u_recv_byte + + ; benchprolog + call t_init + call t_stop + ldis r1, 0 + call t_valset + call t_start + ; /benchprolog + + ;set address of input + ldis r1, inputdata@lo + ldih r1, inputdata@hi + + ;set address of program start + ldis r2, (prog_start/4)@lo + ldih r2, (prog_start/4)@hi + + ;set address to instruction table + ldis r3, instrtable@lo + ldih r3, instrtable@hi + + ;set address to defer table + ldis r9, defertable@lo + ldih r9, defertable@hi + + ldis r13, PBASE@lo + ldih r13, PBASE@hi + + ;set programmer address + stw r2, PADDR(r13) + + ;call jit compiler + call+ jit + + ;set address to stack + ;ldil r3, stack@lo + ;ldih r3, stack@hi + + ;make r15 a 0-register + ldis r15, 0 + ;make r14 a 8-bit -1-register + ldis r14, 0xFF + + ;call jit'ed prog + call+ prog_start + + ; benchepilog + push r0 + call+ t_init + call+ t_stop + call+ t_valget + subi r0, r0, 0xd ; offset abziehen + pop r3 + push r0 + push r3 + ; /benchepilog + + ;send result + call+ u_init + pop r1 + call u_send_byte + call u_send_newline + pop r1 + call u_send_uint + call u_send_newline + + br+ main + +;first version only supports backward jumps +jit: + ;r1 ... address to input, every byte is a new input + ; includes pc implicitly + ;r2 ... address to program start + ;r3 ... address of instruction table + ;r4 ... gets loaded with instr. prog. addr. + ;r5 ... input + ;r9 ... address to actual entry in defer table + ;r10... address to defer table + ;r13 .. programmer address + + ;load address of program + ldil r14, prog_mul@lo + ldih r14, prog_mul@hi + + ldil r15, prog_consts@lo + ldih r15, prog_consts@hi + + ;backup defer table address + mov r10, r9 + ;decrement address to input by 1 + subi r1, r1, 1 + +vm_default: +vm_loop: + ;increment input address + addi r1, r1, 1 + + ;store address of next instruction in table + stw r2, 0(r3) + ;increment instr. table + addi r3, r3, 4 + + ;load input + ldb r5, 0(r1) + ;we need to multiply input by 4 to get correct address offset + lls r0, r5, 2 + ;calc position in jumptable + ldw r0, jumptable(r0) + ;jump to instr + brr r0 + +vm_eof: + ;load address of program + ldil r4, prog_eof@lo + ldih r4, prog_eof@hi + ;program instruction (2) + ldw r0, 0(r4) + stw r0, PDATA(r13) + ldw r0, 4(r4) + stw r0, PDATA(r13) + + ;end of program + ;now it is time to clear up the defer table + + ldil r7, prog_jmp@lo + ldih r7, prog_jmp@hi + ;load branch template + ldw r7, 12(r7) + + ;if actual and base are equal, no entry + cmp r9, r10 + ;return + reteq- + +vm_defer: + ;load pointer to where to jump to + ldw r6, 0(r10) + ;load where to jump to + ldw r6, 0(r6) + ;load where to save from defer table + stw r8, 4(r10) + + ;generate branch + sub r11, r6, r8 + ;lrs r11, r11, 2 + ;set the upper 16 bit 0 + andx r11, 0xFFFF + ;shift to the position of imm in br + lls r11, r11, 7 + or r6, r7, r11 + + stw r8, PADDR(r13) + stw r6, PDATA(r13) + + addi r10, r10, 8 + cmp r10, r9 + reteq+ + brnq- vm_defer + +;case * +;42 +vm_mul: + ;program instruction (14) + ldw r0, 0(r14) + PROGINSTR + ldw r0, 4(r14) + PROGINSTR + ldw r0, 8(r14) + PROGINSTR + ldw r0, 12(r14) + PROGINSTR + ldw r0, 16(r14) + PROGINSTR + ldw r0, 20(r14) + PROGINSTR + ldw r0, 24(r14) + PROGINSTR + ldw r0, 28(r14) + PROGINSTR + ldw r0, 32(r14) + PROGINSTR + ldw r0, 36(r14) + PROGINSTR + ldw r0, 40(r14) + PROGINSTR + ldw r0, 44(r14) + PROGINSTR + + ;increment address + addi r2, r2, 12 + + br+ vm_loop + +;case + +;43 +vm_add: + ;load address of program + ldil r4, prog_add@lo + ldih r4, prog_add@hi + + ;program instruction (5) + ldw r0, 0(r4) + PROGINSTR + ldw r0, 4(r4) + PROGINSTR + + ;increment address + addi r2, r2, 2 + + br+ vm_loop + +;case - +;45 +vm_sub: + ;load address of program + ldil r4, prog_sub@lo + ldih r4, prog_sub@hi + + ;program instruction (5) + ldw r0, 0(r4) + PROGINSTR + ldw r0, 4(r4) + PROGINSTR + + ;increment address + addi r2, r2, 2 + + br+ vm_loop + +;case 0 1 2 3 4 5 6 7 8 9 +;48-57 +vm_consts: + ;program instruction (3) + ldw r0, 0(r15) + PROGINSTR + ldw r0, 4(r15) + ;the first instr. loads r6 with the number + ;thus we shall emulate this + + ;call number + subi r6, r5, 48 + ;shift 3 bits left, as the immediate in ldi has + ;an offset of 3 + lls r6, r6, 3 + ;now 'add' this to the ldi + or r0, r0, r6 + + ;store this 'dynamic' instruction + PROGINSTR + + ;increment address + addi r2, r2, 2 + + br+ vm_loop + +;case < +;60 +vm_lessthan: + ;load address of program + ldil r4, prog_lessthan@lo + ldih r4, prog_lessthan@hi + + ;program instruction (6) + ldw r0, 0(r4) + PROGINSTR + ldw r0, 4(r4) + PROGINSTR + ldw r0, 8(r4) + PROGINSTR + ldw r0, 12(r4) + PROGINSTR + + ;increment address + addi r2, r2, 4 + + br+ vm_loop + +;case D +;68 +vm_dup: + ldil r4, prog_dup@lo + ldih r4, prog_dup@hi + + ;program instruction (3) + ldw r0, 0(r4) + PROGINSTR + + ;increment address + addi r2, r2, 1 + + br+ vm_loop + +;case I +;73 +vm_imm: + ;the following instructions calculate the immediate + ;load new high byte + ldb r6, 4(r1) + ;shift high byte + lls r6, r6, 8 + ;load 2nd byte + ldb r7, 3(r1) + ;add to high byte + add r6, r6, r7 + ;shift + lls r6, r6, 8 + ;load + ldb r7, 2(r1) + ;add + add r6, r6, r7 + ;shift + lls r6, r6, 8 + ;load + ldb r7, 1(r1) + ;add + add r6, r6, r7 + + ;now we will generate ldih/l which will store this + ;immediate into a register + + ;load address of program + ldil r4, prog_imm@lo + ldih r4, prog_imm@hi + + ldw r0, 4(r4) + PROGINSTR + + ;save r6 to r7 + mov r7, r6 + + ;generate 1st instr + ldw r0, 4(r4) + andx r6, 0xFFFF + lls r6, r6, 3 + or r0, r0, r6 + PROGINSTR + + ;generate 2nd instr + ldw r0, 8(r4) + andxh r7, 0xFFFF + lrs r7, r7, 13 + or r0, r0, r7 + PROGINSTR + + ;increment address + addi r2, r2, 3 + + ;pc+4 + addi r1, r1, 4 + br+ vm_loop + +;case J +;74 +vm_jmp: + ;gfreit mi net ... + ;gespeicherte instrs sollten input indepentent sein + ;jumptable verwenden + ;fuer forward jumps muss deferrer table gemacht werden *puke* + + ;load address of program + ldil r4, prog_jmp@lo + ldih r4, prog_jmp@hi + + ;compare to 0 + ;cmpi r6,0 + ldw r0, 0(r4) + PROGINSTR + + ;program instruction (2) + ;pop r6 + ldw r0, 4(r4) + PROGINSTR + + ;breq+ vm_next + ;is statically known + ldw r0, 8(r4) + PROGINSTR + + ;we add the offset to this instruction + addi r8, r2, 3 + + + ;we know calculate the jump destination + ;set r6 to 0 (to clear upper bytes) + ldis r6, 0 + ;load pc+1 input + ldb r6, 1(r1) + ;compare input with neg. max of 8 bit + cmpi r6, 0x80 + brlt- vm_possign + + + + ;generate negativ offset + ldis r7, 0xFF00 + ;r6 is now the 'real' negativ number + or r6, r6, r7 + ;todo: testing showed (at least once) we are off by 2 instr. + ;addi r6, r6, 2 + ;multiply by to get the offset + lls r6, r6, 2 + ;generate address in table + add r6, r3, r6 + ;r0 now has the target address + ;todo: 0-4? + ldw r0, 0(r6) + ;we calc the offset + sub r8, r0, r8 + ;we shift 2 bits out, because rel. br takes instr. + ;count and not address amount ... + ;lrs r8, r8, 2 + ;set the upper 16 bit 0 + andx r8, 0xFFFF + ;shift to the position of imm in br + lls r8, r8, 7 + ;load template br + ldw r0, 12(r4) + or r0, r0, r8 + PROGINSTR + + ;increment address + addi r2, r2, 4 + + br+ vm_loop + + +vm_possign: + ;we know save the address in the instrtable where the addr to jump to stands + ;the value doesn't exists at the moment, but it will at evaluation + + ;save position to save the instr into defer table + stw r8, 4(r9) + + ;we need one instruction to have the correct offset (?) + PROGINSTR + + ;todo: check if -1 is needed + ;subi r6, r6, 1 + ;multiply with 2 to get offset right + lls r6, r6, 2 + ;add to current base + add r6, r3, r6 + ;save the address to defer table + stw r6, 0(r9) + ;increment defer table address + addi r9, r9, 8 + ;increment address + addi r2, r2, 4 + br+ vm_loop + +;case P +;80 +vm_pop: + ;load address of program + ldil r4, prog_pop@lo + ldih r4, prog_pop@hi + + ;program instruction (1) + ldw r0, 0(r4) + PROGINSTR + + ;increment address + addi r2, r2, 1 + + br+ vm_loop + +;case X +;88 +vm_xch: + ;load address of program + ldil r4, prog_xch@lo + ldih r4, prog_xch@hi + + ;program instruction (4) + ldw r0, 0(r4) + PROGINSTR + ldw r0, 4(r4) + PROGINSTR + ldw r0, 8(r4) + PROGINSTR + + ;increment address + addi r2, r2, 3 + + br+ vm_loop + +;case ~ +;126 +vm_not: + ;load address of program + ldil r4, prog_not@lo + ldih r4, prog_not@hi + + ;program instruction (3) + ldw r0, 0(r4) + PROGINSTR + + ;increment address + addi r2, r2, 1 + + br+ vm_loop + + +.data +jumptable: +;0 +.fill 1, vm_eof/4 +.fill 41, vm_default/4 +;42 +.fill 1, vm_mul/4 +;43 +.fill 1, vm_add/4 +;44 +.fill 1, vm_default/4 +;45 +.fill 1, vm_sub/4 +;46-47 +.fill 2, vm_default/4 +;48-57 +.fill 10, vm_consts/4 +;58-59 +.fill 2, vm_default/4 +;60 +.fill 1, vm_lessthan/4 +;61-67 +.fill 7, vm_default/4 +;68 +.fill 1, vm_dup/4 +;69-72 +.fill 4, vm_default/4 +;73 +.fill 1, vm_imm/4 +;74 +.fill 1, vm_jmp/4 +;75-79 +.fill 5, vm_default/4 +;80 +.fill 1, vm_pop/4 +;81-87 +.fill 7, vm_default/4 +;88 +.fill 1, vm_xch/4 +;89-125 +.fill 37, vm_default/4 +;126 +.fill 1, vm_not/4 +;127-255 +.fill 129, vm_default/4 + +;we assume not more than 3 entries +defertable: +.fill 6, 0 -- 2.25.1