/* qbe.c * * Copyright (C) 2005 by Andy Goth . * * This program 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. * * This program 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 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple * Place - Suite 330, Boston, MA 02111-1307, USA. */ #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: */