/* objcode.c: Quantum object code functions Copyright 2003 Bjoern Butscher, Hendrik Weimer This file is part of libquantum libquantum is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. libquantum is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with libquantum; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include "objcode.h" #include "config.h" #include "matrix.h" #include "qureg.h" #include "gates.h" #include "measure.h" /* status of the objcode functionality (0 = disabled) */ int opstatus = 0; /* Generated OBJCODE data */ unsigned char *objcode = 0; /* Current POSITION of the last instruction in the OBJCODE array */ unsigned long position = 0; /* Number of ALLOCATED pages */ unsigned long allocated = 0; /* file to write the object code to, if not given */ char *globalfile; /* Convert a big integer to a byte array */ void quantum_mu2char(MAX_UNSIGNED mu, unsigned char *buf) { int i, size; size = sizeof(MAX_UNSIGNED); for(i=0; i=0 ; i--) mu += buf[i] * ((MAX_UNSIGNED) 1 << (8 * (size - i - 1))); return mu; } int quantum_char2int(unsigned char *buf) { int i, size; int j = 0; size = sizeof(int); for(i=size-1; i>=0 ; i--) j += buf[i] * (1 << (8 * (size - i - 1))); return j; } double quantum_char2double(unsigned char *buf) { double *d = (double *) buf; return *d; } /* Start object code recording */ void quantum_objcode_start() { opstatus = 1; allocated = 1; objcode = malloc(OBJCODE_PAGE * sizeof(char)); if(!objcode) { printf("Error allocating memory for objcode data!\n"); exit(1); } quantum_memman(OBJCODE_PAGE * sizeof(char)); } /* Stop object code recording */ void quantum_objcode_stop() { opstatus = 0; free(objcode); objcode = 0; quantum_memman(- allocated * OBJCODE_PAGE * sizeof(char)); allocated = 0; } /* Store an operation with its arguments in the object code data */ int quantum_objcode_put(unsigned char operation, ...) { int i, size; va_list args; unsigned char buf[80]; double d; MAX_UNSIGNED mu; if(!opstatus) return 0; va_start(args, operation); buf[0] = operation; switch(operation) { case INIT: mu = va_arg(args, MAX_UNSIGNED); quantum_mu2char(mu, &buf[1]); size = sizeof(MAX_UNSIGNED) + 1; break; case CNOT: case COND_PHASE: i = va_arg(args, int); quantum_int2char(i, &buf[1]); i = va_arg(args, int); quantum_int2char(i, &buf[sizeof(int)+1]); size = 2 * sizeof(int) + 1; break; case TOFFOLI: i = va_arg(args, int); quantum_int2char(i, &buf[1]); i = va_arg(args, int); quantum_int2char(i, &buf[sizeof(int)+1]); i = va_arg(args, int); quantum_int2char(i, &buf[2*sizeof(int)+1]); size = 3 * sizeof(int) + 1; break; case SIGMA_X: case SIGMA_Y: case SIGMA_Z: case HADAMARD: case BMEASURE: case BMEASURE_P: case SWAPLEADS: i = va_arg(args, int); quantum_int2char(i, &buf[1]); size = sizeof(int) + 1; break; case ROT_X: case ROT_Y: case ROT_Z: case PHASE_KICK: case PHASE_SCALE: i = va_arg(args, int); d = va_arg(args, double); quantum_int2char(i, &buf[1]); quantum_double2char(d, &buf[sizeof(int)+1]); size = sizeof(int) + sizeof(double) + 1; break; case CPHASE_KICK: i = va_arg(args, int); quantum_int2char(i, &buf[1]); i = va_arg(args, int); quantum_int2char(i, &buf[sizeof(int)+1]); d = va_arg(args, double); quantum_double2char(d, &buf[2*sizeof(int)+1]); size = 2 * sizeof(int) + sizeof(double) + 1; break; case MEASURE: case NOP: size = 1; break; default: printf("Unknown opcode 0x(%X)!\n", operation); exit(1); } if((position+size) / OBJCODE_PAGE > position / OBJCODE_PAGE) { allocated++; objcode = realloc(objcode, allocated * OBJCODE_PAGE); if(!objcode) { printf("Error reallocating memory for objcode data!\n"); exit(1); } quantum_memman(OBJCODE_PAGE * sizeof(char)); } for(i=0; i