home *** CD-ROM | disk | FTP | other *** search
- /* Superoptimizer -- execute a instruction sequence to in order to
- test it's correctness.
-
- Copyright (C) 1991 Free Software Foundation, Inc.
-
- 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, 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; see the file COPYING. If not, write to the Free
- Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
-
- int
- run_program(insn_t *sequence, int n_insns, word *regs)
- {
- int pc;
- insn_t insn;
- word v, r1, r2;
- int co, ci = -1; /* Combine co and ci into cy? */
-
- for (pc = 0; pc < n_insns; pc++)
- {
- insn = sequence[pc];
- r1 = regs[insn.s1];
- r2 = regs[insn.s2];
-
- switch (insn.opcode)
- {
- default:
- fprintf(stderr,
- "internal error: undefined instruction generated\n");
- abort();
-
- case COPY: PERFORM_COPY(v, co, r1, ci); break;
- case EXCHANGE:
- regs[insn.s1] = r2;
- regs[insn.s2] = r1;
- continue;
-
- case ADD: PERFORM_ADD(v, co, r1, r2, ci); break;
- case ADD_CI: PERFORM_ADD_CI(v, co, r1, r2, ci); break;
- case ADD_CO: PERFORM_ADD_CO(v, co, r1, r2, ci); break;
- case ADD_CIO: PERFORM_ADD_CIO(v, co, r1, r2, ci); break;
-
- case SUB: PERFORM_SUB(v, co, r1, r2, ci); break;
- case SUB_CI: PERFORM_SUB_CI(v, co, r1, r2, ci); break;
- case SUB_CO: PERFORM_SUB_CO(v, co, r1, r2, ci); break;
- case SUB_CIO: PERFORM_SUB_CIO(v, co, r1, r2, ci); break;
-
- case ADC_CI: PERFORM_ADC_CI(v, co, r1, r2, ci); break;
- case ADC_CO: PERFORM_ADC_CO(v, co, r1, r2, ci); break;
- case ADC_CIO: PERFORM_ADC_CIO(v, co, r1, r2, ci); break;
-
- case CMP: PERFORM_CMP(v, co, r1, r2, ci); break;
- case CMPPAR: PERFORM_CMPPAR(v, co, r1, r2, ci); break;
-
- case AND: PERFORM_AND(v, co, r1, r2, ci); break;
- case IOR: PERFORM_IOR(v, co, r1, r2, ci); break;
- case XOR: PERFORM_XOR(v, co, r1, r2, ci); break;
- case ANDC: PERFORM_ANDC(v, co, r1, r2, ci); break;
- case IORC: PERFORM_IORC(v, co, r1, r2, ci); break;
- case EQV: PERFORM_EQV(v, co, r1, r2, ci); break;
- case NAND: PERFORM_NAND(v, co, r1, r2, ci); break;
- case NOR: PERFORM_NOR(v, co, r1, r2, ci); break;
-
- case AND_RC: PERFORM_AND_RC(v, co, r1, r2, ci); break;
- case IOR_RC: PERFORM_IOR_RC(v, co, r1, r2, ci); break;
- case XOR_RC: PERFORM_XOR_RC(v, co, r1, r2, ci); break;
- case ANDC_RC: PERFORM_ANDC_RC(v, co, r1, r2, ci); break;
- case IORC_RC: PERFORM_IORC_RC(v, co, r1, r2, ci); break;
- case EQV_RC: PERFORM_EQV_RC(v, co, r1, r2, ci); break;
- case NAND_RC: PERFORM_NAND_RC(v, co, r1, r2, ci); break;
- case NOR_RC: PERFORM_NOR_RC(v, co, r1, r2, ci); break;
-
- case AND_CC: PERFORM_AND_CC(v, co, r1, r2, ci); break;
- case IOR_CC: PERFORM_IOR_CC(v, co, r1, r2, ci); break;
- case XOR_CC: PERFORM_XOR_CC(v, co, r1, r2, ci); break;
- case ANDC_CC: PERFORM_ANDC_CC(v, co, r1, r2, ci); break;
- case IORC_CC: PERFORM_IORC_CC(v, co, r1, r2, ci); break;
- case EQV_CC: PERFORM_EQV_CC(v, co, r1, r2, ci); break;
- case NAND_CC: PERFORM_NAND_CC(v, co, r1, r2, ci); break;
- case NOR_CC: PERFORM_NOR_CC(v, co, r1, r2, ci); break;
-
- case LSHIFTR: PERFORM_LSHIFTR(v, co, r1, r2, ci); break;
- case ASHIFTR: PERFORM_ASHIFTR(v, co, r1, r2, ci); break;
- case SHIFTL: PERFORM_SHIFTL(v, co, r1, r2, ci); break;
- case ROTATEL: PERFORM_ROTATEL(v, co, r1, r2, ci); break;
- case LSHIFTR_CO:PERFORM_LSHIFTR_CO(v, co, r1, r2, ci); break;
- case ASHIFTR_CO:PERFORM_ASHIFTR_CO(v, co, r1, r2, ci); break;
- case SHIFTL_CO: PERFORM_SHIFTL_CO(v, co, r1, r2, ci); break;
- case ROTATEL_CO:PERFORM_ROTATEL_CO(v, co, r1, r2, ci); break;
- case ROTATEXL_CIO:PERFORM_ROTATEXL_CIO(v, co, r1, r2, ci); break;
- case ASHIFTR_CON:PERFORM_ASHIFTR_CON(v, co, r1, r2, ci); break;
-
- case EXTS1: PERFORM_EXTS1(v, co, r1, r2, ci); break;
- case EXTS2: PERFORM_EXTS2(v, co, r1, r2, ci); break;
- case EXTU1: PERFORM_EXTU1(v, co, r1, r2, ci); break;
- case EXTU2: PERFORM_EXTU2(v, co, r1, r2, ci); break;
-
- case CLZ: PERFORM_CLZ(v, co, r1, ci); break;
- case CTZ: PERFORM_CTZ(v, co, r1, ci); break;
- case FF1: PERFORM_FF1(v, co, r1, ci); break;
- case FF0: PERFORM_FF0(v, co, r1, ci); break;
-
- case ABSVAL: PERFORM_ABSVAL(v, co, r1, ci); break;
- case NABSVAL: PERFORM_NABSVAL(v, co, r1, ci); break;
-
- case DOZ: PERFORM_DOZ(v, co, r1, r2, ci); break;
- case COMCY: co = ci ^ 1; break;
-
- case CPEQ: PERFORM_CPEQ(v, co, r1, r2, ci); break;
- case CPGE: PERFORM_CPGE(v, co, r1, r2, ci); break;
- case CPGEU: PERFORM_CPGEU(v, co, r1, r2, ci); break;
- case CPGT: PERFORM_CPGT(v, co, r1, r2, ci); break;
- case CPGTU: PERFORM_CPGTU(v, co, r1, r2, ci); break;
- case CPLE: PERFORM_CPLE(v, co, r1, r2, ci); break;
- case CPLEU: PERFORM_CPLEU(v, co, r1, r2, ci); break;
- case CPLT: PERFORM_CPLT(v, co, r1, r2, ci); break;
- case CPLTU: PERFORM_CPLTU(v, co, r1, r2, ci); break;
- case CPNEQ: PERFORM_CPNEQ(v, co, r1, r2, ci); break;
-
- case CMPEQ: PERFORM_CMPEQ(v, co, r1, r2, ci); break;
- case CMPLE: PERFORM_CMPLE(v, co, r1, r2, ci); break;
- case CMPLEU: PERFORM_CMPLEU(v, co, r1, r2, ci); break;
- case CMPLT: PERFORM_CMPLT(v, co, r1, r2, ci); break;
- case CMPLTU: PERFORM_CMPLTU(v, co, r1, r2, ci); break;
-
- case CMOVEQ:
- v = regs[insn.d];
- PERFORM_CMOVEQ(v, co, r1, r2, ci);
- break;
- case CMOVNE:
- v = regs[insn.d];
- PERFORM_CMOVNE(v, co, r1, r2, ci);
- break;
- case CMOVLT:
- v = regs[insn.d];
- PERFORM_CMOVLT(v, co, r1, r2, ci);
- break;
- case CMOVGE:
- v = regs[insn.d];
- PERFORM_CMOVGE(v, co, r1, r2, ci);
- break;
- case CMOVLE:
- v = regs[insn.d];
- PERFORM_CMOVLE(v, co, r1, r2, ci);
- break;
- case CMOVGT:
- v = regs[insn.d];
- PERFORM_CMOVGT(v, co, r1, r2, ci);
- break;
-
- case MUL: PERFORM_MUL(v, co, r1, r2, ci); break;
- case UMULWIDEN_HI: PERFORM_UMULWIDEN_HI(v, co, r1, r2, ci); break;
- case INVDIV: PERFORM_INVDIV(v, co, r1, ci); break;
- case INVMOD: PERFORM_INVMOD(v, co, r1, ci); break;
-
- #ifdef UDIV_WITH_SDIV
- case SDIV: PERFORM_SDIV(v, co, r1, r2, ci); break;
- #endif
- }
-
- /* Store result. */
- regs[insn.d] = v;
- ci = co;
- }
-
- return ci;
- }
-