/* qbe.c * * Andy Goth * * Derived from, and hopefully compatible with, GIMP's gqbist.c, originally by * Jens Ch. Restemeier . gqbist.c is available * under the GPL (GNU General Public License), version 2 or later. Therefore, * this file is also available under the GPL. And there was much rejoicing. */ #include #include #include "qbism.h" /* Reads a QBE file into an algorithm structure. */ void algo_read_qbe(algo_t* algo, FILE* in) { int i, j; int ret; char buf[8]; int* data = NULL; int data_len = 0; int data_cap = 0; algo->num_steps = 0; algo->num_regs = 0; /* Read all data. */ while (1) { /* If necessary, grow the sequence buffer. */ if (data_len == data_cap) { if (data_cap == 0) { data_cap = 36 * 4; } else { data_cap *= 2; } data = xrealloc(data, sizeof(*data) * data_cap); } /* Read some bits! */ ret = fread(buf, 1, sizeof(buf), in); if (ret != sizeof(buf)) { if (ferror(in)) { perror("fread"); exit(EXIT_FAILURE); } if (ret == 0) { break; } else { fprintf(stderr, "Malformatted QBE input file.\n"); exit(EXIT_FAILURE); } } /* Store into the temporary data buffer. */ for (i = 0; i < 4; ++i) { data[data_len + i] = (buf[i * 2 + 0] << 8) | (buf[i * 2 + 1] << 0); } data_len += 4; ++algo->num_steps; } /* Store into the algorithm structure. Also, identify the highest-numbered * register. */ algo->seq = xmalloc(sizeof(*algo->seq) * algo->num_steps); for (i = 0; i < algo->num_steps; ++i) { algo->seq[i].opcode = data[algo->num_steps * 0 + i]; algo->seq[i].source = data[algo->num_steps * 1 + i]; algo->seq[i].control = data[algo->num_steps * 2 + i]; algo->seq[i].dest = data[algo->num_steps * 3 + i]; for (j = 1; j <= 3; ++j) { if (data[algo->num_steps * j + i] > algo->num_regs) { algo->num_regs = data[algo->num_steps * j + i]; } } } ++algo->num_regs; free(data); } /* Wirtes an algorithm structure to a QBE file. */ void algo_write_qbe(algo_t* algo, FILE* out) { int i; for (i = 0; i < algo->num_steps; ++i) { fputc(algo->seq[i].opcode >> 8, out); fputc(algo->seq[i].opcode >> 0, out); } for (i = 0; i < algo->num_steps; ++i) { fputc(algo->seq[i].source >> 8, out); fputc(algo->seq[i].source >> 0, out); } for (i = 0; i < algo->num_steps; ++i) { fputc(algo->seq[i].control >> 8, out); fputc(algo->seq[i].control >> 0, out); } for (i = 0; i < algo->num_steps; ++i) { fputc(algo->seq[i].dest >> 8, out); fputc(algo->seq[i].dest >> 0, out); } } /* vim: set ts=4 sts=4 sw=4 tw=80 et: */