/*
Classic version of the Deutsch's Algorithm.

It takes one of the four possible one-bit binary 
functions and finds out if it is constant:
f(x) = 0 or f(x) = 1; or balanced: f(x) = x or 
f(x) = not x; using the function f(x) only once.

The answer is stored in R1 as: 
R1 = 0  -> Constant
R1 = 1  -> Balanced
R1 = -1 -> Error
*/

// Stored in the 0x200 address is the function to use
// 0: f(x) = 0; 1: f(x) = 1; 2: f(x) = x; 3: f(x) = not x;

.word 0x200 3 //Change this number to select the function

.text 0

addi R2, R0, 0x200
lw R2, 0(R2)         //Load the function number

addi R6, R0, 0

jal callf
addi R4, R6, 0

addi R6, R0, 1

jal callf
addi R5, R6, 0

beq R4, R5, end
addi R1, R0, 1

end:
trap 0

//*****Oracle call*****
callf:
addi R3, R0, 0
beq R3, R2, const0   //Function is f(x) = 0

addi R3, R0, 1
beq R3, R2, const1   //Function is f(x) = 1

addi R3, R0, 2
beq R3, R2, ident    //Function is f(x) = x

addi R3, R0, 3
beq R3, R2, not      //Function is f(x) = not x

addi R1, R0, -1      //There is no function with that number, return error
trap 0

continue:
jr R31
//*********************

const0:
addi R6, R0, 0
j continue

const1:
addi R6, R0 , 1
j continue

ident:
j continue

not:
addi R7, R0, 1
xor R6, R6, R7
j continue



