// This is free and unencumbered software released into the public domain. // // Anyone is free to copy, modify, publish, use, compile, sell, or // distribute this software, either in source code form or as a compiled // binary, for any purpose, commercial or non-commercial, and by any // means. #define ENABLE_RVTST #define ENABLE_SIEVE #define ENABLE_MULTST #define ENABLE_STATS #include "custom_ops.S" .section .text .global irq .global sieve .global multest .global hard_mul .global hard_mulh .global hard_mulhsu .global hard_mulhu .global stats reset_vec: // no more than 16 bytes here ! waitirq zero maskirq zero, zero j start /* Interrupt handler **********************************/ .balign 16 irq_vec: /* save registers */ setq q2, x1 setq q3, x2 lui x1, %hi(irq_regs) addi x1, x1, %lo(irq_regs) getq x2, q0 sw x2, 0*4(x1) getq x2, q2 sw x2, 1*4(x1) getq x2, q3 sw x2, 2*4(x1) sw x3, 3*4(x1) sw x4, 4*4(x1) sw x5, 5*4(x1) sw x6, 6*4(x1) sw x7, 7*4(x1) sw x8, 8*4(x1) sw x9, 9*4(x1) sw x10, 10*4(x1) sw x11, 11*4(x1) sw x12, 12*4(x1) sw x13, 13*4(x1) sw x14, 14*4(x1) sw x15, 15*4(x1) sw x16, 16*4(x1) sw x17, 17*4(x1) sw x18, 18*4(x1) sw x19, 19*4(x1) sw x20, 20*4(x1) sw x21, 21*4(x1) sw x22, 22*4(x1) sw x23, 23*4(x1) sw x24, 24*4(x1) sw x25, 25*4(x1) sw x26, 26*4(x1) sw x27, 27*4(x1) sw x28, 28*4(x1) sw x29, 29*4(x1) sw x30, 30*4(x1) sw x31, 31*4(x1) /* call interrupt handler C function */ lui sp, %hi(irq_stack) addi sp, sp, %lo(irq_stack) // arg0 = address of regs lui a0, %hi(irq_regs) addi a0, a0, %lo(irq_regs) // arg1 = interrupt type getq x11, q1 // call to C function jal ra, irq /* restore registers */ lui x1, %hi(irq_regs) addi x1, x1, %lo(irq_regs) lw x2, 0*4(x1) setq q0, x2 lw x2, 1*4(x1) setq q1, x2 lw x2, 2*4(x1) setq q2, x2 lw x3, 3*4(x1) lw x4, 4*4(x1) lw x5, 5*4(x1) lw x6, 6*4(x1) lw x7, 7*4(x1) lw x8, 8*4(x1) lw x9, 9*4(x1) lw x10, 10*4(x1) lw x11, 11*4(x1) lw x12, 12*4(x1) lw x13, 13*4(x1) lw x14, 14*4(x1) lw x15, 15*4(x1) lw x16, 16*4(x1) lw x17, 17*4(x1) lw x18, 18*4(x1) lw x19, 19*4(x1) lw x20, 20*4(x1) lw x21, 21*4(x1) lw x22, 22*4(x1) lw x23, 23*4(x1) lw x24, 24*4(x1) lw x25, 25*4(x1) lw x26, 26*4(x1) lw x27, 27*4(x1) lw x28, 28*4(x1) lw x29, 29*4(x1) lw x30, 30*4(x1) lw x31, 31*4(x1) getq x1, q1 getq x2, q2 retirq irq_regs: // registers are saved to this memory region during interrupt handling // the program counter is saved as register 0 .fill 32,4 // stack for the interrupt handler .fill 128,4 irq_stack: /* Main program **********************************/ start: /* zero-initialize all registers */ addi x1, zero, 0 addi x2, zero, 0 addi x3, zero, 0 addi x4, zero, 0 addi x5, zero, 0 addi x6, zero, 0 addi x7, zero, 0 addi x8, zero, 0 addi x9, zero, 0 addi x10, zero, 0 addi x11, zero, 0 addi x12, zero, 0 addi x13, zero, 0 addi x14, zero, 0 addi x15, zero, 0 addi x16, zero, 0 addi x17, zero, 0 addi x18, zero, 0 addi x19, zero, 0 addi x20, zero, 0 addi x21, zero, 0 addi x22, zero, 0 addi x23, zero, 0 addi x24, zero, 0 addi x25, zero, 0 addi x26, zero, 0 addi x27, zero, 0 addi x28, zero, 0 addi x29, zero, 0 addi x30, zero, 0 addi x31, zero, 0 /* running tests from riscv-tests */ #ifdef ENABLE_RVTST # define TEST(n) \ .global n; \ addi x1, zero, 1000; \ timer zero, x1; \ jal zero,n; \ .global n ## _ret; \ n ## _ret: #else # define TEST(n) \ .global n ## _ret; \ n ## _ret: #endif TEST(lui) TEST(auipc) TEST(j) TEST(jal) TEST(jalr) TEST(beq) TEST(bne) TEST(blt) TEST(bge) TEST(bltu) TEST(bgeu) TEST(lb) TEST(lh) TEST(lw) TEST(lbu) TEST(lhu) TEST(sb) TEST(sh) TEST(sw) TEST(addi) TEST(slti) // also tests sltiu TEST(xori) TEST(ori) TEST(andi) TEST(slli) TEST(srli) TEST(srai) TEST(add) TEST(sub) TEST(sll) TEST(slt) // what is with sltu ? TEST(xor) TEST(srl) TEST(sra) TEST(or) TEST(and) TEST(mulh) TEST(mulhsu) TEST(mulhu) TEST(mul) TEST(simple) /* set stack pointer */ lui sp,(64*1024)>>12 #ifdef ENABLE_SIEVE /* call sieve C code */ jal ra,sieve #endif #ifdef ENABLE_MULTST /* call sieve C code */ jal ra,multest #endif #ifdef ENABLE_STATS /* call stats C code */ jal ra,stats #endif /* print "DONE\n" */ lui a0,0x10000000>>12 addi a1,zero,'D' addi a2,zero,'O' addi a3,zero,'N' addi a4,zero,'E' addi a5,zero,'\n' sw a1,0(a0) sw a2,0(a0) sw a3,0(a0) sw a4,0(a0) sw a5,0(a0) /* break */ sbreak hard_mul: mul a0, a0, a1 ret hard_mulh: mulh a0, a0, a1 ret hard_mulhsu: mulhsu a0, a0, a1 ret hard_mulhu: mulhu a0, a0, a1 ret