/*
 *	Currently only SBs are frpizable
 */
bool El_is_frpizable(Hyperblock *hb)
{
    Op *op;
    Operand pred;

    /* See if there are any ops guarded by a predicate */
    /* Also, no table jumps allowed */
    for (Region_ops_C0_order op_i(hb); op_i!=0; op_i++) {
	op = *op_i;
	if (op->predicated()) {
	    pred = op->src(PRED1);
	    if (! pred.is_predicate_true())
	        return (false);
	}
	if (op->flag(EL_OPER_TABLE_JUMP))
	    return (false);
    }

    return (true);
}
Exemple #2
0
t_stat cpu_one_inst (uint32 opc, uint32 ir)
{
uint32 ea, op, dat, res, dev, sh4, ch;
t_bool ovf_this_cycle = FALSE;
t_stat reason = 0;

op = I_GETOP (ir);                                      /* opcode */
ea = I_GETEA (ir);                                      /* address */
switch (op) {                                           /* case on opcode */

/* Loads, stores, transfers instructions */

    case OP_B:                                          /* bring */
        A = Read (ea);                                  /* A <- M[ea] */
        delay = I_delay (opc, ea, op);
        break;

    case OP_H:                                          /* hold */
        Write (ea, A);                                  /* M[ea] <- A */
        delay = I_delay (opc, ea, op);
        break;

    case OP_C:                                          /* clear */
        Write (ea, A);                                  /* M[ea] <- A */
        A = 0;                                          /* A <- 0 */
        delay = I_delay (opc, ea, op);
        break;

    case OP_Y:                                          /* store address */
        dat = Read (ea);                                /* get operand */
        dat = (dat & ~I_EA) | (A & I_EA);               /* merge address */
        Write (ea, dat);
        delay = I_delay (opc, ea, op);
        break;

    case OP_R:                                          /* return address */
        dat = Read (ea);                                /* get operand */
        dat = (dat & ~I_EA) | (((PC + 1) & AMASK) << I_V_EA);
        Write (ea, dat);
        delay = I_delay (opc, ea, op);
        break;

    case OP_U:                                          /* uncond transfer */
        PCQ_ENTRY;
        PC = ea;                                        /* transfer */
        delay = I_delay (opc, ea, op);
        break;

    case OP_T:                                          /* conditional transfer */
        if ((A & SIGN) ||                               /* A < 0 or */
            ((ir & SIGN) && t_switch)) {                /* -T and Tswitch set? */
            PCQ_ENTRY;
            PC = ea;                                    /* transfer */
            }
        delay = I_delay (opc, ea, op);
        break;

/* Arithmetic and logical instructions */

    case OP_A:                                          /* add */
        dat = Read (ea);                                /* get operand */
        res = (A + dat) & DMASK;                        /* add */
        if ((~A ^ dat) & (dat ^ res) & SIGN)            /* calc overflow */
            ovf_this_cycle = TRUE;
        A = res;                                        /* save result */
        delay = I_delay (opc, ea, op);
        break;

    case OP_S:                                          /* sub */
        dat = Read (ea);                                /* get operand */
        res = (A - dat) & DMASK;                        /* subtract */
        if ((A ^ dat) & (~dat ^ res) & SIGN)            /* calc overflow */
            ovf_this_cycle = TRUE;
        A = res;
        delay = I_delay (opc, ea, op);
        break;

    case OP_M:                                          /* multiply high */
        dat = Read (ea);                                /* get operand */
        A = (Mul64 (A, dat, NULL) << 1) & DMASK;        /* multiply */
        delay = I_delay (opc, ea, op);
        break;

    case OP_N:                                          /* multiply low */
        dat = Read (ea);                                /* get operand */
        Mul64 (A, dat, &res);                           /* multiply */
        A = res;                                        /* keep low result */
        delay = I_delay (opc, ea, op);                  /* total delay */
        break;

    case OP_D:                                          /* divide */
        dat = Read (ea);                                /* get operand */
        if (Div32 (A, dat, &A))                         /* divide; overflow? */
            ovf_this_cycle = TRUE;
        delay = I_delay (opc, ea, op);
        break;

    case OP_E:                                          /* extract */
        dat = Read (ea);                                /* get operand */
        A = A & dat;                                    /* and */
        delay = I_delay (opc, ea, op);
        break;

/* IO instructions */

    case OP_P:                                          /* output */
        if (Q_LGP21) {                                  /* LGP-21 */
            ch = A >> 26;                               /* char, 6b */
            if (ir & SIGN)                              /* 4b? convert */
                ch = (ch & 0x3C) | 2;
            dev = I_GETTK (ir);                         /* device select */
            }
        else {                                          /* LGP-30 */
            ch = I_GETTK (ir);                          /* char, always 6b */
            dev = Q_OUTPT? DEV_PT: DEV_TT;              /* device select */
            }
        reason = op_p (dev & DEV_MASK, ch);             /* output */
        delay = I_delay (sim_grtime (), ea, op);        /* next instruction */
        break;

    case OP_I:                                          /* input */
        if (Q_LGP21) {                                  /* LGP-21 */
            ch = 0;                                     /* initial shift */
            sh4 = ir & SIGN;                            /* 4b/6b select */
            dev = I_GETTK (ir);                         /* device select */
            }
        else {                                          /* LGP-30 */
            ch = I_GETTK (ir);                          /* initial shift */
            sh4 = Q_IN4B;                               /* 4b/6b select */
            dev = Q_INPT? DEV_PT: DEV_TT;               /* device select */
            }
        if (dev == DEV_SHIFT)                           /* shift? */
            A = shift_in (A, 0, sh4);                   /* shift 4/6b */
        else reason = op_i (dev & DEV_MASK, ch, sh4);   /* input */
        delay = I_delay (sim_grtime (), ea, op);        /* next instruction */
        break;

    case OP_Z:
        if (Q_LGP21) {                                  /* LGP-21 */
            if (ea & 0xF80) {                           /* no stop? */
                if (((ea & 0x800) && !bp32) ||          /* skip if any */
                    ((ea & 0x400) && !bp16) ||          /* selected switch */
                    ((ea & 0x200) && !bp8) ||           /* is off */
                    ((ea & 0x100) && !bp4) ||           /* or if */
                    ((ir & SIGN) && !OVF))              /* ovf sel and off */
                    PC = (PC + 1) & AMASK;
                if (ir & SIGN)                          /* -Z? clr overflow */
                    OVF = 0;
                }
            else {                                      /* stop */
                lgp21_sov = (ir & SIGN)? 1: 0;          /* pending sense? */
                reason = STOP_STOP;                     /* stop */
                }
            }
        else {                                          /* LGP-30 */
            if (out_done)                               /* P complete? */
                out_done = 0;
            else if (((ea & 0x800) && bp32) ||          /* bpt switch set? */
                ((ea & 0x400) && bp16) ||
                ((ea & 0x200) && bp8) ||
                ((ea & 0x100) && bp4)) ;                /* don't stop or stall */
            else if (out_strt)                          /* P pending? stall */
                reason = STOP_STALL;
            else reason = STOP_STOP;                    /* no, stop */
            }
        delay = I_delay (sim_grtime (), ea, op);        /* next instruction */
        break;                                          /* end switch */
        }