Execution time is limited to 1000ms.

Information

C15 is a 100 MHz processor based on a fictional architecture brought to life thanks to an FPGA. The processor contains three registers, all 32 bits wide: register A, register B, and register R, used for arithmetic results. There are four flags: zero, greater than, less than, and out of time (indicating the exhaustion of the execution time).

Press "Run" to assemble/compile, upload, and execute the machine code. You can program the processor by either using C15 assembly or the programming language C.

Using the C Compiler

To use the C compiler, create a new tab with the extension ".c". The compiler has support for struct, integer, unsigned integer, and float types. There is no support for recursion due to the limited stack space in the processor.

There are a few intrinsics provided:

Try out these sample .c files, just click on the hyperlinks to load a script into the editor:

Using the C15 Assembler

Memory below all instructions is prefixed with the "a" character followed by the index. Numbers with the "0x" prefix are treated as hexadecimal, numbers ending with "f" are treated as single-precision floating point, and everything else is treated as decimal. Use the "#" symbol to begin a comment.

Listed below is a subset of the C15 instruction set:

0x00HALT

Halts the execution of the processor.

0x01SAVE ADDRESS

Copies the value in register R to the given address.

0x18SAVEA ADDRESS

Copies the value in register A to the given address.

0x19SAVEB ADDRESS

Copies the value in register B to the given address.

0x02STORE VALUE ADDRESS

Writes the value to the address.

0x03GETA ADDRESS

Loads the value located at the given address into the register A.

0x04GETB ADDRESS

Loads the value located at the given address into the register B.

0x05ADD

Sums the values from register A and B and stores the result in register R. (A + B)

This will set the flag Z to 1 if the result is zero. (which may occur because of an arithmetic overflow)

0x06SUB

Subtracts the values from register A and B and stores the result in register R. (A - B)

This will set the flag Z to 1 if the result is zero. (which may occur because of an arithmetic underflow)

0x07MULT

Multiplies the values from register A and B and stores the result in register R. (A × B)

This will set the flag Z to 1 if the result is zero.

0x08DIV

Divides the values from register A and B and stores the quotient in register R. (A ÷ B)

This will set the flag Z to 1 if the result is zero.

0x09REM

Divides the values from register A and B and stores the remainder in register R. (A % B)

0x0BINC

Increments the value of register A and stores the result back into register A. (A++)

0x0CDEC

Decrements the value of register A and stores the result back into register A. (A--)

0x1ARAND

Generates a 32-bit random number and places the random number into register A.

0x0AJMP ADDRESS

Jumps to the given address (sets the program counter to the given address).

0x0DJZ ADDRESS

Jumps to the given address if the flag Z is set to 1.

This instruction combined with CMP is equivalent to A == B.

0x11JNZ ADDRESS

Jumps to the given address if the flag Z is set to 0.

This instruction combined with CMP is equivalent to A != B.

0x13JLT ADDRESS

Jumps to the given address if the flag Less Than is set to 1.

This instruction combined with CMP is equivalent to A < B.

0x14JLTE ADDRESS

Jumps to the given address if the flag Greater Than is set to 0.

This instruction combined with CMP is equivalent to A <= B.

0x15JGT ADDRESS

Jumps to the given address if the flag Greater Than is set to 1.

This instruction combined with CMP is equivalent to A > B.

0x16JGTE ADDRESS

Jumps to the given address if the flag Less Than is set to 0.

This instruction combined with CMP is equivalent to A >= B.

0x0ECMP

Compares the values in registers A and B and sets the flags accordingly:

0x0FCALL ADDRESS

Pushes the next address after the current address to the stack and jumps to the given address.

This acts like a JMP instruction but has the ability to return back to its previous address similar to how a subroutine works.

0x10RTN

Pops the address on top of the stack and jumps to it.

This operation will jump back to the address last called with the CALL instruction.

0x12MOV SOURCE DESTINATION

Copies the value from the source address to the destination address.

0x17SWAP

Swaps the values of register A and B.


0x2DFADD

Performs single-precision floating-point addition between the values in registers A and B, then places the result in register R.
A + B

0x30FMULT

Performs single-precision floating-point multiplication between the values in registers A and B, then places the result in register R.
A * B

0x31FDIV

Performs single-precision floating-point division between the values in registers A and B, then places the result in register R.
A / B

0x2EFLTOINT

Converts a single-precision floating-point in register A to an integer and places the result in register R.
(int)A

0x2FINTTOFL

Converts an integer in register A to a single-precision floating-point and places the result in register R.
(float)A

0x2CTICK

Places the number of clock cycles since execution began in register R.

0x1BPUSH ADDRESS

Pushes the value at the given address to the stack. (maximum 32 elements)

0x1CPOP ADDRESS

Pushes the value at the top of the stack and places it at the given address.

0x1DCMPLT

Compares the values from register A and B and places a 1 if A < B, otherwise 0 in register R.

0x1ECMPGT

Compares the values from register A and B and places a 1 if A > B, otherwise 0 in register R.

0x1FCMPLTE

Compares the values from register A and B and places a 1 if A <= B, otherwise 0 in register R.

0x20CMPGTE

Compares the values from register A and B and places a 1 if A >= B, otherwise 0 in register R.

0x21CMPE

Compares the values from register A and B and places a 1 if A == B, otherwise 0 in register R.

0x22CMPNE

Compares the values from register A and B and places a 1 if A != B, otherwise 0 in register R.

0x23JA ADDRESS

Jumps to the given address if the value in register R is non-zero.

0x24JNA ADDRESS

Jumps to the given address if the value in register R is zero.

0x25NEG

Places a 1 in register R if the value in register A is zero.
Places a 0 in register R if the value in register A is non-zero.

This instruction is equivalent to !A.

0x32QADD VALUEA VALUEB

Performs quick inline addition, compared to the ADD instruction, quick addition allows for single cycle addition by placing the operands A and B into the 32-bit width of the instruction. The result after the operation is placed into register R.

The assembler will interpret addresses by value, that is, only the numeric value of the address will be placed into an operand not the contents at the given address. Operands A and B are restricted to 12-bit values, specifically, only values ranging from 0 and up to and including 4095.